mirror of https://github.com/artf/grapesjs.git
60 changed files with 2294 additions and 452 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1,3 @@ |
|||
<%= label %> <span id="<%= pfx %>close">⨯</span> |
|||
<span id="<%= pfx %>checkbox" class="fa"></span> |
|||
<span id="<%= pfx %>tag-label"><%= label %></span> |
|||
<span id="<%= pfx %>close">⨯</span> |
|||
@ -1,44 +1,89 @@ |
|||
define(['backbone'], |
|||
define(['backbone'], |
|||
function (Backbone) { |
|||
/** |
|||
* @class CssGenerator |
|||
* */ |
|||
return Backbone.Model.extend({ |
|||
|
|||
|
|||
initialize: function(){ |
|||
this.compCls = []; |
|||
}, |
|||
|
|||
/** @inheritdoc */ |
|||
getId : function() |
|||
{ |
|||
return 'css'; |
|||
return 'css'; |
|||
}, |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model) |
|||
{ |
|||
|
|||
|
|||
/** |
|||
* Get CSS from components |
|||
* @return {String} |
|||
*/ |
|||
buildFromComp: function(model){ |
|||
var coll = model.get('components') || model, |
|||
code = ''; |
|||
|
|||
|
|||
coll.each(function(m){ |
|||
var css = m.get('style'), |
|||
cln = m.get('components'); // Children
|
|||
|
|||
var css = m.get('style'), |
|||
cls = m.get('classes'), |
|||
cln = m.get('components'); |
|||
cls.each(function(m){ |
|||
this.compCls.push(m.get('name')); |
|||
}, this); |
|||
|
|||
if(css && Object.keys(css).length !== 0){ |
|||
code += '#' + m.cid + '{'; |
|||
|
|||
for(var prop in css) |
|||
for(var prop in css){ |
|||
if(css.hasOwnProperty(prop)) |
|||
code += prop + ': ' + css[prop] + ';'; |
|||
|
|||
code += prop + ':' + css[prop] + ';'; |
|||
} |
|||
code += '}'; |
|||
} |
|||
|
|||
|
|||
if(cln.length) |
|||
code += this.build(cln); |
|||
|
|||
code += this.buildFromComp(cln); |
|||
|
|||
}, this); |
|||
|
|||
|
|||
return code; |
|||
}, |
|||
|
|||
/** @inheritdoc */ |
|||
build: function(model, cssc) |
|||
{ |
|||
this.compCls = []; |
|||
var code = this.buildFromComp(model); |
|||
var compCls = this.compCls; |
|||
|
|||
if(cssc){ |
|||
var rules = cssc.getRules(); |
|||
rules.each(function(rule){ |
|||
var selectors = rule.get('selectors'); |
|||
var ruleStyle = rule.get('style'); |
|||
var strSel = ''; |
|||
var found = 0; |
|||
|
|||
selectors.each(function(selector){ |
|||
strSel += '.' + selector.get('name'); |
|||
if(compCls.indexOf(selector.get('name')) > -1) |
|||
found = 1; |
|||
}); |
|||
if(strSel && found){ |
|||
var strStyle = ''; |
|||
if(ruleStyle && Object.keys(ruleStyle).length !== 0){ |
|||
for(var prop2 in ruleStyle){ |
|||
if(ruleStyle.hasOwnProperty(prop2)) |
|||
strStyle += prop2 + ':' + ruleStyle[prop2] + ';'; |
|||
} |
|||
} |
|||
if(strStyle) |
|||
code += strSel + '{' + strStyle + '}'; |
|||
} |
|||
}); |
|||
|
|||
} |
|||
return code; |
|||
}, |
|||
|
|||
|
|||
}); |
|||
}); |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
define(function () { |
|||
return { |
|||
|
|||
// Style prefix
|
|||
stylePrefix: 'css-', |
|||
|
|||
// Custom CSS string to render on top
|
|||
'staticRules': '', |
|||
|
|||
// Default CSS style
|
|||
'defaults': [], |
|||
|
|||
}; |
|||
}); |
|||
@ -0,0 +1,106 @@ |
|||
define(function(require) { |
|||
/** |
|||
* @class CssComposer |
|||
* @param {Object} config Configurations |
|||
* |
|||
* */ |
|||
var CssComposer = function(config) |
|||
{ |
|||
var c = config || {}, |
|||
def = require('./config/config'), |
|||
CssRule = require('./model/CssRule'), |
|||
CssRules = require('./model/CssRules'), |
|||
Selectors = require('./model/Selectors'), |
|||
CssRulesView = require('./view/CssRulesView'); |
|||
|
|||
for (var name in def) { |
|||
if (!(name in c)) |
|||
c[name] = def[name]; |
|||
} |
|||
|
|||
var rules = new CssRules(c.defaults, c), |
|||
rulesView = new CssRulesView({ |
|||
collection: rules, |
|||
config: c, |
|||
}); |
|||
|
|||
return { |
|||
|
|||
Selectors: Selectors, |
|||
|
|||
/** |
|||
* Create new rule and return it. Don't add it to the collection |
|||
* @param {Array} selectors Array of selectors |
|||
* @param {String} state Css rule state |
|||
* @param {String} width For which device this style is oriented |
|||
* |
|||
* @return {Object} |
|||
* */ |
|||
newRule: function(selectors, state, width) { |
|||
var s = state || ''; |
|||
var w = width || ''; |
|||
var rule = new CssRule({ |
|||
state: s, |
|||
maxWidth: w, |
|||
}); |
|||
rule.get('selectors').add(selectors); |
|||
return rule; |
|||
}, |
|||
|
|||
/** |
|||
* Add new rule to the collection if not yet exists |
|||
* @param {Object} rule |
|||
* |
|||
* @return {Object} |
|||
* */ |
|||
addRule: function(rule){ |
|||
var models = rule.get('selectors').models; |
|||
var r = this.getRule(models, rule.get('state'), rule.get('maxWidth')); |
|||
if(!r) |
|||
r = rules.add(rule); |
|||
return r; |
|||
}, |
|||
|
|||
/** |
|||
* Get class by its name |
|||
* @param {Array} selectors Array of selectors |
|||
* @param {String} state Css rule state |
|||
* @param {String} width For which device this style is oriented |
|||
* |
|||
* @return {Object|null} |
|||
* */ |
|||
getRule : function(selectors, state, width) { |
|||
fRule = null; |
|||
rules.each(function(rule){ |
|||
if(fRule) |
|||
return; |
|||
if(rule.compare(selectors, state, width)) |
|||
fRule = rule; |
|||
}, this); |
|||
return fRule; |
|||
}, |
|||
|
|||
/** |
|||
* Get collection of css rules |
|||
* |
|||
* @return {Object} |
|||
* */ |
|||
getRules : function() { |
|||
return rules; |
|||
}, |
|||
|
|||
/** |
|||
* Render block of CSS rules |
|||
* |
|||
* @return {Object} |
|||
*/ |
|||
render: function(){ |
|||
return rulesView.render().el; |
|||
} |
|||
|
|||
}; |
|||
}; |
|||
|
|||
return CssComposer; |
|||
|
|||
}); |
|||
@ -0,0 +1,75 @@ |
|||
define(['backbone', './Selectors'], |
|||
function (Backbone, Selectors) { |
|||
/** |
|||
* @class CssRule |
|||
* */ |
|||
return Backbone.Model.extend({ |
|||
|
|||
defaults: { |
|||
// Css selectors
|
|||
selectors: {}, |
|||
// Css properties style
|
|||
style: {}, |
|||
// On which device width this rule should be rendered, eg. @media (max-width: 1000px)
|
|||
maxWidth: '', |
|||
// State of the rule, eg: hover | pressed | focused
|
|||
state: '', |
|||
// Indicates if the rule is stylable
|
|||
stylable: true, |
|||
}, |
|||
|
|||
initialize: function(c, opt) { |
|||
this.config = c || {}; |
|||
this.sm = opt ? opt.sm || {} : {}; |
|||
this.slct = this.config.selectors || []; |
|||
|
|||
if(this.sm.get){ |
|||
var slct = []; |
|||
for(var i = 0; i < this.slct.length; i++) |
|||
slct.push(this.sm.get('ClassManager').addClass(this.slct[i].name)); |
|||
this.slct = slct; |
|||
} |
|||
|
|||
this.set('selectors', new Selectors(this.slct)); |
|||
}, |
|||
|
|||
/** |
|||
* Compare the actual model with parameters |
|||
* @param {Object} selectors Collection of selectors |
|||
* @param {String} state Css rule state |
|||
* @param {String} width For which device this style is oriented |
|||
* |
|||
* @return {Boolean} |
|||
*/ |
|||
compare: function(selectors, state, width){ |
|||
var st = state || ''; |
|||
var wd = width || ''; |
|||
var cId = 'cid'; |
|||
var a1 = _.pluck(selectors.models || selectors, cId); |
|||
var a2 = _.pluck(this.get('selectors').models, cId); |
|||
var f = false; |
|||
|
|||
if(a1.length !== a2.length) |
|||
return f; |
|||
|
|||
for (var i = 0; i < a1.length; i++) { |
|||
var re = 0; |
|||
for (var j = 0; j < a2.length; j++) { |
|||
if (a1[i] === a2[j]) |
|||
re = 1; |
|||
} |
|||
if(re === 0) |
|||
return f; |
|||
} |
|||
|
|||
if(this.get('state') !== st) |
|||
return f; |
|||
|
|||
if(this.get('maxWidth') !== wd) |
|||
return f; |
|||
|
|||
return true; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,27 @@ |
|||
define(['backbone','./CssRule'], |
|||
function (Backbone, CssRule) { |
|||
/** |
|||
* @class CssRules |
|||
* */ |
|||
return Backbone.Collection.extend({ |
|||
|
|||
initialize: function(models, opt){ |
|||
|
|||
this.model = function(attrs, options) { |
|||
var model; |
|||
|
|||
if(!options.sm && opt && opt.sm) |
|||
options.sm = opt.sm; |
|||
|
|||
switch(1){ |
|||
default: |
|||
model = new CssRule(attrs, options); |
|||
} |
|||
|
|||
return model; |
|||
}; |
|||
|
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,29 @@ |
|||
define([ 'backbone', 'require'], |
|||
function (Backbone, require) { |
|||
/** |
|||
* @class Selectors |
|||
* */ |
|||
|
|||
return Backbone.Collection.extend({ |
|||
|
|||
initialize: function(models, opt){ |
|||
|
|||
this.model = function(attrs, opts) { |
|||
var model; |
|||
|
|||
switch(1){ |
|||
|
|||
default: |
|||
if(!this.ClassTag) |
|||
this.ClassTag = require("ClassManager/model/ClassTag"); |
|||
model = new this.ClassTag(attrs, opts); |
|||
|
|||
} |
|||
|
|||
return model; |
|||
}; |
|||
|
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,56 @@ |
|||
define(['backbone'], |
|||
function (Backbone) { |
|||
/** |
|||
* @class CssRuleView |
|||
* */ |
|||
return Backbone.View.extend({ |
|||
|
|||
tagName: 'style', |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.listenTo(this.model, 'change:style', this.render); |
|||
}, |
|||
|
|||
/** |
|||
* Returns string of selectors |
|||
* |
|||
* @return {String} |
|||
*/ |
|||
renderSelectors: function(){ |
|||
var sel = []; |
|||
this.model.get('selectors').each(function(m){ |
|||
sel.push('.' + m.get('name')); |
|||
}); |
|||
return sel.join(''); |
|||
}, |
|||
|
|||
/** |
|||
* Returns string of properties |
|||
* |
|||
* @return {String} |
|||
*/ |
|||
renderProperties: function(){ |
|||
var sel = [], |
|||
props = this.model.get('style'); |
|||
for (var prop in props){ |
|||
sel.push(prop + ':' + props[prop] + ';'); |
|||
} |
|||
return sel.join(''); |
|||
}, |
|||
|
|||
render : function(){ |
|||
var block = '', |
|||
o = ''; |
|||
if(!this.selStr) |
|||
this.selStr = this.renderSelectors(); |
|||
var prpStr = this.renderProperties(); |
|||
if(this.selStr) |
|||
block = prpStr !== '' ? '{' + prpStr + '}' : ''; |
|||
o = this.selStr && block ? this.selStr + block : ''; |
|||
this.$el.html(o); |
|||
return this; |
|||
}, |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,63 @@ |
|||
define(['backbone','./CssRuleView'], |
|||
function (Backbone, CssRuleView) { |
|||
/** |
|||
* @class CssRulesView |
|||
* */ |
|||
return Backbone.View.extend({ |
|||
|
|||
initialize: function(o) { |
|||
this.config = o.config || {}; |
|||
this.pfx = this.config.stylePrefix || ''; |
|||
this.className = this.pfx + 'rules'; |
|||
this.listenTo( this.collection, 'add', this.addTo ); |
|||
this.listenTo( this.collection, 'reset', this.render ); |
|||
}, |
|||
|
|||
/** |
|||
* Add to collection |
|||
* @param {Object} model |
|||
* */ |
|||
addTo: function(model){ |
|||
//console.log('Added');
|
|||
this.addToCollection(model); |
|||
}, |
|||
|
|||
/** |
|||
* Add new object to collection |
|||
* @param {Object} model |
|||
* @param {Object} fragmentEl |
|||
* |
|||
* @return {Object} |
|||
* */ |
|||
addToCollection: function(model, fragmentEl){ |
|||
var fragment = fragmentEl || null; |
|||
var viewObject = CssRuleView; |
|||
|
|||
var view = new viewObject({ |
|||
model: model, |
|||
config: this.config, |
|||
}); |
|||
var rendered = view.render().el; |
|||
|
|||
if(fragment) |
|||
fragment.appendChild( rendered ); |
|||
else |
|||
this.$el.append(rendered); |
|||
|
|||
return rendered; |
|||
}, |
|||
|
|||
render: function() { |
|||
var fragment = document.createDocumentFragment(); |
|||
this.$el.empty(); |
|||
|
|||
this.collection.each(function(model){ |
|||
this.addToCollection(model, fragment); |
|||
}, this); |
|||
|
|||
this.$el.append(fragment); |
|||
this.$el.attr('class', this.className); |
|||
return this; |
|||
} |
|||
}); |
|||
}); |
|||
@ -0,0 +1,130 @@ |
|||
|
|||
define( |
|||
function(require) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('E2E tests', function() { |
|||
|
|||
/** |
|||
* Create tags viewer |
|||
* @param {Object} ctx |
|||
*/ |
|||
var instClassTagViewer = function(ctx){ |
|||
var $clm; |
|||
var clm = ctx.gjs.editor.get('ClassManager'); |
|||
clm.config.target = ctx.gjs.editor; |
|||
if(clm){ |
|||
$clm = new clm.ClassTagsView({ |
|||
collection: new clm.ClassTags([]), |
|||
config: clm.config, |
|||
}).render(); |
|||
ctx.$fixture.append($clm.el); |
|||
} |
|||
return $clm; |
|||
}; |
|||
|
|||
before(function () { |
|||
this.$fixtures = $("#fixtures"); |
|||
this.$fixture = $('<div id="ClassManager-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
var Grapes = require('editor/main'); |
|||
this.gjs = new Grapes({ |
|||
stylePrefix: '', |
|||
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(); |
|||
}); |
|||
|
|||
describe('Interaction with Components', function() { |
|||
|
|||
beforeEach(function () { |
|||
this.wrapper = this.gjs.editor.get('Components').getWrapper().get('components'); |
|||
this.$clm = instClassTagViewer(this); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.wrapper; |
|||
delete this.$clm; |
|||
}); |
|||
|
|||
it('Assign correctly new class to component', function() { |
|||
var model = this.wrapper.add({}); |
|||
model.get('classes').length.should.equal(0); |
|||
this.gjs.editor.set('selectedComponent', model); |
|||
this.$clm.addNewTag('test'); |
|||
model.get('classes').length.should.equal(1); |
|||
model.get('classes').at(0).get('name').should.equal('test'); |
|||
}); |
|||
|
|||
it('Classes from components are correctly imported inside main container', function() { |
|||
var model = this.wrapper.add([ |
|||
{ classes: ['test11', 'test12', 'test13'] }, |
|||
{ classes: ['test11', 'test22', 'test22'] }, |
|||
]); |
|||
this.gjs.editor.get('ClassManager').getClasses().length.should.equal(4); |
|||
}); |
|||
|
|||
it('Class imported into component is the same model from main container', function() { |
|||
var model = this.wrapper.add({ classes: ['test1'] }); |
|||
var clModel = model.get('classes').at(0); |
|||
var clModel2 = this.gjs.editor.get('ClassManager').getClasses().at(0); |
|||
clModel.should.deep.equal(clModel2); |
|||
}); |
|||
|
|||
it('Can assign only one time the same class on selected component and the class viewer', function() { |
|||
var model = this.wrapper.add({}); |
|||
this.gjs.editor.set('selectedComponent', model); |
|||
this.$clm.addNewTag('test'); |
|||
this.$clm.addNewTag('test'); |
|||
model.get('classes').length.should.equal(1); |
|||
model.get('classes').at(0).get('name').should.equal('test'); |
|||
this.$clm.collection.length.should.equal(1); |
|||
this.$clm.collection.at(0).get('name').should.equal('test'); |
|||
}); |
|||
|
|||
it('Removing from container removes also from selected component', function() { |
|||
var model = this.wrapper.add({}); |
|||
this.gjs.editor.set('selectedComponent', model); |
|||
this.$clm.addNewTag('test'); |
|||
this.$clm.collection.at(0).destroy(); |
|||
model.get('classes').length.should.equal(0); |
|||
}); |
|||
|
|||
it("Trigger correctly event on target with new class add", function() { |
|||
var spy = sinon.spy(); |
|||
var model = this.wrapper.add({}); |
|||
this.gjs.editor.set('selectedComponent', model); |
|||
this.$clm.addNewTag('test'); |
|||
this.gjs.editor.on("targetClassAdded", spy); |
|||
this.$clm.addNewTag('test'); |
|||
spy.called.should.equal(false); |
|||
this.$clm.addNewTag('test2'); |
|||
spy.called.should.equal(true); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,93 @@ |
|||
var modulePath = './../../../test/specs/class_manager'; |
|||
|
|||
define([ |
|||
'ClassManager', |
|||
modulePath + '/model/ClassModels', |
|||
modulePath + '/view/ClassTagView', |
|||
modulePath + '/view/ClassTagsView', |
|||
modulePath + '/e2e/ClassManager' |
|||
], |
|||
function( |
|||
ClassManager, |
|||
Models, |
|||
ClassTagView, |
|||
ClassTagsView, |
|||
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({ |
|||
defaults: ['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); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
Models.run(); |
|||
ClassTagView.run(); |
|||
ClassTagsView.run(); |
|||
e2e.run(); |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,53 @@ |
|||
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); |
|||
}); |
|||
|
|||
it('Has active property', function() { |
|||
this.obj.has('active').should.equal(true); |
|||
}); |
|||
|
|||
it('escapeName test', function() { |
|||
this.obj.escapeName('@Te sT*').should.equal('-te-st-'); |
|||
}); |
|||
|
|||
it('Name is corrected at instantiation', function() { |
|||
this.obj = new ClassTag({ name: '@Te sT*'}); |
|||
this.obj.get('name').should.equal('-te-st-'); |
|||
}); |
|||
|
|||
|
|||
}); |
|||
describe('ClassTags', function() { |
|||
|
|||
it('Creates collection item correctly', function() { |
|||
var c = new ClassTags(); |
|||
var m = c.add({}); |
|||
m.should.be.an.instanceOf(ClassTag); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,117 @@ |
|||
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 = $('<div class="classtag-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
this.coll = new ClassTags(); |
|||
this.testLabel = 'TestLabel'; |
|||
var model = this.coll.add({ |
|||
name: 'test', |
|||
label: this.testLabel, |
|||
}); |
|||
this.view = new ClassTagView({ |
|||
config : {}, |
|||
model: model, |
|||
coll: this.coll |
|||
}); |
|||
this.view.target = { get:function(){} }; |
|||
_.extend(this.view.target, Backbone.Events); |
|||
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('Has checkbox', function() { |
|||
var $el = this.view.$el; |
|||
$el.find('#checkbox').should.have.property(0); |
|||
}); |
|||
it('Has label', function() { |
|||
var $el = this.view.$el; |
|||
$el.find('#tag-label').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; |
|||
}); |
|||
|
|||
it('On remove triggers event', function() { |
|||
var spy = sinon.spy(); |
|||
sinon.stub(this.view.target, 'get').returns(0); |
|||
this.view.target.on("targetClassRemoved", spy); |
|||
this.view.$el.find('#close').trigger('click'); |
|||
spy.called.should.equal(true); |
|||
}); |
|||
|
|||
it('Checkbox toggles status', function() { |
|||
var spy = sinon.spy(); |
|||
this.view.model.on("change:active", spy); |
|||
this.view.model.set('active', true); |
|||
this.view.$el.find('#checkbox').trigger('click'); |
|||
this.view.model.get('active').should.equal(false); |
|||
spy.called.should.equal(true); |
|||
}); |
|||
|
|||
it('On toggle triggers event', function() { |
|||
var spy = sinon.spy(); |
|||
sinon.stub(this.view.target, 'get').returns(0); |
|||
this.view.target.on("targetClassUpdated", spy); |
|||
this.view.$el.find('#checkbox').trigger('click'); |
|||
spy.called.should.equal(true); |
|||
}); |
|||
|
|||
it('Label toggles status', function() { |
|||
var spy = sinon.spy(); |
|||
this.view.model.on("change:active", spy); |
|||
this.view.model.set('active', true); |
|||
this.view.$el.find('#tag-label').trigger('click'); |
|||
this.view.model.get('active').should.equal(false); |
|||
spy.called.should.equal(true); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,157 @@ |
|||
var path = 'ClassManager/view/'; |
|||
define([path + 'ClassTagsView', 'ClassManager/model/ClassTags'], |
|||
function(ClassTagsView, ClassTags) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('ClassTagsView', function() { |
|||
|
|||
before(function () { |
|||
this.$fixtures = $("#fixtures"); |
|||
this.$fixture = $('<div class="classtag-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
this.target = { get: function(){} }; |
|||
this.coll = new ClassTags(); |
|||
_.extend(this.target, Backbone.Events); |
|||
|
|||
this.view = new ClassTagsView({ |
|||
config : { target: this.target }, |
|||
collection: this.coll |
|||
}); |
|||
|
|||
this.targetStub = { |
|||
addClass: function(v){ return {name: v}; } |
|||
}; |
|||
|
|||
this.compTargetStub = { |
|||
get: function(){ return { add: function(){} }} |
|||
}; |
|||
|
|||
this.$fixture.empty().appendTo(this.$fixtures); |
|||
this.$fixture.html(this.view.render().el); |
|||
this.btnAdd = this.view.$el.find('#' + this.view.addBtnId); |
|||
this.input = this.view.$el.find('input#' + this.view.newInputId); |
|||
this.$tags = this.$fixture.find('#tags-c'); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.view.collection; |
|||
}); |
|||
|
|||
after(function () { |
|||
this.$fixture.remove(); |
|||
}); |
|||
|
|||
it('Object exists', function() { |
|||
ClassTagsView.should.be.exist; |
|||
}); |
|||
|
|||
it('Not tags inside', function() { |
|||
this.$tags.html().should.equal(''); |
|||
}); |
|||
|
|||
it('Add new tag triggers correct method', function() { |
|||
sinon.stub(this.view, "addToClasses"); |
|||
this.coll.add({ name: 'test' }); |
|||
this.view.addToClasses.calledOnce.should.equal(true); |
|||
}); |
|||
|
|||
it('Start new tag creation', function() { |
|||
this.btnAdd.click(); |
|||
(this.btnAdd.css('display') == 'none').should.equal(true); |
|||
(this.input.css('display') !== 'none').should.equal(true); |
|||
}); |
|||
|
|||
it('Stop tag creation', function() { |
|||
this.btnAdd.click(); |
|||
this.input.val('test') |
|||
this.input.blur(); |
|||
(this.btnAdd.css('display') !== 'none').should.equal(true); |
|||
(this.input.css('display') == 'none').should.equal(true); |
|||
this.input.val().should.equal(''); |
|||
}); |
|||
|
|||
it('Check keyup of ESC on input', function() { |
|||
this.btnAdd.click(); |
|||
sinon.stub(this.view, "addNewTag"); |
|||
this.input.trigger({ |
|||
type: 'keyup', |
|||
keyCode: 13 |
|||
}); |
|||
this.view.addNewTag.calledOnce.should.equal(true); |
|||
}); |
|||
|
|||
it('Check keyup on ENTER on input', function() { |
|||
this.btnAdd.click(); |
|||
sinon.stub(this.view, "endNewTag"); |
|||
this.input.trigger({ |
|||
type: 'keyup', |
|||
keyCode: 27 |
|||
}); |
|||
this.view.endNewTag.calledOnce.should.equal(true); |
|||
}); |
|||
|
|||
it('Collection changes on update of target', function() { |
|||
this.coll.add({ name: 'test' }); |
|||
this.target.trigger('change:selectedComponent'); |
|||
this.coll.length.should.equal(0); |
|||
}); |
|||
|
|||
it('Collection reacts on reset', function() { |
|||
this.coll.add([{ name: 'test1' }, { name: 'test2' }]); |
|||
sinon.stub(this.view, "addToClasses"); |
|||
this.coll.trigger('reset'); |
|||
this.view.addToClasses.calledTwice.should.equal(true); |
|||
}); |
|||
|
|||
it("Don't accept empty tags", function() { |
|||
this.view.addNewTag(''); |
|||
this.$tags.html().should.equal(''); |
|||
}); |
|||
|
|||
it("Accept new tags", function() { |
|||
sinon.stub(this.target, "get").returns(this.targetStub); |
|||
this.view.compTarget = this.compTargetStub; |
|||
this.view.addNewTag('test'); |
|||
this.view.addNewTag('test2'); |
|||
this.$tags.children().length.should.equal(2); |
|||
}); |
|||
|
|||
it("New tag correctly added", function() { |
|||
this.coll.add({ label: 'test' }); |
|||
this.$tags.children().first().find('#tag-label').html().should.equal('test'); |
|||
}); |
|||
|
|||
it("Output correctly state options", function() { |
|||
var view = new ClassTagsView({ |
|||
config : { |
|||
target: this.target, |
|||
states: [ { name: 'testName', label: 'testLabel' } ], |
|||
}, |
|||
collection: this.coll |
|||
}); |
|||
view.getStateOptions().should.equal('<option value="testName">testLabel</option>'); |
|||
}); |
|||
|
|||
describe('Should be rendered correctly', function() { |
|||
it('Has label', function() { |
|||
this.view.$el.find('#label').should.have.property(0); |
|||
}); |
|||
it('Has tags container', function() { |
|||
this.view.$el.find('#tags-c').should.have.property(0); |
|||
}); |
|||
it('Has add button', function() { |
|||
this.view.$el.find('#add-tag').should.have.property(0); |
|||
}); |
|||
it.skip('Has states input', function() { |
|||
this.view.$el.find('#states').should.have.property(0); |
|||
}); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,39 @@ |
|||
var modulePath = './../../../test/specs/code_manager'; |
|||
|
|||
define([ |
|||
'CodeManager', |
|||
modulePath + '/model/CodeModels', |
|||
//modulePath + '/view/ClassTagView',
|
|||
//modulePath + '/view/ClassTagsView',
|
|||
//modulePath + '/e2e/ClassManager'
|
|||
], |
|||
function( |
|||
CodeManager, |
|||
Models |
|||
) { |
|||
|
|||
describe('Code Manager', function() { |
|||
|
|||
describe('Main', function() { |
|||
|
|||
beforeEach(function () { |
|||
this.obj = new CodeManager(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.obj; |
|||
}); |
|||
|
|||
it('Object exists', function() { |
|||
CodeManager.should.be.exist; |
|||
}); |
|||
|
|||
}); |
|||
|
|||
Models.run(); |
|||
//ClassTagView.run();
|
|||
//ClassTagsView.run();
|
|||
//e2e.run();
|
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,151 @@ |
|||
var path = 'CodeManager/model/'; |
|||
define([path + 'HtmlGenerator', |
|||
path + 'CssGenerator', |
|||
'DomComponents/model/Component', |
|||
'CssComposer'], |
|||
function(HtmlGenerator, CssGenerator, Component, CssComposer) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('HtmlGenerator', function() { |
|||
beforeEach(function () { |
|||
this.obj = new HtmlGenerator(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.obj; |
|||
}); |
|||
|
|||
it('Build correctly one component', function() { |
|||
var comp = new Component(); |
|||
this.obj.build(comp).should.equal(''); |
|||
}); |
|||
|
|||
it('Build correctly empty component inside', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({}); |
|||
this.obj.build(comp).should.equal('<div></div>'); |
|||
}); |
|||
|
|||
it('Build correctly not empty component inside', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({ |
|||
tagName: 'article', |
|||
attributes: { |
|||
'data-test1': 'value1', |
|||
'data-test2': 'value2' |
|||
} |
|||
}); |
|||
this.obj.build(comp).should.equal('<article data-test1="value1" data-test2="value2"></article>'); |
|||
}); |
|||
|
|||
it('Build correctly component with classes', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({ |
|||
tagName: 'article', |
|||
attributes: { |
|||
'data-test1': 'value1', |
|||
'data-test2': 'value2' |
|||
} |
|||
}); |
|||
['class1', 'class2'].forEach(function(item){ |
|||
m1.get('classes').add({name: item}); |
|||
}); |
|||
this.obj.build(comp).should.equal('<article class="class1 class2" data-test1="value1" data-test2="value2"></article>'); |
|||
}); |
|||
}); |
|||
|
|||
describe('CssGenerator', function() { |
|||
beforeEach(function () { |
|||
this.obj = new CssGenerator(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.obj; |
|||
}); |
|||
|
|||
it('Build correctly one component', function() { |
|||
var comp = new Component(); |
|||
this.obj.build(comp).should.equal(''); |
|||
}); |
|||
|
|||
it('Build correctly empty component inside', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({tagName: 'article'}); |
|||
this.obj.build(comp).should.equal(''); |
|||
}); |
|||
|
|||
it('Build correctly component with style inside', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({ |
|||
tagName: 'article', |
|||
style: { |
|||
'prop1': 'value1', |
|||
'prop2': 'value2' |
|||
} |
|||
}); |
|||
this.obj.build(comp).should.equal('#' + m1.cid +'{prop1:value1;prop2:value2;}'); |
|||
}); |
|||
|
|||
it('Build correctly component with class styled', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({tagName: 'article'}); |
|||
var cls1 = m1.get('classes').add({name: 'class1'}); |
|||
|
|||
var cssc = new CssComposer(); |
|||
var rule = cssc.newRule(cls1); |
|||
rule.set('style',{'prop1':'value1', 'prop2':'value2'}); |
|||
cssc.addRule(rule); |
|||
|
|||
this.obj.build(comp, cssc).should.equal('.class1{prop1:value1;prop2:value2;}'); |
|||
}); |
|||
|
|||
it('Build correctly with more classes', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({tagName: 'article'}); |
|||
var cls1 = m1.get('classes').add({name: 'class1'}); |
|||
var cls2 = m1.get('classes').add({name: 'class2'}); |
|||
|
|||
var cssc = new CssComposer(); |
|||
var rule = cssc.newRule([cls1, cls2]); |
|||
rule.set('style',{'prop1':'value1', 'prop2':'value2'}); |
|||
cssc.addRule(rule); |
|||
|
|||
this.obj.build(comp, cssc).should.equal('.class1.class2{prop1:value1;prop2:value2;}'); |
|||
this.obj.build(comp, cssc).should.equal('.class1.class2{prop1:value1;prop2:value2;}'); |
|||
}); |
|||
|
|||
it('Build correctly with class styled out', function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({tagName: 'article'}); |
|||
var cls1 = m1.get('classes').add({name: 'class1'}); |
|||
var cls2 = m1.get('classes').add({name: 'class2'}); |
|||
|
|||
var cssc = new CssComposer(); |
|||
var rule = cssc.newRule([cls1, cls2]); |
|||
rule.set('style',{'prop1':'value1'}); |
|||
cssc.addRule(rule); |
|||
var rule2 = cssc.newRule(cls2); |
|||
rule2.set('style',{'prop2':'value2'}); |
|||
cssc.addRule(rule2); |
|||
|
|||
this.obj.build(comp, cssc).should.equal('.class1.class2{prop1:value1;}.class2{prop2:value2;}'); |
|||
}); |
|||
it("Avoid useless code", function() { |
|||
var comp = new Component(); |
|||
var m1 = comp.get('components').add({tagName: 'article'}); |
|||
var cls1 = m1.get('classes').add({name: 'class1'}); |
|||
|
|||
var cssc = new CssComposer(); |
|||
var rule = cssc.newRule(cls1); |
|||
rule.set('style',{'prop1':'value1', 'prop2':'value2'}); |
|||
cssc.addRule(rule); |
|||
|
|||
comp.get('components').remove(m1); |
|||
this.obj.build(comp, cssc).should.equal(''); |
|||
}); |
|||
}) |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,82 @@ |
|||
|
|||
define(function(require) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('E2E tests', function() { |
|||
|
|||
before(function () { |
|||
this.$fixtures = $("#fixtures"); |
|||
this.$fixture = $('<div id="csscomposer-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
this.Grapes = require('editor/main'); |
|||
this.gjs = new this.Grapes({ |
|||
stylePrefix: '', |
|||
storageType: 'none', |
|||
storageManager: { storageType: 'none', }, |
|||
assetManager: { storageType: 'none', }, |
|||
container: 'csscomposer-fixture', |
|||
}); |
|||
this.cssc = this.gjs.editor.get('CssComposer'); |
|||
this.clsm = this.gjs.editor.get('ClassManager'); |
|||
this.$fixture.empty().appendTo(this.$fixtures); |
|||
this.gjs.render(); |
|||
this.rulesSet = [ |
|||
{ selectors: [{name: 'test1'}, {name: 'test2'}] }, |
|||
{ selectors: [{name: 'test2'}, {name: 'test3'}] }, |
|||
{ selectors: [{name: 'test3'}] } |
|||
]; |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.Grapes; |
|||
delete this.gjs; |
|||
delete this.cssc; |
|||
delete this.clsm; |
|||
}); |
|||
|
|||
after(function () { |
|||
this.$fixture.remove(); |
|||
}); |
|||
|
|||
it('Rules are correctly imported from default property', function() { |
|||
var gj = new this.Grapes({ |
|||
stylePrefix: '', |
|||
storageType: 'none', |
|||
storageManager: { storageType: 'none', }, |
|||
assetManager: { storageType: 'none', }, |
|||
cssComposer: { defaults: this.rulesSet}, |
|||
container: 'csscomposer-fixture', |
|||
}); |
|||
var cssc = gj.editor.get('CssComposer'); |
|||
cssc.getRules().length.should.equal(this.rulesSet.length); |
|||
var cls = gj.editor.get('ClassManager').getClasses(); |
|||
cls.length.should.equal(3); |
|||
}); |
|||
|
|||
|
|||
it('New rule adds correctly the class inside classe manager', function() { |
|||
var rules = this.cssc.getRules(); |
|||
rules.add({ selectors: [{name: 'test1'}] }); |
|||
this.clsm.getClasses().at(0).get('name').should.equal('test1'); |
|||
}); |
|||
|
|||
it('New rules are correctly imported inside classe manager', function() { |
|||
var rules = this.cssc.getRules(); |
|||
this.rulesSet.forEach(function(item){ |
|||
rules.add(item); |
|||
}); |
|||
var cls = this.clsm.getClasses(); |
|||
cls.length.should.equal(3); |
|||
cls.at(0).get('name').should.equal('test1'); |
|||
cls.at(1).get('name').should.equal('test2'); |
|||
cls.at(2).get('name').should.equal('test3'); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,143 @@ |
|||
var modulePath = './../../../test/specs/css_composer'; |
|||
|
|||
define([ |
|||
'CssComposer', |
|||
modulePath + '/model/CssModels', |
|||
modulePath + '/view/CssRuleView', |
|||
modulePath + '/view/CssRulesView', |
|||
modulePath + '/e2e/CssComposer' |
|||
], |
|||
function( |
|||
CssComposer, |
|||
Models, |
|||
CssRuleView, |
|||
CssRulesView, |
|||
e2e |
|||
) { |
|||
|
|||
describe('Css Composer', function() { |
|||
|
|||
describe('Main', function() { |
|||
|
|||
beforeEach(function () { |
|||
this.obj = new CssComposer(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.obj; |
|||
}); |
|||
|
|||
it('Object exists', function() { |
|||
CssComposer.should.be.exist; |
|||
}); |
|||
|
|||
it("Rules are empty", function() { |
|||
this.obj.getRules().length.should.equal(0); |
|||
}); |
|||
|
|||
it('Create new rule with correct selectors', function() { |
|||
var sel = new this.obj.Selectors(); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var rule = this.obj.newRule(sel.models); |
|||
rule.get('selectors').at(0).should.deep.equal(s1); |
|||
}); |
|||
|
|||
it('Create new rule correctly', function() { |
|||
var sel = new this.obj.Selectors(); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var rule = this.obj.newRule(sel.models, 'state1', 'width1'); |
|||
rule.get('state').should.equal('state1'); |
|||
rule.get('maxWidth').should.equal('width1'); |
|||
}); |
|||
|
|||
it("Add rule to collection", function() { |
|||
var sel = new this.obj.Selectors([{name: 'test1'}]); |
|||
var rule = this.obj.newRule(sel.models); |
|||
this.obj.addRule(rule); |
|||
this.obj.getRules().length.should.equal(1); |
|||
this.obj.getRules().at(0).get('selectors').at(0).get('name').should.equal('test1'); |
|||
}); |
|||
|
|||
it("Returns correct rule with the same selector", function() { |
|||
var sel = new this.obj.Selectors([{name: 'test1'}]); |
|||
var rule1 = this.obj.newRule(sel.models); |
|||
this.obj.addRule(rule1); |
|||
var rule2 = this.obj.getRule(sel.models); |
|||
rule1.should.deep.equal(rule2); |
|||
}); |
|||
|
|||
it("Returns correct rule with the same selectors", function() { |
|||
var sel1 = new this.obj.Selectors([{name: 'test1'}]); |
|||
var rule1 = this.obj.newRule(sel1.models); |
|||
this.obj.addRule(rule1); |
|||
|
|||
var sel2 = new this.obj.Selectors([{name: 'test21'}, {name: 'test22'}]); |
|||
var rule2 = this.obj.newRule(sel2.models); |
|||
this.obj.addRule(rule2); |
|||
|
|||
var rule3 = this.obj.getRule(sel2.models); |
|||
rule3.should.deep.equal(rule2); |
|||
}); |
|||
|
|||
it("Don't duplicate rules", function() { |
|||
var sel = new this.obj.Selectors([]); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var s2 = sel.add({name: 'test2'}); |
|||
var s3 = sel.add({name: 'test3'}); |
|||
|
|||
var rule1 = this.obj.newRule([s1, s3]); |
|||
var aRule1 = this.obj.addRule(rule1); |
|||
|
|||
var rule2 = this.obj.newRule([s3, s1]); |
|||
var aRule2 = this.obj.addRule(rule2); |
|||
|
|||
aRule2.should.deep.equal(aRule1); |
|||
}); |
|||
|
|||
it("Returns correct rule with the same mixed selectors", function() { |
|||
var sel = new this.obj.Selectors([]); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var s2 = sel.add({name: 'test2'}); |
|||
var s3 = sel.add({name: 'test3'}); |
|||
var rule1 = this.obj.newRule([s1, s3]); |
|||
this.obj.addRule(rule1); |
|||
|
|||
var rule2 = this.obj.getRule([s3, s1]); |
|||
rule2.should.deep.equal(rule1); |
|||
}); |
|||
|
|||
it("Returns correct rule with the same selectors and state", function() { |
|||
var sel = new this.obj.Selectors([]); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var s2 = sel.add({name: 'test2'}); |
|||
var s3 = sel.add({name: 'test3'}); |
|||
var rule1 = this.obj.newRule([s1, s3], 'hover'); |
|||
this.obj.addRule(rule1); |
|||
|
|||
var rule2 = this.obj.getRule([s3, s1], 'hover'); |
|||
rule2.should.deep.equal(rule1); |
|||
}); |
|||
|
|||
it("Returns correct rule with the same selectors, state and width", function() { |
|||
var sel = new this.obj.Selectors([]); |
|||
var s1 = sel.add({name: 'test1'}); |
|||
var rule1 = this.obj.newRule([s1], 'hover','1'); |
|||
this.obj.addRule(rule1); |
|||
|
|||
var rule2 = this.obj.getRule([s1], 'hover', '1'); |
|||
rule2.should.deep.equal(rule1); |
|||
}); |
|||
|
|||
it("Renders correctly", function() { |
|||
this.obj.render().should.be.ok; |
|||
}); |
|||
|
|||
}); |
|||
|
|||
Models.run(); |
|||
CssRuleView.run(); |
|||
CssRulesView.run(); |
|||
e2e.run(); |
|||
|
|||
}); |
|||
}); |
|||
@ -0,0 +1,84 @@ |
|||
var path = 'CssComposer/model/'; |
|||
define([path + 'CssRule', |
|||
path + 'CssRules', |
|||
path + 'Selectors', |
|||
'ClassManager/model/ClassTag'], |
|||
function(CssRule, CssRules, Selectors, ClassTag) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('CssRule', function() { |
|||
|
|||
beforeEach(function () { |
|||
this.obj = new CssRule(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
delete this.obj; |
|||
}); |
|||
|
|||
it('Has selectors property', function() { |
|||
this.obj.has('selectors').should.equal(true); |
|||
}); |
|||
|
|||
it('Has style property', function() { |
|||
this.obj.has('style').should.equal(true); |
|||
}); |
|||
|
|||
it('Has state property', function() { |
|||
this.obj.has('state').should.equal(true); |
|||
}); |
|||
|
|||
it('No default selectors', function() { |
|||
this.obj.get('selectors').length.should.equal(0); |
|||
}); |
|||
|
|||
it('Compare returns true with the same selectors', function() { |
|||
var s1 = this.obj.get('selectors').add({ name: 'test1' }); |
|||
var s2 = this.obj.get('selectors').add({ name: 'test2' }); |
|||
this.obj.compare([s1, s2]).should.equal(true); |
|||
}); |
|||
|
|||
it('Compare with different state', function() { |
|||
var s1 = this.obj.get('selectors').add({ name: 'test1' }); |
|||
var s2 = this.obj.get('selectors').add({ name: 'test2' }); |
|||
this.obj.set('state','hover'); |
|||
this.obj.compare([s1, s2]).should.equal(false); |
|||
this.obj.compare([s1, s2], 'hover').should.equal(true); |
|||
}); |
|||
|
|||
it('Compare with different maxWidth', function() { |
|||
var s1 = this.obj.get('selectors').add({ name: 'test1' }); |
|||
var s2 = this.obj.get('selectors').add({ name: 'test2' }); |
|||
this.obj.set('state','hover'); |
|||
this.obj.set('maxWidth','1000'); |
|||
this.obj.compare([s1, s2]).should.equal(false); |
|||
this.obj.compare([s1, s2], 'hover').should.equal(false); |
|||
this.obj.compare([s2, s1], 'hover', '1000').should.equal(true); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
describe('CssRules', function() { |
|||
|
|||
it('Creates collection item correctly', function() { |
|||
var c = new CssRules(); |
|||
var m = c.add({}); |
|||
m.should.be.an.instanceOf(CssRule); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
describe('Selectors', function() { |
|||
|
|||
it('Creates collection item correctly', function() { |
|||
var c = new Selectors(); |
|||
var m = c.add({}); |
|||
m.should.be.an.instanceOf(ClassTag); |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,101 @@ |
|||
var path = 'CssComposer/view/'; |
|||
define([path + 'CssRuleView', 'CssComposer/model/CssRule'], |
|||
function(CssRuleView, CssRule) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('CssRuleView', function() { |
|||
|
|||
before(function () { |
|||
this.$fixtures = $("#fixtures"); |
|||
this.$fixture = $('<div class="cssrule-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
var m = new CssRule(); |
|||
this.view = new CssRuleView({ |
|||
model: m |
|||
}); |
|||
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() { |
|||
CssRuleView.should.be.exist; |
|||
}); |
|||
|
|||
it('Correct behaviour of renderSelectors with single selector', function() { |
|||
this.view.model.get('selectors').add({name: 'test'}); |
|||
this.view.renderSelectors().should.equal('.test'); |
|||
}); |
|||
|
|||
it('Correct behaviour of renderSelectors with multiple selectors', function() { |
|||
this.view.model.get('selectors').add([{name: 'test2'}, {name: 'test1'}]); |
|||
this.view.renderSelectors().should.equal('.test2.test1'); |
|||
}); |
|||
|
|||
it('Correct behaviour of renderProperties with single property', function() { |
|||
this.view.model.set('style', {'prop': 'value'}); |
|||
this.view.renderProperties().should.equal('prop:value;'); |
|||
}); |
|||
|
|||
it('Correct behaviour of renderProperties with multiple properties', function() { |
|||
this.view.model.set('style', {'prop2': 'value2', 'prop3': 'value3'}); |
|||
this.view.renderProperties().should.equal('prop2:value2;prop3:value3;'); |
|||
}); |
|||
|
|||
it('Empty style inside', function() { |
|||
this.$fixture.html().should.equal('<style></style>'); |
|||
}); |
|||
|
|||
it('On update of style always empty as there is no selectors', function() { |
|||
this.view.model.set('style', {'prop':'value'}); |
|||
this.$fixture.html().should.equal('<style></style>'); |
|||
}); |
|||
|
|||
describe('CssRuleView with selectors', function() { |
|||
|
|||
beforeEach(function () { |
|||
var m = new CssRule({ |
|||
selectors: [{name:'test1'}, {name:'test2'}] |
|||
}); |
|||
this.regView = new CssRuleView({ |
|||
model: m |
|||
}); |
|||
this.regView.render(); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
this.regView.model.destroy(); |
|||
}); |
|||
|
|||
it('Empty with no style', function() { |
|||
this.regView.$el.html().should.equal(''); |
|||
}); |
|||
|
|||
it('Not empty on update of style', function() { |
|||
this.regView.model.set('style', {'prop':'value'}); |
|||
this.regView.$el.html().should.equal('.test1.test2{prop:value;}'); |
|||
}); |
|||
|
|||
it('Empty on clear', function() { |
|||
this.regView.model.set('style', {'prop':'value'}); |
|||
this.regView.model.set('style', {}); |
|||
this.regView.$el.html().should.equal(''); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -0,0 +1,54 @@ |
|||
var path = 'CssComposer/view/'; |
|||
define([path + 'CssRulesView', 'CssComposer/model/CssRules'], |
|||
function(CssRulesView, CssRules) { |
|||
|
|||
return { |
|||
run : function(){ |
|||
describe('CssRulesView', function() { |
|||
|
|||
before(function () { |
|||
this.$fixtures = $("#fixtures"); |
|||
this.$fixture = $('<div class="cssrules-fixture"></div>'); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
var col = new CssRules([]); |
|||
this.view = new CssRulesView({ |
|||
collection: col |
|||
}); |
|||
this.$fixture.empty().appendTo(this.$fixtures); |
|||
this.$fixture.html(this.view.render().el); |
|||
}); |
|||
|
|||
afterEach(function () { |
|||
this.view.collection.reset(); |
|||
}); |
|||
|
|||
after(function () { |
|||
this.$fixture.remove(); |
|||
}); |
|||
|
|||
it('Object exists', function() { |
|||
CssRulesView.should.be.exist; |
|||
}); |
|||
|
|||
it("Collection is empty", function (){ |
|||
this.view.$el.html().should.be.empty; |
|||
}); |
|||
|
|||
it("Add new rule", function (){ |
|||
sinon.stub(this.view, "addToCollection"); |
|||
this.view.collection.add({}); |
|||
this.view.addToCollection.calledOnce.should.equal(true); |
|||
}); |
|||
|
|||
it("Render new rule", function (){ |
|||
this.view.collection.add({}); |
|||
this.view.$el.html().should.not.be.empty; |
|||
}); |
|||
|
|||
}); |
|||
} |
|||
}; |
|||
|
|||
}); |
|||
@ -1,25 +0,0 @@ |
|||
|
|||
define(['panelModel','appDir/panel_commands/buttons/main'], |
|||
function(panelModel, commandsButtonsProvider) { |
|||
describe('Panel', function() { |
|||
|
|||
it('Contiene valori di default', function() { //Has default values
|
|||
var model = new panelModel({}); |
|||
model.should.be.ok; |
|||
model.get('name').should.equal(""); |
|||
model.get('visible').should.equal(true); |
|||
model.get('buttons').should.equal.undefined; |
|||
}); |
|||
it('Imposta valori passati', function() { //Sets passed attributes
|
|||
var model = new panelModel({ |
|||
name:'command', |
|||
visible: false, |
|||
buttons: commandsButtonsProvider.createButtons(), |
|||
}); |
|||
model.should.be.ok; |
|||
model.get('name').should.equal("command"); |
|||
model.get('visible').should.equal(false); |
|||
model.get('buttons').should.have.length(5); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -1,49 +0,0 @@ |
|||
|
|||
define(['panelModel', 'panelView', 'Buttons', 'appDir/panel_commands/buttons/main'], |
|||
function(panelModel,panelView, Buttons, commandsButtonsProvider) { |
|||
describe('PanelView', function() { |
|||
before(function () { |
|||
this.testPanelName = 'commands'; |
|||
this.$fixture = $("<div id='panel-fixture'></div>"); |
|||
}); |
|||
|
|||
beforeEach(function () { |
|||
this.view = new panelView({ |
|||
model: new panelModel({ |
|||
name : this.testPanelName, |
|||
buttons: commandsButtonsProvider.createButtons(), |
|||
}), |
|||
eventsQ : { |
|||
commands: {createComponent : {}} |
|||
}, |
|||
}); |
|||
this.$fixture.empty().appendTo($("#fixtures")); |
|||
this.$fixture.html(this.view.render().el); |
|||
}); |
|||
afterEach(function () { |
|||
//this.view.model.destroy();
|
|||
}); |
|||
|
|||
after(function () { |
|||
//this.$fixture.remove();
|
|||
}); |
|||
describe("Inizializzazione", function () { |
|||
it('Render pannello', function() { //Has default values
|
|||
this.view.should.be.ok; |
|||
this.view.$el.attr('id').should.equal(this.testPanelName); |
|||
}); |
|||
it('Non deve essere vuoto', function() { |
|||
this.view.$el.find('.c a').should.have.length.above(0); |
|||
}); |
|||
it('Nessun elemento deve essere attivo', function() { |
|||
this.view.$el.find('.c a.active').should.have.length(0); |
|||
}); |
|||
}); |
|||
describe("Interazione", function(){ |
|||
it('Elemento attivo alla richiesta', function(){ |
|||
this.view.model.buttons.models[0].toggle(); |
|||
this.view.$el.find('.c a.active').should.have.length(1); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue