hamcrest4qunit 1.3.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/.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
|
+
|