hamcrest4qunit 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +38 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/hamcrest4qunit/description.js.coffee +23 -0
- data/app/assets/javascripts/hamcrest4qunit/h4q.js.coffee +158 -0
- data/app/assets/javascripts/hamcrest4qunit/index.js.coffee +7 -0
- data/app/assets/javascripts/hamcrest4qunit/matcher.js.coffee +31 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/arrays.js.coffee +221 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/compounds.js.coffee +134 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/core.js.coffee +126 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/dates.js.coffee +166 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/dom.js.coffee +73 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/functions.js.coffee +142 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/index.js.coffee +1 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/numbers.js.coffee +177 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/objects.js.coffee +249 -0
- data/app/assets/javascripts/hamcrest4qunit/matchers/strings.js.coffee +123 -0
- data/app/assets/javascripts/hamcrest4qunit/test/index.js +920 -0
- data/hamcrest4qunit.gemspec +20 -0
- data/lib/hamcrest4qunit.rb +11 -0
- data/lib/hamcrest4qunit/engine.rb +9 -0
- data/lib/hamcrest4qunit/version.rb +3 -0
- metadata +122 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
h4q.allOf = ->
|
2
|
+
args = h4q.argumentsToArray arguments
|
3
|
+
matchers = []
|
4
|
+
for m in args
|
5
|
+
if m instanceof Matcher
|
6
|
+
matchers.push m
|
7
|
+
else
|
8
|
+
matchers.push equalTo m
|
9
|
+
|
10
|
+
new Matcher
|
11
|
+
matchers: matchers
|
12
|
+
_matches: (v, msg) ->
|
13
|
+
msg.appendText("was").appendValue v
|
14
|
+
|
15
|
+
hasError = false
|
16
|
+
for m in @matchers
|
17
|
+
msgtmp = new Description()
|
18
|
+
res = m.matches v, msgtmp
|
19
|
+
unless res
|
20
|
+
hasError = true
|
21
|
+
|
22
|
+
not hasError
|
23
|
+
|
24
|
+
_describeTo: (msg) ->
|
25
|
+
l = @matchers.length
|
26
|
+
msg.appendText '('
|
27
|
+
@matchers.map (o, i) ->
|
28
|
+
msgtmp = new Description()
|
29
|
+
if i is l-1
|
30
|
+
msg.appendText "and"
|
31
|
+
else if i > 0
|
32
|
+
msg.appendText ","
|
33
|
+
|
34
|
+
o.describeTo msg
|
35
|
+
|
36
|
+
msg.appendText ')'
|
37
|
+
|
38
|
+
h4q.anyOf = ->
|
39
|
+
args = h4q.argumentsToArray arguments
|
40
|
+
matchers = []
|
41
|
+
for m in args
|
42
|
+
if m instanceof Matcher
|
43
|
+
matchers.push m
|
44
|
+
else
|
45
|
+
matchers.push equalTo m
|
46
|
+
|
47
|
+
new Matcher
|
48
|
+
matchers: matchers
|
49
|
+
_matches: (v, msg) ->
|
50
|
+
msg.appendText("was ").appendValue v
|
51
|
+
hasMatches = false
|
52
|
+
hasError = false
|
53
|
+
for m in @matchers
|
54
|
+
msgtmp = new Description()
|
55
|
+
res = m.matches v, msgtmp
|
56
|
+
if res
|
57
|
+
hasMatches = true
|
58
|
+
|
59
|
+
hasMatches
|
60
|
+
|
61
|
+
_describeTo: (msg) ->
|
62
|
+
msg.appendText '('
|
63
|
+
l = @matchers.length
|
64
|
+
@matchers.map (o,i) ->
|
65
|
+
if i is l - 1
|
66
|
+
msg.appendText "or"
|
67
|
+
else if i > 0
|
68
|
+
msg.appendText ","
|
69
|
+
|
70
|
+
o.describeTo msg
|
71
|
+
|
72
|
+
msg.appendText ')'
|
73
|
+
|
74
|
+
h4q.both = (m) ->
|
75
|
+
new Matcher
|
76
|
+
matchA: if m instanceof Matcher then m else equalTo m
|
77
|
+
and: (m) ->
|
78
|
+
this.matchB = if m instanceof Matcher then m else equalTo m
|
79
|
+
this
|
80
|
+
|
81
|
+
_matches: (v,msg) ->
|
82
|
+
unless @matchB?
|
83
|
+
throw new Error
|
84
|
+
message: "the both..and matcher require an 'and' assertion"
|
85
|
+
|
86
|
+
msgtmp1 = new Description()
|
87
|
+
msgtmp2 = new Description();
|
88
|
+
|
89
|
+
res1 = @matchA.matches v, msgtmp1
|
90
|
+
res2 = @matchB.matches v, msgtmp2
|
91
|
+
|
92
|
+
if res1 and res2
|
93
|
+
msg.appendText("was").appendValue v
|
94
|
+
else
|
95
|
+
msg.appendText msgtmp1 unless res1
|
96
|
+
|
97
|
+
|
98
|
+
msg.appendText "and" unless res1 or res2
|
99
|
+
|
100
|
+
msg.appendText msgtmp2 unless res2
|
101
|
+
|
102
|
+
res1 and res2
|
103
|
+
|
104
|
+
_describeTo: (msg) ->
|
105
|
+
unless @matchB?
|
106
|
+
throw new hasError
|
107
|
+
message: "the both..and matcher require an 'and' assertion"
|
108
|
+
|
109
|
+
msg.appendText("both").appendDescriptionOf(@matchA)
|
110
|
+
.appendText("and").appendDescriptionOf(@matchB)
|
111
|
+
|
112
|
+
h4q.either = (m) ->
|
113
|
+
new Matcher
|
114
|
+
matchA: if m instanceof Matcher then m else equalTo m
|
115
|
+
or: (m) ->
|
116
|
+
@matchB = if m instanceof Matcher then m else equalTo m
|
117
|
+
this
|
118
|
+
|
119
|
+
_matches: (v, msg) ->
|
120
|
+
msg.appendText("was").appendValue v
|
121
|
+
unless @matchB?
|
122
|
+
throw new Error
|
123
|
+
message: "the either..or matcher require an 'or' assertion"
|
124
|
+
|
125
|
+
msgtmp = new Description()
|
126
|
+
@matchA.matches(v, msgtmp) or @matchB.matches(v, msgtmp)
|
127
|
+
|
128
|
+
_describeTo: (msg) ->
|
129
|
+
unless @matchB?
|
130
|
+
throw new Error
|
131
|
+
message: "the either..or matcher require an 'or' assertion"
|
132
|
+
|
133
|
+
msg.appendText("either").appendDescriptionOf(@matchA)
|
134
|
+
.appendText("or").appendDescriptionOf(@matchB)
|
@@ -0,0 +1,126 @@
|
|
1
|
+
h4q.equalTo = (m) ->
|
2
|
+
new Matcher
|
3
|
+
value: m
|
4
|
+
_describeTo: (msg) -> msg.appendValue @value
|
5
|
+
_matches: (v, msg) ->
|
6
|
+
msg.appendText("was").appendValue v
|
7
|
+
if v instanceof Array and @value instanceof Array
|
8
|
+
l = v.length
|
9
|
+
if @value.length isnt l
|
10
|
+
msg.appendText("with a length of").appendValue l
|
11
|
+
return false
|
12
|
+
else
|
13
|
+
hasError = false
|
14
|
+
|
15
|
+
for i in [0..l-1]
|
16
|
+
if `v[i] != this.value[i]`
|
17
|
+
msg.appendText "and" if hasError
|
18
|
+
|
19
|
+
msg.appendText ("with")
|
20
|
+
.appendValue(v[i])
|
21
|
+
.appendText ("at index")
|
22
|
+
.appendValue(i)
|
23
|
+
.appendText ("instead of")
|
24
|
+
.appendValue(@value[i])
|
25
|
+
hasError = true
|
26
|
+
|
27
|
+
if hasError
|
28
|
+
msg.diff = QUnit.diff QUnit.jsDump.parse(@value),
|
29
|
+
QUnit.jsDump.parse(v)
|
30
|
+
|
31
|
+
return not hasError
|
32
|
+
|
33
|
+
return true if `v == this.value`
|
34
|
+
|
35
|
+
msg.diff = QUnit.diff QUnit.jsDump.parse(@value), QUnit.jsDump.parse(v)
|
36
|
+
return false
|
37
|
+
|
38
|
+
h4q.strictlyEqualTo = (m) ->
|
39
|
+
new Matcher
|
40
|
+
value: m,
|
41
|
+
_matches: (v, msg) ->
|
42
|
+
msg.appendText("was ").appendValue v
|
43
|
+
|
44
|
+
return true if v is @value
|
45
|
+
|
46
|
+
msg.diff = QUnit.diff QUnit.jsDump.parse(m),
|
47
|
+
QUnit.jsDump.parse(v)
|
48
|
+
return false
|
49
|
+
|
50
|
+
_describeTo: (msg) ->
|
51
|
+
msg.appendText("a value strictly equal to").appendValue @value
|
52
|
+
|
53
|
+
h4q.not = (m) ->
|
54
|
+
new Matcher
|
55
|
+
submatch: m
|
56
|
+
_matches: (v, msg) ->
|
57
|
+
if @submatch instanceof Matcher
|
58
|
+
not @submatch.matches v, msg
|
59
|
+
else
|
60
|
+
msg.appendText("was").appendValue v
|
61
|
+
v isnt @submatch
|
62
|
+
|
63
|
+
_describeTo: (msg) ->
|
64
|
+
if @submatch instanceof Matcher
|
65
|
+
msg.appendText "not"
|
66
|
+
@submatch.describeTo msg
|
67
|
+
else
|
68
|
+
msg.appendText("not").appendValue @submatch
|
69
|
+
|
70
|
+
h4q.nullValue = ->
|
71
|
+
new Matcher
|
72
|
+
_matches: (v, msg) ->
|
73
|
+
msg.appendText("was").appendValue v
|
74
|
+
not v?
|
75
|
+
|
76
|
+
_describeTo: (msg) ->
|
77
|
+
msg.appendValue null
|
78
|
+
|
79
|
+
h4q.notNullValue = ->
|
80
|
+
new Matcher
|
81
|
+
_matches: (v, msg) ->
|
82
|
+
msg.appendText("was").appendValue v
|
83
|
+
v?
|
84
|
+
_describeTo: (msg) ->
|
85
|
+
msg.appendText("not").appendValue null
|
86
|
+
|
87
|
+
h4q.anything = ->
|
88
|
+
new Matcher
|
89
|
+
_matches: (v, msg) ->
|
90
|
+
msg.appendText("was").appendValue v
|
91
|
+
true
|
92
|
+
|
93
|
+
_describeTo: (msg) ->
|
94
|
+
msg.clearMessage().appendText "anything"
|
95
|
+
|
96
|
+
h4q.isA = (type) ->
|
97
|
+
new Matcher
|
98
|
+
type:type
|
99
|
+
_matches: (v, msg) ->
|
100
|
+
msg.appendText("was").appendValue v
|
101
|
+
typeof v is @type
|
102
|
+
_describeTo: (msg) ->
|
103
|
+
msg.appendText(aPrefix @type).appendRawValue @type
|
104
|
+
|
105
|
+
h4q.describedAs = (m, t) ->
|
106
|
+
unless m? and m instanceof Matcher
|
107
|
+
throw new Error message: "describedAs first argument must
|
108
|
+
be a valid Matcher instance"
|
109
|
+
|
110
|
+
unless t? and typeof t is "string"
|
111
|
+
throw new Error message: "describedAs second argument must
|
112
|
+
be a valid string"
|
113
|
+
|
114
|
+
extraArgs = h4q.argumentsToArray arguments
|
115
|
+
extraArgs.shift()
|
116
|
+
extraArgs.shift()
|
117
|
+
|
118
|
+
new Matcher
|
119
|
+
description: t
|
120
|
+
matcher: m
|
121
|
+
extraArgs: extraArgs
|
122
|
+
_matches: (v,msg) ->
|
123
|
+
@matcher.matches v, msg
|
124
|
+
_describeTo: (msg) ->
|
125
|
+
msg.appendText h4q.tokenReplace.apply null,
|
126
|
+
[@description].concat extraArgs
|
@@ -0,0 +1,166 @@
|
|
1
|
+
h4q.dateAfterOrEqualTo = (d) -> h4q.dateAfter d, true
|
2
|
+
h4q.dateAfter = (d, inclusive) ->
|
3
|
+
unless d? and d instanceof Date
|
4
|
+
throw new Error message: "dateAfter must have a valid comparison date"
|
5
|
+
|
6
|
+
new Matcher
|
7
|
+
date: d
|
8
|
+
included: inclusive
|
9
|
+
inclusive: ->
|
10
|
+
@included = true
|
11
|
+
this
|
12
|
+
|
13
|
+
_matches: (v,msg) ->
|
14
|
+
unless v? and v instanceof Date
|
15
|
+
msg.appendText("was").appendValue( v )
|
16
|
+
false
|
17
|
+
else
|
18
|
+
if @included
|
19
|
+
if v >= @date
|
20
|
+
msg.appendText("was").appendRawValue v.toString()
|
21
|
+
true
|
22
|
+
else
|
23
|
+
msg.appendRawValue(v.toString())
|
24
|
+
.appendText("is not after or equal to")
|
25
|
+
.appendRawValue(@date.toString())
|
26
|
+
false
|
27
|
+
else
|
28
|
+
if v > @date
|
29
|
+
msg.appendText("was").appendRawValue(v.toString())
|
30
|
+
true
|
31
|
+
else
|
32
|
+
msg.appendRawValue(v.toString())
|
33
|
+
.appendText("is not after")
|
34
|
+
.appendRawValue(@date.toString())
|
35
|
+
false
|
36
|
+
|
37
|
+
_describeTo: (msg) ->
|
38
|
+
if @included
|
39
|
+
msg.appendText("a date after or equal to")
|
40
|
+
.appendRawValue(@date.toString())
|
41
|
+
else
|
42
|
+
msg.appendText("a date after").appendRawValue(@date.toString())
|
43
|
+
|
44
|
+
h4q.dateBeforeOrEqualTo = (d) -> h4q.dateBefore d, true
|
45
|
+
h4q.dateBefore = (d,inclusive) ->
|
46
|
+
unless d? and d instanceof Date
|
47
|
+
throw new Error message: "dateBefore must have a valid comparison date"
|
48
|
+
|
49
|
+
new Matcher
|
50
|
+
date: d
|
51
|
+
included: inclusive
|
52
|
+
inclusive: ->
|
53
|
+
@included = true
|
54
|
+
this
|
55
|
+
_matches: (v,msg) ->
|
56
|
+
unless v? and v instanceof Date
|
57
|
+
msg.appendText("was").appendValue(v)
|
58
|
+
false
|
59
|
+
else
|
60
|
+
|
61
|
+
if @included
|
62
|
+
if v <= @date
|
63
|
+
msg.appendText("was").appendRawValue(v.toString())
|
64
|
+
true
|
65
|
+
else
|
66
|
+
msg.appendRawValue(v.toString())
|
67
|
+
.appendText("is not before or equal to")
|
68
|
+
.appendRawValue(@date.toString())
|
69
|
+
false
|
70
|
+
else
|
71
|
+
if v < @date
|
72
|
+
msg.appendText("was").appendRawValue(v.toString())
|
73
|
+
true
|
74
|
+
else
|
75
|
+
msg.appendRawValue(v.toString())
|
76
|
+
.appendText("is not before")
|
77
|
+
.appendRawValue(@date.toString())
|
78
|
+
false
|
79
|
+
|
80
|
+
_describeTo: (msg) ->
|
81
|
+
if @included
|
82
|
+
msg.appendText("a date before or equal to")
|
83
|
+
.appendRawValue(@date.toString())
|
84
|
+
else
|
85
|
+
msg.appendText("a date before").appendRawValue(@date.toString())
|
86
|
+
|
87
|
+
h4q.dateBetween = (a,b,inclusive) ->
|
88
|
+
|
89
|
+
unless a? and a instanceof Date
|
90
|
+
throw new Error message: "dateBetween must have a valid first date"
|
91
|
+
|
92
|
+
unless b? and b instanceof Date
|
93
|
+
throw new Error message: "dateBetween must have a valid first date"
|
94
|
+
|
95
|
+
if b <= a
|
96
|
+
throw new Error
|
97
|
+
message: "dateBetween second date must be after the first date"
|
98
|
+
|
99
|
+
new Matcher
|
100
|
+
a: a
|
101
|
+
b: b
|
102
|
+
included: inclusive
|
103
|
+
inclusive: ->
|
104
|
+
@included = true
|
105
|
+
this
|
106
|
+
|
107
|
+
_matches: (v, msg) ->
|
108
|
+
unless v? and v instanceof Date
|
109
|
+
msg.appendText("was").appendValue(v)
|
110
|
+
false
|
111
|
+
else
|
112
|
+
if @included
|
113
|
+
if v < @a
|
114
|
+
msg.appendRawValue(v.toString())
|
115
|
+
.appendText("is before the min date")
|
116
|
+
.appendRawValue(@a.toString())
|
117
|
+
false
|
118
|
+
else if( v > @b )
|
119
|
+
msg.appendRawValue(v.toString())
|
120
|
+
.appendText("is after the max date")
|
121
|
+
.appendRawValue(@b.toString())
|
122
|
+
false
|
123
|
+
else
|
124
|
+
msg.appendText("was").appendRawValue(v.toString())
|
125
|
+
true
|
126
|
+
else
|
127
|
+
if v <= @a
|
128
|
+
msg.appendRawValue(v.toString())
|
129
|
+
.appendText("is before or equal to the min date")
|
130
|
+
.appendRawValue(@a.toString())
|
131
|
+
false
|
132
|
+
else if v >= @b
|
133
|
+
msg.appendRawValue(v.toString())
|
134
|
+
.appendText("is after or equal to the max date")
|
135
|
+
.appendRawValue(@b.toString())
|
136
|
+
false
|
137
|
+
else
|
138
|
+
msg.appendText("was").appendRawValue(v.toString())
|
139
|
+
true
|
140
|
+
|
141
|
+
_describeTo: (msg) ->
|
142
|
+
msg.appendText("a date between")
|
143
|
+
.appendRawValue(@a.toString())
|
144
|
+
.appendText("and")
|
145
|
+
.appendRawValue(@b.toString())
|
146
|
+
if @included
|
147
|
+
msg.appendText("inclusive")
|
148
|
+
|
149
|
+
h4q.dateEquals = (d) ->
|
150
|
+
unless d? and d instanceof Date
|
151
|
+
throw new Error
|
152
|
+
message: "dateEquals expect a valid Date object as argument"
|
153
|
+
|
154
|
+
new Matcher
|
155
|
+
date: d
|
156
|
+
_matches: (v,msg) ->
|
157
|
+
unless v? and v instanceof Date
|
158
|
+
msg.appendText("was").appendValue(v)
|
159
|
+
false
|
160
|
+
else
|
161
|
+
msg.appendText("was").appendRawValue(v.toString())
|
162
|
+
v.getTime() is @date.getTime()
|
163
|
+
|
164
|
+
_describeTo: (msg) ->
|
165
|
+
msg.appendText("a Date equal to").appendRawValue(@date.toString())
|
166
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
h4q.equalToNode = (node) ->
|
2
|
+
unless node?
|
3
|
+
throw new Error message: "equalToNode expect an argument"
|
4
|
+
else unless node instanceof Node
|
5
|
+
throw new Error message: "equalToNode except a Node object as argument"
|
6
|
+
|
7
|
+
new Matcher
|
8
|
+
node: node
|
9
|
+
_matches: (v,msg) ->
|
10
|
+
unless v? and v instanceof Node
|
11
|
+
msg.appendText("was").appendValue(v)
|
12
|
+
false
|
13
|
+
else
|
14
|
+
msg.appendText("was\n").appendRawValue(h4q.nodeToString v)
|
15
|
+
if v.isEqualNode(@node)
|
16
|
+
true
|
17
|
+
else
|
18
|
+
msg.diff = QUnit.diff nodeToString(@node), h4q.nodeToString(v)
|
19
|
+
false
|
20
|
+
|
21
|
+
_describeTo: (msg) ->
|
22
|
+
msg.appendText("a Node equal to\n")
|
23
|
+
.appendRawValue(nodeToString @node)
|
24
|
+
|
25
|
+
h4q.hasAttribute = (a, m) ->
|
26
|
+
|
27
|
+
unless a?
|
28
|
+
throw new Error message: "hasAttribute expect an attribute name"
|
29
|
+
else if typeof a isnt "string"
|
30
|
+
throw new Error message: "attribute name must be a string"
|
31
|
+
|
32
|
+
m = equalTo(m) if m? and not (m instanceof Matcher)
|
33
|
+
|
34
|
+
new Matcher
|
35
|
+
attribute: a
|
36
|
+
matcher: m
|
37
|
+
_matches: (v,msg) ->
|
38
|
+
unless v? and v instanceof Node
|
39
|
+
msg.appendText("was").appendValue(v)
|
40
|
+
false
|
41
|
+
else
|
42
|
+
if v.attributes[@attribute]?
|
43
|
+
if @matcher
|
44
|
+
av = v.attributes[@attribute].value
|
45
|
+
mismatchMsg = new Description()
|
46
|
+
if !@matcher.matches av, mismatchMsg
|
47
|
+
msg.appendText("attribute")
|
48
|
+
.appendRawValue(@attribute)
|
49
|
+
.appendText("value")
|
50
|
+
.appendText(mismatchMsg)
|
51
|
+
.appendText("in\n")
|
52
|
+
.appendRawValue(h4q.nodeToString v)
|
53
|
+
msg.diff = mismatchMsg.diff
|
54
|
+
false
|
55
|
+
else
|
56
|
+
msg.appendText("was\n").appendRawValue(h4q.nodeToString v)
|
57
|
+
true
|
58
|
+
else
|
59
|
+
msg.appendText("was\n").appendRawValue(h4q.nodeToString v)
|
60
|
+
true
|
61
|
+
else
|
62
|
+
msg.appendRawValue(h4q.nodeToString v)
|
63
|
+
.appendText("do not have an attribute")
|
64
|
+
.appendRawValue(@attribute)
|
65
|
+
false
|
66
|
+
|
67
|
+
_describeTo: (msg) ->
|
68
|
+
msg.appendText("a Node with an attribute")
|
69
|
+
.appendRawValue(@attribute)
|
70
|
+
|
71
|
+
if @matcher
|
72
|
+
msg.appendText("of which value is").appendDescriptionOf(@matcher)
|
73
|
+
|