From 8f3fa6df7681d76679fedeb84a74c550b25db5ef Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Fri, 26 Feb 2016 02:07:03 +0100 Subject: [PATCH] Add tests for Class Manager --- src/asset_manager/view/AssetsView.js | 42 ++++----- src/class_manager/main.js | 54 +++++------ src/class_manager/view/ClassTagView.js | 2 +- src/class_manager/view/ClassTagsView.js | 12 ++- src/commands/view/OpenStyleManager.js | 7 +- src/editor/main.js | 2 +- src/editor/model/Editor.js | 4 +- src/storage_manager/main.js | 18 +++- test/runner/main.js | 1 + test/specs/class_manager/e2e/ClassManager.js | 67 +++++++++++++ test/specs/class_manager/main.js | 94 +++++++++++++++++++ test/specs/class_manager/model/ClassModels.js | 39 ++++++++ test/specs/class_manager/view/ClassTagView.js | 72 ++++++++++++++ 13 files changed, 350 insertions(+), 64 deletions(-) create mode 100644 test/specs/class_manager/e2e/ClassManager.js create mode 100644 test/specs/class_manager/main.js create mode 100644 test/specs/class_manager/model/ClassModels.js create mode 100644 test/specs/class_manager/view/ClassTagView.js diff --git a/src/asset_manager/view/AssetsView.js b/src/asset_manager/view/AssetsView.js index 342816300..af3f92d98 100644 --- a/src/asset_manager/view/AssetsView.js +++ b/src/asset_manager/view/AssetsView.js @@ -1,10 +1,10 @@ -define(['backbone', './AssetView', './AssetImageView', './FileUploader'], +define(['backbone', './AssetView', './AssetImageView', './FileUploader'], function (Backbone, AssetView, AssetImageView, FileUploader) { - /** + /** * @class AssetsView * */ return Backbone.View.extend({ - + initialize: function(o) { this.options = o; this.config = o.config; @@ -12,7 +12,7 @@ define(['backbone', './AssetView', './AssetImageView', './FileUploader'], this.listenTo( this.collection, 'add', this.addToAsset ); this.listenTo( this.collection, 'deselectAll', this.deselectAll ); this.className = this.pfx + 'assets'; - + // Check if storage is required and if Storage Manager is available if(this.config.stm && this.config.storageType !== ''){ var type = this.config.storageType; @@ -30,20 +30,20 @@ define(['backbone', './AssetView', './AssetImageView', './FileUploader'], } } }, - + /** * Store collection - * + * * @return void * */ store: function(){ if(this.storagePrv) this.storagePrv.store(this.storeName, JSON.stringify(this.collection.toJSON()) ); }, - + /** * Load collection - * + * * @return {Object} * */ load: function(){ @@ -59,63 +59,63 @@ define(['backbone', './AssetView', './AssetImageView', './FileUploader'], } return result; }, - + /** * Add asset to collection * */ addToAsset: function(model){ this.addAsset(model); }, - + /** * Add new asset to collection * @param Object Model * @param Object Fragment collection - * + * * @return Object Object created * */ addAsset: function(model, fragmentEl){ var fragment = fragmentEl || null; var viewObject = AssetView; - + if(model.get('type').indexOf("image") > -1) viewObject = AssetImageView; - + var view = new viewObject({ model : model, config : this.config, }); var rendered = view.render().el; - + if(fragment){ fragment.appendChild( rendered ); }else{ this.$el.prepend(rendered); } - + return rendered; }, - + /** * Deselect all assets - * + * * @return void * */ deselectAll: function(){ this.$el.find('.' + this.pfx + 'highlight').removeClass(this.pfx + 'highlight'); }, - + render: function() { var fragment = document.createDocumentFragment(); this.$el.empty(); - + this.collection.each(function(model){ this.addAsset(model, fragment); },this); - + this.$el.append(fragment); this.$el.attr('class', this.className); - + return this; } }); diff --git a/src/class_manager/main.js b/src/class_manager/main.js index 940f25ed2..cbd2e01a1 100644 --- a/src/class_manager/main.js +++ b/src/class_manager/main.js @@ -7,38 +7,39 @@ define(function(require) { var ClassManager = function(config) { var c = config || {}, - def = require('./config/config'), - ClassTags = require('./model/ClassTags'), - ClassTagsView = require('./view/ClassTagsView'); + def = require('./config/config'); + this.ClassTags = require('./model/ClassTags'); + this.ClassTagsView = require('./view/ClassTagsView'); for (var name in def) { if (!(name in c)) c[name] = def[name]; } - this.classes = new ClassTags(c.classes); - - var obj = { - collection: this.classes, - config: c, - }; - this.tagsView = new ClassTagsView(obj); - //this.ClassTagsView = new ClassTagsView(obj); + this.classes = new this.ClassTags(c.classes); + this.config = c; }; ClassManager.prototype = { /** - * Get collection of classes + * Add new class to collection only if it's not already exists + * @param {String} name Class name * - * @return {Object} + * @return {Object} Model class * */ - getClasses : function() { - return this.classes; + addClass: function(name){ + var label = name; + var fname = this.escapeName(name); + var c = this.getClass(fname); + if(!c) + return this.classes.add({name: fname, label: label}); + return c; }, /** * Get class by its name + * @param {String} id Class name * * @return {Object|null} * */ @@ -48,35 +49,24 @@ define(function(require) { }, /** - * Add new class to collection only if it's not already exists - * @param {String} name Class name - * @return {Object} Model class + * Get collection of classes + * + * @return {Object} * */ - addClass: function(name){ - var label = name; - var fname = this.escapeName(name); - var c = this.getClass(fname); - if(!c) - return this.classes.add({name: fname, label: label}); - return c; + getClasses : function() { + return this.classes; }, /** * Escape string * @param {String} name + * * @return {String} */ escapeName: function(name) { return name.toLowerCase().replace(/([^a-z0-9\w]+)/gi, '-'); }, - /** - * Renders a collection of class tags. Useful for components classes - * @return {Object} Rendered view - */ - renderTags: function(){ - return this.tagsView.render().el; - }, }; return ClassManager; diff --git a/src/class_manager/view/ClassTagView.js b/src/class_manager/view/ClassTagView.js index 6a379bcc5..3e5328b60 100644 --- a/src/class_manager/view/ClassTagView.js +++ b/src/class_manager/view/ClassTagView.js @@ -11,7 +11,7 @@ define(['backbone', 'text!./../template/classTag.html'], initialize: function(o) { this.config = o.config || {}; - this.pfx = this.config.stylePrefix; + this.pfx = this.config.stylePrefix || ''; this.className = this.pfx + 'tag'; this.closeId = this.pfx + 'close'; this.events['click #' + this.closeId ] = 'removeTag'; diff --git a/src/class_manager/view/ClassTagsView.js b/src/class_manager/view/ClassTagsView.js index 896c0e4fa..a4c5cb8e4 100644 --- a/src/class_manager/view/ClassTagsView.js +++ b/src/class_manager/view/ClassTagsView.js @@ -26,11 +26,18 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'], this.listenTo( this.target ,'change:selectedComponent',this.componentChanged); this.listenTo( this.collection, 'add', this.addNew); + this.listenTo( this.collection, 'remove', this.removed); this.listenTo( this.collection, 'reset', this.renderClasses); + //this.config. + this.delegateEvents(); }, + removed: function(){ + console.log('removed'); + }, + /** * Add new model * @param {Object} model @@ -106,9 +113,10 @@ define(['backbone', 'text!./../template/classTags.html', './ClassTagView'], var cm = this.target.get('ClassManager'); var model = cm.addClass(name); - if(this.compTarget) + if(this.compTarget){ this.compTarget.get('classes').add(model); - + this.collection.add(model); + } } this.endNewTag(); }, diff --git a/src/commands/view/OpenStyleManager.js b/src/commands/view/OpenStyleManager.js index ec5dec4cf..4cab47f1c 100644 --- a/src/commands/view/OpenStyleManager.js +++ b/src/commands/view/OpenStyleManager.js @@ -24,8 +24,11 @@ define(['StyleManager'], function(StyleManager) { // Class Manager container this.clm = em.get('ClassManager'); if(this.clm){ - //this.$clm = this.clm.renderTags(); - //this.$cn2.append(this.$clm); + this.$clm = new this.clm.ClassTagsView({ + collection: new this.clm.ClassTags([]), + config: this.clm.config, + }).render().el; + this.$cn2.append(this.$clm); } // Style Manager manager container diff --git a/src/editor/main.js b/src/editor/main.js index 0f32157c6..e4294e846 100644 --- a/src/editor/main.js +++ b/src/editor/main.js @@ -23,7 +23,7 @@ define(function (require){ config : c, }; - this.editorView = new EditorView(obj); + this.editorView = new EditorView(obj); }; Grapes.prototype = { diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 08f2458a3..6bddebf0b 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -313,7 +313,9 @@ define([ loadComponents: function(){ var result = null; try{ - result = JSON.parse(this.stm.load(this.compName)); + var r = this.stm.load(this.compName); + if(r) + result = JSON.parse(r); }catch(err){ console.warn("Error encountered while parsing JSON response"); } diff --git a/src/storage_manager/main.js b/src/storage_manager/main.js index ec163f1b7..7c1bc432d 100644 --- a/src/storage_manager/main.js +++ b/src/storage_manager/main.js @@ -153,20 +153,30 @@ define(function(require) { * @param {String} name Name of the resource * @param {String} value Value of the resource * - * @return {Object}|void + * @return {Object|null} * */ store : function(name, value){ - return this.getCurrentProvider().store(name, value); + var pv = this.getCurrentProvider(); + + if(pv) + return pv.store(name, value); + + return; }, /** * Load resource * @param {String} name Name of the resource * - * @return {Object}|void + * @return {Object|null} * */ load : function(name){ - return this.getCurrentProvider().load(name); + var pv = this.getCurrentProvider(); + + if(pv) + return pv.load(name); + + return; }, /** diff --git a/test/runner/main.js b/test/runner/main.js index 7efbeb7f8..24824b47e 100644 --- a/test/runner/main.js +++ b/test/runner/main.js @@ -12,6 +12,7 @@ require(['../src/config/require-config.js', 'config/config.js'], function() { 'specs/asset_manager/view/AssetImageView.js', 'specs/asset_manager/view/FileUploader.js', 'specs/dom_components/main.js', + 'specs/class_manager/main.js', ], function(chai) { var should = chai.should(), diff --git a/test/specs/class_manager/e2e/ClassManager.js b/test/specs/class_manager/e2e/ClassManager.js new file mode 100644 index 000000000..d3c845102 --- /dev/null +++ b/test/specs/class_manager/e2e/ClassManager.js @@ -0,0 +1,67 @@ + +define( + function(require) { + + return { + run : function(){ + describe('E2E tests', function() { + + before(function () { + this.$fixtures = $("#fixtures"); + this.$fixture = $('
'); + }); + + beforeEach(function () { + var Grapes = require('editor/main'); + this.gjs = new Grapes({ + storageType: 'none', + storageManager: { + storageType: 'none', + }, + assetManager: { + storageType: 'none', + }, + container: '#ClassManager-fixture', + }); + this.$fixture.empty().appendTo(this.$fixtures); + this.gjs.render(); + }); + + afterEach(function () { + delete this.gjs; + }); + + after(function () { + this.$fixture.remove(); + }); + + it('Assign correctly new class to component', function() { + var wrp = this.gjs.editor.get('Components').getWrapper().get('components'); + var model = wrp.add({}); + model.get('classes').length.should.equal(0); + + // Init Class Manager and set editor as a target + var clm = this.gjs.editor.get('ClassManager'); + clm.config.target = this.gjs.editor; + if(clm){ + var $clm = new clm.ClassTagsView({ + collection: new clm.ClassTags([]), + config: clm.config, + }).render(); + this.$fixture.append($clm.el); + } + + // Select element + this.gjs.editor.set('selectedComponent', model); + + $clm.addNewTag('test'); + model.get('classes').length.should.equal(1); + model.get('classes').at(0).get('name').should.equal('test'); + + }); + + }); + } + }; + +}); \ No newline at end of file diff --git a/test/specs/class_manager/main.js b/test/specs/class_manager/main.js new file mode 100644 index 000000000..f5e936500 --- /dev/null +++ b/test/specs/class_manager/main.js @@ -0,0 +1,94 @@ +var modulePath = './../../../test/specs/class_manager'; + +define([ + 'ClassManager', + modulePath + '/model/ClassModels', + modulePath + '/view/ClassTagView', + modulePath + '/e2e/ClassManager' + ], + function( + ClassManager, + Models, + ClassTagView, + e2e + ) { + + describe('Class Manager', function() { + + describe('Main', function() { + + beforeEach(function () { + this.obj = new ClassManager(); + }); + + afterEach(function () { + delete this.obj; + }); + + it('Object exists', function() { + ClassManager.should.be.exist; + }); + + it('No classes inside', function() { + this.obj.getClasses().length.should.equal(0); + }); + + it('Able to add default classes', function() { + var cm = new ClassManager({ + classes: ['test1', 'test2', 'test3'], + }); + cm.getClasses().length.should.equal(3); + }); + + it('Add new class', function() { + this.obj.addClass('test'); + this.obj.getClasses().length.should.equal(1); + }); + + it('Check name property', function() { + var className = 'test'; + var obj = this.obj.addClass(className); + obj.get('name').should.equal(className); + }); + + it('Add 2 classes', function() { + this.obj.addClass('test'); + this.obj.addClass('test2'); + this.obj.getClasses().length.should.equal(2); + }); + + it('Add 2 same classes', function() { + this.obj.addClass('test'); + this.obj.addClass('test'); + this.obj.getClasses().length.should.equal(1); + }); + + it('Get class', function() { + var className = 'test'; + var obj = this.obj.addClass(className); + (this.obj.getClass(className) === null).should.equal(false); + }); + + it('Get empty class', function() { + (this.obj.getClass('test') === null).should.equal(true); + }); + + it('Get same class', function() { + var className = 'test'; + var obj = this.obj.addClass(className); + var obj2 = this.obj.getClass(className); + obj2.should.deep.equal(obj); + }); + + it('escapeName test', function() { + this.obj.escapeName('@Te sT*').should.equal('-te-st-'); + }); + + }); + + Models.run(); + ClassTagView.run(); + e2e.run(); + + }); +}); \ No newline at end of file diff --git a/test/specs/class_manager/model/ClassModels.js b/test/specs/class_manager/model/ClassModels.js new file mode 100644 index 000000000..15139070e --- /dev/null +++ b/test/specs/class_manager/model/ClassModels.js @@ -0,0 +1,39 @@ +var path = 'ClassManager/model/'; +define([path + 'ClassTag', + path + 'ClassTags'], + function(ClassTag, ClassTags) { + + return { + run : function(){ + describe('ClassTag', function() { + + beforeEach(function () { + this.obj = new ClassTag(); + }); + + afterEach(function () { + delete this.obj; + }); + + it('Has name property', function() { + this.obj.has('name').should.equal(true); + }); + + it('Has label property', function() { + this.obj.has('label').should.equal(true); + }); + + }); + describe('ClassTags', function() { + + it('Creates collection item correctly', function() { + var c = new ClassTags(); + var m = c.add({}); + m.should.be.an.instanceOf(ClassTag); + }); + + }); + } + }; + +}); \ No newline at end of file diff --git a/test/specs/class_manager/view/ClassTagView.js b/test/specs/class_manager/view/ClassTagView.js new file mode 100644 index 000000000..9d425ab8d --- /dev/null +++ b/test/specs/class_manager/view/ClassTagView.js @@ -0,0 +1,72 @@ +var path = 'ClassManager/view/'; +define([path + 'ClassTagView', 'ClassManager/model/ClassTags'], + function(ClassTagView, ClassTags) { + + return { + run : function(){ + describe('ClassTagView', function() { + + before(function () { + this.$fixtures = $("#fixtures"); + this.$fixture = $('
'); + }); + + beforeEach(function () { + var coll = new ClassTags(); + this.testLabel = 'TestLabel'; + var model = coll.add({ + name: 'test', + label: this.testLabel, + }); + this.view = new ClassTagView({ + config : {}, + model: model + }); + this.$fixture.empty().appendTo(this.$fixtures); + this.$fixture.html(this.view.render().el); + }); + + afterEach(function () { + this.view.model.destroy(); + }); + + after(function () { + this.$fixture.remove(); + }); + + it('Object exists', function() { + ClassTagView.should.be.exist; + }); + + it('Not empty', function() { + var $el = this.view.$el; + $el.html().should.not.be.empty; + }); + + it('Not empty', function() { + var $el = this.view.$el; + $el.html().should.contain(this.testLabel); + }); + + describe('Should be rendered correctly', function() { + + it('Has close button', function() { + var $el = this.view.$el; + $el.find('#close').should.have.property(0); + }); + + }); + + it('Could be removed', function() { + var spy = sinon.spy(); + this.view.config.target = { get:function(){} }; + sinon.stub(this.view.config.target, 'get').returns(0); + this.view.$el.find('#close').trigger('click'); + this.$fixture.html().should.be.empty; + }); + + }); + } + }; + +}); \ No newline at end of file