Skip to content

Commit

Permalink
functional test specs
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Turner committed Jul 6, 2016
1 parent 9984b13 commit f3992db
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 426 deletions.
12 changes: 7 additions & 5 deletions polymer-redux.js
Expand Up @@ -58,20 +58,22 @@

// prevent unnecesary polymer notifications
previous = element.get(property.name);
if(value === previous) {
if (value === previous) {
return;
}

// type of array, work out splices before setting the value
if (property.type === Array) {
value = value || [];
previous = previous || [];
value = value || /* istanbul ignore next */ [];
previous = previous || /* istanbul ignore next */ [];

// check the value type
if (!Array.isArray(value)) {
throw new TypeError('<%s>.%s type is Array but given: %s', element.is, propName, typeof value);
throw new TypeError(
'<'+ element.is +'>.'+ propName +' type is Array but given: ' + (typeof value)
);
}

splices = Polymer.ArraySplice.calculateSplices(value, previous);
}

Expand Down
3 changes: 2 additions & 1 deletion test/index.html
Expand Up @@ -8,7 +8,8 @@
<body>
<script>
WCT.loadSuites([
'polymer-redux.unit-spec.html'
'polymer-redux.unit-spec.html',
'polymer-redux.func-spec.html'
]);
</script>
</body>
Expand Down
181 changes: 181 additions & 0 deletions test/polymer-redux.func-spec.html
@@ -0,0 +1,181 @@
<!doctype html>
<html>
<head>
<title>Polymer Redux Functional Specs</title>
<meta charset="utf-8">
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../web-component-tester/browser.js"></script>
<link rel="import" href="../polymer-redux.html">
<link rel="import" href="./support/redux-stub.html">
</head>
<body>
<test-fixture id="state-path-fixture">
<template>
<state-path></state-path>
</template>
</test-fixture>
<script>
describe('PolymerRedux', function() {
before(function() {
var that = this;

this.store = ReduxStub.createStore();

// mock the redux unsubscribe
this.listener = null;
this.unsubscribe = sinon.spy(function() {
that.listener = null;
});

// store state
this.state = {
name: 'foo',
deep: {
path: 'bar'
},
warn: 'baz',
read: 'bax',
none: 'baxx',
array: []
};
this.store.getState.returns(this.state);
// grab the internal listener from the behavior
this.store.subscribe = sinon.spy(function(fn) {
that.listener = fn;
return that.unsubscribe;
});
// mock redux dispatch
this.store.dispatch = sinon.spy(function(action) {
that.listener();
});

// test element
Polymer({
is: 'state-path',
behaviors: [ PolymerRedux(this.store) ],
properties: {
state: {
type: String,
statePath: ''
},
name: {
type: String,
statePath: 'name'
},
deepPath: {
type: String,
statePath: 'deep.path'
},
warn: {
type: String,
statePath: 'warn',
notify: true
},
read: {
type: String,
statePath: 'read',
readOnly: true
},
array: {
type: Array,
statePath: 'array'
},
none: {
type: String
}
}
});
});

describe('properties', function() {
before(function() {
this.warnSpy = sinon.spy(console, 'warn');
this.propertyElement = fixture('state-path-fixture');
});

it('should set empty statePath to store state', function() {
assert.strictEqual(this.propertyElement.state, this.state);
});

it('should set property to statePath from store', function() {
assert.strictEqual(this.propertyElement.name, this.state.name);
});

it('should set property to deep statePath from store', function() {
assert.strictEqual(this.propertyElement.deepPath, this.state.deep.path);
});

it('should warn againgst "notify" flag on properties', function() {
sinon.assert.calledWithMatch(
this.warnSpy,
sinon.match.string,
sinon.match(this.propertyElement.is),
sinon.match('warn')
);
});

it('should set "readOnly" property to statePath from store', function() {
assert.strictEqual(this.propertyElement.read, this.state.read);
});

it('should not set any properties without statePath', function() {
assert.notEqual(this.propertyElement.none, this.state.none);
});

describe('dispatching actions', function() {
before(function() {
this.dispatchElement = fixture('state-path-fixture');

// mock reducer logic
this.state.name = 'something';
this.state.array = ['item'];

this.fireEvent = sinon.spy(this.dispatchElement, 'fire');
this.notifySplices = sinon.spy(this.dispatchElement, 'notifySplices');
this.notifyPath = sinon.spy(this.dispatchElement, 'notifyPath');
this.set = sinon.spy(this.dispatchElement, 'set');

this.listener();
});

it('should fire the "state-changed" event', function() {
sinon.assert.calledWithMatch(
this.fireEvent,
sinon.match('state-changed'),
sinon.match.same(this.state)
);
});

it('should not set properties with same values', function() {
sinon.assert.neverCalledWithMatch(
this.set,
sinon.match('deepPath')
);
});

it('should not update readonly property with same values', function() {
sinon.assert.neverCalledWithMatch(
this.notifyPath,
sinon.match('read')
);
});

it('should notify on array splices update', function() {
sinon.assert.calledWithMatch(
this.notifySplices,
sinon.match('array'),
sinon.match.array
);
});

it('should throw error if calculating array splices with non-array', function() {
fixture('state-path-fixture');
this.state.array = 'string';
assert.throws(this.listener, /<state-path>\.array type is Array but given: string/);
});
});
});
});
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion test/polymer-redux.unit-spec.html
Expand Up @@ -17,7 +17,7 @@
}, /missing redux store/);
});

describe('Behavior instance', function() {
describe('behavior instance', function() {
before(function() {
this.state = {};
this.element = {
Expand Down

0 comments on commit f3992db

Please sign in to comment.