Browse Source

Add PropertyCompositeView tests

pull/36/head
Artur Arseniev 10 years ago
parent
commit
3a3b40ecfd
  1. 2
      src/style_manager/model/Property.js
  2. 16
      src/style_manager/view/PropertiesView.js
  3. 32
      src/style_manager/view/PropertyCompositeView.js
  4. 27
      src/style_manager/view/PropertyView.js
  5. 5
      test/specs/style_manager/main.js
  6. 213
      test/specs/style_manager/view/PropertyCompositeView.js

2
src/style_manager/model/Property.js

@ -11,7 +11,7 @@ define(['backbone'],
unit: '',
defaults: '',
info: '',
value: '', //Selected value of the property (?)
value: '',
icon: '',
preview: false,
functionName: '',

16
src/style_manager/view/PropertiesView.js

@ -41,14 +41,14 @@ define(['backbone','./PropertyView', './PropertyIntegerView', './PropertyRadioVi
}
var view = new objView({
model : model,
name : model.get('name'),
id : this.pfx + model.get('property'),
target : this.target,
propTarget : this.propTarget,
onChange : this.onChange,
onInputRender : this.onInputRender,
config : this.config,
model: model,
name: model.get('name'),
id: this.pfx + model.get('property'),
target: this.target,
propTarget: this.propTarget,
onChange: this.onChange,
onInputRender: this.onInputRender,
config: this.config,
});
if(model.get('type') != 'composite'){

32
src/style_manager/view/PropertyCompositeView.js

@ -10,8 +10,8 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
initialize: function(o) {
PropertyView.prototype.initialize.apply(this, arguments);
_.bindAll(this, 'build');
this.config = o.config;
this.className = this.className + ' '+ this.pfx +'composite';
this.config = o.config || {};
this.className = this.className + ' '+ this.pfx +'composite';
},
/**
@ -26,8 +26,8 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
this.$input = $('<input>', {value: 0, type: 'hidden' });
if(!this.props){
var Properties = require('./../model/Properties');
this.props = new Properties(props);
var Properties = require('./../model/Properties');
this.props = new Properties(props);
this.model.set('properties', this.props);
}
@ -36,13 +36,14 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
this.props.each(function(prop, index){
prop.set('doNotStyle', true);
});
//Not yet supported nested composite
this.props.each(function(prop, index){
if(prop && prop.get('type') == 'composite'){
this.props.remove(prop);
console.warn(prop.get('property')+' of type composite not yet allowed.');
console.warn('Nested composite types not yet allowed.');
}
},this);
}, this);
var PropertiesView = require('./PropertiesView');
var that = this;
@ -51,17 +52,23 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
collection : this.props,
target : this.target,
propTarget : this.propTarget,
// On any change made to children I need to update composite value
onChange : function(el, model){
var result = that.build(el, model);
that.model.set('value', result);
},
onInputRender : function(property, mIndex){
var value = that.valueOnIndex(mIndex, property.model);
property.setValue(value);
},
// Each child property will receive a full composite string, eg. '0px 0px 10px 0px'
// I need to extract from that string the corresponding one to that property.
customValue : function(property, mIndex){
return that.valueOnIndex(mIndex, property.model);
},
// setValue is already invoked by renderInput().
// TODO: Remove definitively after all tests
/*
onInputRender : function(property, mIndex){
var value = that.valueOnIndex(mIndex, property.model);
property.setValue(value);
},*/
});
this.$props = propsView.render().$el;
this.$el.find('#'+ this.pfx +'input-holder').html(this.$props);
@ -94,7 +101,6 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
var a = this.getComponentValue().split(' ');
if(a.length && a[index]){
result = a[index];
//Check for function type values
if(model && model.get('functionName')){
var v = this.fetchFromFunction(result);
if(v)
@ -108,19 +114,19 @@ define(['backbone','./PropertyView', 'text!./../templates/propertyComposite.html
* Build composite value
* @param Object Selected element
* @param Object Property model
*
* @todo alias getValueForTarget?
* @return string
* */
build: function(selectedEl, propertyModel){
var result = '';
this.model.get('properties').each(function(prop){
//TODO v = prop.getValueForTarget(); -> functionName inside?!?
var v = (prop.get('value') || prop.get('defaults')) + prop.get('unit'),
func = prop.get('functionName');
if(func)
v = func + '(' + v + ')';
result += v + ' ';
});
//Remove also the last white space
return result.replace(/ +$/,'');
},

27
src/style_manager/view/PropertyView.js

@ -32,6 +32,16 @@ define(['backbone', 'text!./../templates/propertyLabel.html', 'text!./../templat
this.listenTo( this.model ,'change:value', this.valueChanged);
},
/**
* Returns selected target which should have 'style' property
* @return {Model|null}
*/
getTarget: function(){
if(this.selectedComponent)
return this.selectedComponent;
return this.propTarget ? this.propTarget.model : null;
},
/**
* Fired when the input value is updated
*/
@ -136,7 +146,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html', 'text!./../templat
if(this.$input)
this.setValue(mVal);
if(!this.selectedComponent)
if(!this.getTarget())
return;
// Check if component is allowed to be styled
@ -149,21 +159,20 @@ define(['backbone', 'text!./../templates/propertyLabel.html', 'text!./../templat
value = this.func + '(' + value + ')';
if( !this.model.get('doNotStyle') ){
var componentCss = _.clone( this.selectedComponent.get('style') );
var componentCss = _.clone( this.getTarget().get('style') );
if(value)
componentCss[this.property] = value;
else
delete componentCss[this.property];
this.selectedComponent.set('style', componentCss, { avoidStore : avSt});
this.getTarget().set('style', componentCss, { avoidStore : avSt});
if(this.helperComponent)
this.helperComponent.set('style', componentCss, { avoidStore : avSt});
}
this.selectedValue = value;
if(this.onChange && typeof this.onChange === "function"){
this.onChange(this.selectedComponent, this.model);
this.onChange(this.getTarget(), this.model);
}
},
@ -172,9 +181,7 @@ define(['backbone', 'text!./../templates/propertyLabel.html', 'text!./../templat
* @return {Boolean}
*/
isTargetStylable: function(){
if(!this.selectedComponent)
return;
var stylable = this.selectedComponent.get('stylable');
var stylable = this.getTarget().get('stylable');
// Stylable could also be an array indicating with which property
// the target could be styled
if(stylable instanceof Array)
@ -251,10 +258,6 @@ define(['backbone', 'text!./../templates/propertyLabel.html', 'text!./../templat
* */
renderInputRequest: function(){
this.renderInput();
if(this.onInputRender && typeof this.onInputRender === "function"){
var index = this.model.collection.indexOf(this.model);
this.onInputRender(this, index);
}
},
/**

5
test/specs/style_manager/main.js

@ -10,6 +10,7 @@ define([
modulePath + '/view/PropertyRadioView',
modulePath + '/view/PropertyIntegerView',
modulePath + '/view/PropertyColorView',
modulePath + '/view/PropertyCompositeView',
],
function(
StyleManager,
@ -20,7 +21,8 @@ define([
PropertySelectView,
PropertyRadioView,
PropertyIntegerView,
PropertyColorView
PropertyColorView,
PropertyCompositeView
) {
describe('StyleManager', function() {
@ -194,6 +196,7 @@ define([
PropertyRadioView.run();
PropertyIntegerView.run();
PropertyColorView.run();
PropertyCompositeView.run();
});

213
test/specs/style_manager/view/PropertyCompositeView.js

@ -0,0 +1,213 @@
var path = 'StyleManager/view/';
define([path + 'PropertyCompositeView', 'StyleManager/model/Property', 'DomComponents/model/Component'],
function(PropertyCompositeView, Property, Component) {
return {
run : function(){
describe('PropertyCompositeView', function() {
var component;
var $fixtures;
var $fixture;
var target;
var model;
var view;
var propName = 'testprop';
var propValue = 'test1value';
var defValue = 'test2value';
var properties = [
{property: 'subprop1'},
{
type: 'integer',
property: 'subprop2',
defaults: 0,
units: ['%', 'px']
},
{
type: 'select',
property: 'subprop3',
defaults: 'val2',
list: [
{value:'val1'},
{value:'val2'},
{value:'val3'},
]
},
];
before(function () {
$fixtures = $("#fixtures");
$fixture = $('<div class="sm-fixture"></div>');
});
beforeEach(function () {
target = new Component();
component = new Component();
target.model = component;
model = new Property({
type: 'composite',
property: propName,
properties: properties
});
view = new PropertyCompositeView({
model: model
});
$fixture.empty().appendTo($fixtures);
$fixture.html(view.render().el);
});
afterEach(function () {
//view.remove(); // strange errors ???
});
after(function () {
$fixture.remove();
delete component;
delete view;
delete model;
});
it('Rendered correctly', function() {
var prop = view.el;
$fixture.get(0).querySelector('.property').should.be.ok;
prop.querySelector('.label').should.be.ok;
prop.querySelector('.field').should.be.ok;
});
it('Properties rendered', function() {
var prop = view.el;
prop.querySelector('.properties').should.be.ok;
});
it('Properties rendered correctly', function() {
var children = view.el.querySelector('.properties').children;
children.length.should.equal(properties.length + 1);
children[0].id.should.equal(properties[0].property);
children[1].id.should.equal(properties[1].property);
children[2].id.should.equal(properties[2].property);
});
it('Props should exist', function() {
view.$props.should.be.ok;
});
it('Input value is empty', function() {
view.model.get('value').should.be.empty;
});
it('Update input on value change', function() {
view.model.set('value', propValue);
view.$input.val().should.equal(propValue);
});
describe('With target setted', function() {
var prop2Val;
var prop3Val;
var prop2Unit;
var finalResult;
var $prop1;
var $prop2;
var $prop3;
beforeEach(function () {
model = new Property({
type: 'composite',
property: propName,
properties: properties
});
view = new PropertyCompositeView({
model: model,
propTarget: target
});
$fixture.empty().appendTo($fixtures);
$fixture.html(view.render().el);
prop3Val = properties[2].list[2].value;
prop2Val = properties[1].defaults;
prop2Unit = properties[1].units[0];
finalResult = propValue + ' ' + prop2Val + prop2Unit +' ' + prop3Val;
$prop1 = view.$props.find('#' + properties[0].property + ' input');
$prop2 = view.$props.find('#' + properties[1].property + ' input');
$prop3 = view.$props.find('#' + properties[2].property + ' select');
});
it('Update model on input change', function() {
var $prop1 = view.$props.find('#' + properties[0].property + ' input');
var $prop2 = view.$props.find('#' + properties[1].property + ' input');
var $prop3 = view.$props.find('#' + properties[2].property + ' select');
var prop3Val = properties[2].list[2].value;
var prop2Val = properties[1].defaults;
var prop2Unit = properties[1].units[0];
var finalResult = propValue + ' ' + prop2Val + prop2Unit +' ' + prop3Val;
$prop1.val(propValue).trigger('change');
$prop3.val(prop3Val).trigger('change');
view.model.get('value').should.equal(finalResult);
});
it('Update value on models change', function() {
view.model.get('properties').at(0).set('value', propValue);
view.model.get('properties').at(2).set('value', prop3Val);
view.model.get('value').should.equal(finalResult);
});
it('Update target on value change', function() {
var $prop1 = view.$props.find('#' + properties[0].property + ' input');
$prop1.val(propValue).trigger('change');
var compStyle = view.getTarget().get('style');
var assertStyle = {};
assertStyle[propName] = propValue + ' 0% val2';
compStyle.should.deep.equal(assertStyle);
});
it('Update value and input on target swap', function() {
var style = {};
style[propName] = finalResult;
component.set('style', style);
view.propTarget.trigger('update');
$prop1.val().should.equal(propValue);
$prop3.val().should.equal(prop3Val);
});
it('Update value after multiple swaps', function() {
var style = {};
style[propName] = finalResult;
component.set('style', style);
view.propTarget.trigger('update');
style[propName] = propValue + '2 ' + prop2Val + '2' + prop2Unit +' ' + 'val1';
component.set('style', style);
view.propTarget.trigger('update');
$prop1.val().should.equal(propValue + '2');
$prop2.val().should.equal('2');
$prop3.val().should.equal('val1');
});
})
describe('Init property', function() {
beforeEach(function () {
model = new Property({
type: 'composite',
property: propName,
properties: properties,
defaults: defValue,
});
view = new PropertyCompositeView({
model: model
});
$fixture.empty().appendTo($fixtures);
$fixture.html(view.render().el);
});
it('Value as default', function() {
view.model.get('value').should.equal(defValue);
});
});
});
}
};
});
Loading…
Cancel
Save