chai-backbone-rails 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +42 -0
- data/lib/chai-backbone-rails/version.rb +1 -1
- data/vendor/assets/javascripts/chai-backbone.js.coffee +135 -24
- data/vendor/assets/javascripts/factories.js.coffee +14 -2
- data/vendor/assets/javascripts/spec/chai-backbone_spec.js.coffee +61 -18
- data/vendor/assets/javascripts/spec/factory_spec.js.coffee +24 -0
- metadata +19 -39
data/README.md
CHANGED
@@ -41,9 +41,27 @@ this can also be chained further:
|
|
41
41
|
|
42
42
|
### Changes
|
43
43
|
|
44
|
+
Changes by delta: 'change.by'
|
45
|
+
|
44
46
|
expect(-> view.$('p').length).to.change.by(4).when -> collection.add [{}, {}, {}, {}]
|
45
47
|
expect(-> result).to.not.change.when -> somethingElse()
|
46
48
|
|
49
|
+
Changes to end result: 'change.to'
|
50
|
+
|
51
|
+
result = ['a']
|
52
|
+
expect(-> result).to.change.to(['b']).when -> result = ['b']
|
53
|
+
|
54
|
+
Changes from begin result: 'change.from'
|
55
|
+
|
56
|
+
result = ['a']
|
57
|
+
expect(-> result).to.change.from(['a']).when -> result = ['b']
|
58
|
+
|
59
|
+
Mix and match:
|
60
|
+
|
61
|
+
result = 3
|
62
|
+
expect(-> result).to.change.from(3).to(5).by(2).when -> result = 5
|
63
|
+
|
64
|
+
|
47
65
|
Using Sinon Chai Matchers
|
48
66
|
-------------------------
|
49
67
|
|
@@ -72,6 +90,8 @@ other objects as you see fit:
|
|
72
90
|
|
73
91
|
Factory.create 'user', name: 'Matthijs'
|
74
92
|
|
93
|
+
### Traits
|
94
|
+
|
75
95
|
you can also use 'traits':
|
76
96
|
|
77
97
|
Factory.define 'user', (attributes = {}, traits...) ->
|
@@ -88,6 +108,28 @@ you can also use 'traits':
|
|
88
108
|
Factory.create 'male-user', name: 'Matthijs' # => new User name: 'Matthijs', gender: 'male'
|
89
109
|
Factory.create 'male-admin-user', name: 'Matthijs' # => new AdminUser name: 'Matthijs', gender: 'male'
|
90
110
|
|
111
|
+
### Sequences
|
112
|
+
|
113
|
+
Sequences are also supported:
|
114
|
+
|
115
|
+
Factory.define 'counter', ->
|
116
|
+
{
|
117
|
+
amount: @sequence('amount')
|
118
|
+
other: @sequence('other')
|
119
|
+
}
|
120
|
+
|
121
|
+
This does not conflict with similar names in other factory definitions.
|
122
|
+
|
123
|
+
You can also yield results:
|
124
|
+
|
125
|
+
Factory.define 'abc', ->
|
126
|
+
@sequence (i) -> ['a','b','c'][i]
|
127
|
+
|
128
|
+
# results in:
|
129
|
+
Factory.create('abc') => 'a'
|
130
|
+
Factory.create('abc') => 'b'
|
131
|
+
|
132
|
+
|
91
133
|
Contributing
|
92
134
|
------------
|
93
135
|
|
@@ -115,55 +115,166 @@
|
|
115
115
|
|
116
116
|
chai.Assertion.addChainableMethod 'to', routeTo, -> this
|
117
117
|
|
118
|
+
|
119
|
+
###
|
120
|
+
#
|
121
|
+
# Changes Matchers
|
122
|
+
#
|
123
|
+
###
|
124
|
+
|
125
|
+
noChangeAssert = (context) ->
|
126
|
+
relevant = flag(context, 'no-change')
|
127
|
+
return unless relevant
|
128
|
+
|
129
|
+
negate = flag(context, 'negate')
|
130
|
+
flag(context, 'negate', @negate)
|
131
|
+
object = flag(context, 'object')
|
132
|
+
|
133
|
+
startValue = flag(context, 'changeStart')
|
134
|
+
endValue = object()
|
135
|
+
actualDelta = endValue - startValue
|
136
|
+
|
137
|
+
result = (0 is actualDelta)
|
138
|
+
result = !result if negate
|
139
|
+
context.assert result,
|
140
|
+
"not supported"
|
141
|
+
"expected `#{formatFunction object}` not to change, but it changed by #{actualDelta}",
|
142
|
+
flag(context, 'negate', negate)
|
143
|
+
|
144
|
+
changeByAssert = (context) ->
|
145
|
+
negate = flag(context, 'negate')
|
146
|
+
flag(context, 'negate', @negate)
|
147
|
+
object = flag(context, 'object')
|
148
|
+
|
149
|
+
startValue = flag(context, 'changeStart')
|
150
|
+
endValue = object()
|
151
|
+
actualDelta = endValue - startValue
|
152
|
+
|
153
|
+
result = (@expectedDelta is actualDelta)
|
154
|
+
result = !result if negate
|
155
|
+
context.assert result,
|
156
|
+
"expected `#{formatFunction object}` to change by #{@expectedDelta}, but it changed by #{actualDelta}",
|
157
|
+
"not supported"
|
158
|
+
flag(context, 'negate', negate)
|
159
|
+
|
160
|
+
changeToBeginAssert = (context) ->
|
161
|
+
negate = flag(context, 'negate')
|
162
|
+
flag(context, 'negate', @negate)
|
163
|
+
object = flag(context, 'object')
|
164
|
+
|
165
|
+
startValue = object()
|
166
|
+
|
167
|
+
result = !utils.eql(startValue, @expectedEndValue)
|
168
|
+
result = !result if negate
|
169
|
+
context.assert result,
|
170
|
+
"expected `#{formatFunction object}` to change to #{utils.inspect @expectedEndValue}, but it was already #{utils.inspect startValue}",
|
171
|
+
"not supported"
|
172
|
+
flag(context, 'negate', negate)
|
173
|
+
|
174
|
+
changeToAssert = (context) ->
|
175
|
+
negate = flag(context, 'negate')
|
176
|
+
flag(context, 'negate', @negate)
|
177
|
+
object = flag(context, 'object')
|
178
|
+
|
179
|
+
endValue = object()
|
180
|
+
|
181
|
+
result = utils.eql(endValue, @expectedEndValue)
|
182
|
+
result = !result if negate
|
183
|
+
context.assert result,
|
184
|
+
"expected `#{formatFunction object}` to change to #{utils.inspect @expectedEndValue}, but it changed to #{utils.inspect endValue}",
|
185
|
+
"not supported"
|
186
|
+
flag(context, 'negate', negate)
|
187
|
+
|
188
|
+
changeFromBeginAssert = (context) ->
|
189
|
+
negate = flag(context, 'negate')
|
190
|
+
flag(context, 'negate', @negate)
|
191
|
+
object = flag(context, 'object')
|
192
|
+
|
193
|
+
startValue = object()
|
194
|
+
|
195
|
+
result = utils.eql(startValue, @expectedStartValue)
|
196
|
+
result = !result if negate
|
197
|
+
context.assert result,
|
198
|
+
"expected `#{formatFunction object}` to change from #{utils.inspect @expectedStartValue}, but it changed from #{utils.inspect startValue}",
|
199
|
+
"not supported"
|
200
|
+
flag(context, 'negate', negate)
|
201
|
+
|
202
|
+
changeFromAssert = (context) ->
|
203
|
+
negate = flag(context, 'negate')
|
204
|
+
flag(context, 'negate', @negate)
|
205
|
+
object = flag(context, 'object')
|
206
|
+
|
207
|
+
startValue = flag(context, 'changeStart')
|
208
|
+
endValue = object()
|
209
|
+
|
210
|
+
result = !utils.eql(startValue, endValue)
|
211
|
+
result = !result if negate
|
212
|
+
context.assert result,
|
213
|
+
"expected `#{formatFunction object}` to change from #{utils.inspect @expectedStartValue}, but it did not change"
|
214
|
+
"not supported"
|
215
|
+
flag(context, 'negate', negate)
|
216
|
+
|
118
217
|
# Verifies if the subject return value changes by given delta 'when' events happen
|
119
218
|
#
|
120
219
|
# Examples:
|
121
220
|
# (-> resultValue).should.change.by(1).when -> resultValue += 1
|
122
221
|
#
|
123
222
|
chai.Assertion.addProperty 'change', ->
|
124
|
-
flag(this, 'change', true)
|
223
|
+
flag(this, 'no-change', true)
|
125
224
|
|
126
225
|
definedActions = flag(this, 'whenActions') || []
|
127
|
-
|
128
226
|
# Add a around filter to the when actions
|
129
227
|
definedActions.push
|
130
228
|
negate: flag(this, 'negate')
|
131
229
|
|
132
230
|
# set up the callback to trigger
|
133
231
|
before: (context) ->
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
# verify if our callback is triggered
|
139
|
-
after: (context) ->
|
140
|
-
negate = flag(context, 'negate')
|
141
|
-
flag(context, 'negate', @negate)
|
142
|
-
object = flag(context, 'object')
|
143
|
-
@endValue = object()
|
144
|
-
actualChange = @endValue - @startValue
|
145
|
-
|
146
|
-
result = (@expectedChange is actualChange)
|
147
|
-
result = !result if negate
|
148
|
-
context.assert result,
|
149
|
-
"expected `#{formatFunction object}` to change by #{@expectedChange} but it changed by #{actualChange}",
|
150
|
-
"expected `#{formatFunction object}` not to change, but it changed by #{actualChange}",
|
232
|
+
startValue = flag(context, 'object')()
|
233
|
+
flag(context, 'changeStart', startValue)
|
234
|
+
after: noChangeAssert
|
151
235
|
|
152
|
-
flag(context, 'negate', negate)
|
153
236
|
flag(this, 'whenActions', definedActions)
|
154
237
|
|
155
238
|
formatFunction = (func) ->
|
156
239
|
func.toString().replace(/^\s*function \(\) {\s*/, '').replace(/\s+}$/, '').replace(/\s*return\s*/, '')
|
157
240
|
|
158
241
|
changeBy = (delta) ->
|
242
|
+
flag(this, 'no-change', false)
|
159
243
|
definedActions = flag(this, 'whenActions') || []
|
160
|
-
|
161
|
-
|
162
|
-
|
244
|
+
# Add a around filter to the when actions
|
245
|
+
definedActions.push
|
246
|
+
negate: flag(this, 'negate')
|
247
|
+
expectedDelta: delta
|
248
|
+
after: changeByAssert
|
163
249
|
flag(this, 'whenActions', definedActions)
|
164
250
|
|
165
251
|
chai.Assertion.addChainableMethod 'by', changeBy, -> this
|
166
252
|
|
167
|
-
)
|
253
|
+
changeTo = (endValue) ->
|
254
|
+
flag(this, 'no-change', false)
|
255
|
+
definedActions = flag(this, 'whenActions') || []
|
256
|
+
# Add a around filter to the when actions
|
257
|
+
definedActions.push
|
258
|
+
negate: flag(this, 'negate')
|
259
|
+
expectedEndValue: endValue
|
260
|
+
before: changeToBeginAssert
|
261
|
+
after: changeToAssert
|
262
|
+
flag(this, 'whenActions', definedActions)
|
168
263
|
|
264
|
+
chai.Assertion.addChainableMethod 'to', changeTo, -> this
|
265
|
+
|
266
|
+
changeFrom = (startValue) ->
|
267
|
+
flag(this, 'no-change', false)
|
268
|
+
definedActions = flag(this, 'whenActions') || []
|
269
|
+
# Add a around filter to the when actions
|
270
|
+
definedActions.push
|
271
|
+
negate: flag(this, 'negate')
|
272
|
+
expectedStartValue: startValue
|
273
|
+
before: changeFromBeginAssert
|
274
|
+
after: changeFromAssert
|
275
|
+
flag(this, 'whenActions', definedActions)
|
276
|
+
|
277
|
+
chai.Assertion.addChainableMethod 'from', changeFrom, -> this
|
278
|
+
|
279
|
+
)
|
169
280
|
|
@@ -1,3 +1,12 @@
|
|
1
|
+
sequencer = (property) ->
|
2
|
+
value = if @sequences[property]?
|
3
|
+
@sequences[property] += 1
|
4
|
+
else
|
5
|
+
@sequences[property] = 0
|
6
|
+
if typeof(property) is 'function'
|
7
|
+
property(value)
|
8
|
+
else
|
9
|
+
value
|
1
10
|
|
2
11
|
window.Factory =
|
3
12
|
factories: {}
|
@@ -7,14 +16,17 @@ window.Factory =
|
|
7
16
|
throw "Factory name '#{factoryName}' can't use - in name. It clashes with the traits construct"
|
8
17
|
if @factories[factoryName]?
|
9
18
|
throw "Factory #{factoryName} is already defined"
|
10
|
-
@factories[factoryName] =
|
19
|
+
@factories[factoryName] =
|
20
|
+
sequences: {}
|
21
|
+
factory: builder
|
22
|
+
sequence: sequencer
|
11
23
|
|
12
24
|
create: (nameWithTraits, options) ->
|
13
25
|
traits = nameWithTraits.split '-'
|
14
26
|
factoryName = traits.pop()
|
15
27
|
unless @factories[factoryName]?
|
16
28
|
throw "Factory #{factoryName} does not exist"
|
17
|
-
@factories[factoryName] options, traits...
|
29
|
+
@factories[factoryName].factory options, traits...
|
18
30
|
|
19
31
|
resetFactories: ->
|
20
32
|
@factories = []
|
@@ -44,21 +44,64 @@ describe 'Chai-Backbone', ->
|
|
44
44
|
|
45
45
|
describe 'change', ->
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
47
|
+
describe 'by delta', ->
|
48
|
+
|
49
|
+
it 'asserts the delta of a change', ->
|
50
|
+
result = 1
|
51
|
+
expect(-> result).to.change.by(3).when -> result += 3
|
52
|
+
|
53
|
+
it 'reports the contents of the subject method', ->
|
54
|
+
result = 1
|
55
|
+
expect(->
|
56
|
+
(-> 1 + 3; result).should.change.by(3).when -> result += 2
|
57
|
+
).to.throw 'expected `1 + 3;result;` to change by 3, but it changed by 2'
|
58
|
+
|
59
|
+
it 'can be negated to not.change', ->
|
60
|
+
result = 1
|
61
|
+
expect(->
|
62
|
+
expect(-> result).to.not.change.when -> result += 2
|
63
|
+
).to.throw 'expected `result;` not to change, but it changed by 2'
|
64
|
+
expect(-> result).to.not.change.when -> 1 + 3
|
65
|
+
|
66
|
+
describe 'to', ->
|
67
|
+
|
68
|
+
it 'asserts end values', ->
|
69
|
+
result = ['a']
|
70
|
+
expect(-> result).to.change.to(['b']).when -> result = ['b']
|
71
|
+
|
72
|
+
it 'reports the mismatched end value', ->
|
73
|
+
result = ['a']
|
74
|
+
expect(->
|
75
|
+
expect(-> result).to.change.to(['b']).when -> result = ['c']
|
76
|
+
).to.throw 'expected `result;` to change to [ \'b\' ], but it changed to [ \'c\' ]'
|
77
|
+
|
78
|
+
it 'raises an error if there was no change', ->
|
79
|
+
result = 'b'
|
80
|
+
expect(->
|
81
|
+
expect(-> result).to.change.to('b').when -> result = 'b'
|
82
|
+
).to.throw 'expected `result;` to change to \'b\', but it was already \'b\''
|
83
|
+
|
84
|
+
describe 'from', ->
|
85
|
+
|
86
|
+
it 'asserts start values', ->
|
87
|
+
result = ['a']
|
88
|
+
expect(-> result).to.change.from(['a']).when -> result = ['b']
|
89
|
+
|
90
|
+
it 'reports the mismatched start value', ->
|
91
|
+
result = ['a']
|
92
|
+
expect(->
|
93
|
+
expect(-> result).to.change.from(['b']).when -> result = ['c']
|
94
|
+
).to.throw 'expected `result;` to change from [ \'b\' ], but it changed from [ \'a\' ]'
|
95
|
+
|
96
|
+
it 'raises an error if there was no change', ->
|
97
|
+
result = 'b'
|
98
|
+
expect(->
|
99
|
+
expect(-> result).to.change.from('b').when -> result = 'b'
|
100
|
+
).to.throw 'expected `result;` to change from \'b\', but it did not change'
|
101
|
+
|
102
|
+
|
103
|
+
describe 'mix and match', ->
|
104
|
+
|
105
|
+
it 'can use from to and by in one sentence', ->
|
106
|
+
result = 3
|
107
|
+
expect(-> result).to.change.from(3).to(5).by(2).when -> result = 5
|
@@ -32,3 +32,27 @@ describe 'Factory', ->
|
|
32
32
|
result = Factory.create 'male-admin-user'
|
33
33
|
result[1].should.deep.equal ['male', 'admin']
|
34
34
|
|
35
|
+
|
36
|
+
describe 'helpers', ->
|
37
|
+
|
38
|
+
describe 'sequence', ->
|
39
|
+
|
40
|
+
beforeEach ->
|
41
|
+
Factory.define 'counter', (options = {}, traits...) ->
|
42
|
+
@sequence('property')
|
43
|
+
|
44
|
+
Factory.define 'otherCounter', (options = {}, traits...) ->
|
45
|
+
@sequence('property')
|
46
|
+
|
47
|
+
Factory.define 'abc', (options = {}, traits...) ->
|
48
|
+
@sequence((c) -> ['a', 'b', 'c'][c])
|
49
|
+
|
50
|
+
it 'provides sequencers scoped to factory and property', ->
|
51
|
+
Factory.create('counter').should.equal 0
|
52
|
+
Factory.create('otherCounter').should.equal 0
|
53
|
+
Factory.create('counter').should.equal 1
|
54
|
+
|
55
|
+
it 'can yield results', ->
|
56
|
+
Factory.create('abc').should.equal 'a'
|
57
|
+
Factory.create('abc').should.equal 'b'
|
58
|
+
|
metadata
CHANGED
@@ -1,33 +1,23 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: chai-backbone-rails
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 3
|
10
|
-
version: 0.1.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Matthijs Groen
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2012-09-26 00:00:00 Z
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
14
|
description: Chai.js matchers for Backbone.js framework
|
22
|
-
email:
|
15
|
+
email:
|
23
16
|
- matthijs.groen@gmail.com
|
24
17
|
executables: []
|
25
|
-
|
26
18
|
extensions: []
|
27
|
-
|
28
19
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
files:
|
20
|
+
files:
|
31
21
|
- .gitignore
|
32
22
|
- Gemfile
|
33
23
|
- LICENSE
|
@@ -46,36 +36,26 @@ files:
|
|
46
36
|
- vendor/assets/javascripts/spec/factory_spec.js.coffee
|
47
37
|
homepage: https://github.com/matthijsgroen/chai-backbone-rails
|
48
38
|
licenses: []
|
49
|
-
|
50
39
|
post_install_message:
|
51
40
|
rdoc_options: []
|
52
|
-
|
53
|
-
require_paths:
|
41
|
+
require_paths:
|
54
42
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
44
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
- 0
|
63
|
-
version: "0"
|
64
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
50
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
segments:
|
71
|
-
- 0
|
72
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
73
55
|
requirements: []
|
74
|
-
|
75
56
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.8.
|
57
|
+
rubygems_version: 1.8.24
|
77
58
|
signing_key:
|
78
59
|
specification_version: 3
|
79
60
|
summary: A set of assertion matchers to test Backbone code using Konacha in Rails
|
80
61
|
test_files: []
|
81
|
-
|