wrong 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README.markdown +114 -25
  2. data/lib/predicated/Gemfile +15 -0
  3. data/lib/predicated/LICENSE +20 -0
  4. data/lib/predicated/README.markdown +191 -0
  5. data/lib/predicated/Rakefile +51 -0
  6. data/lib/predicated/lib/predicated.rb +4 -0
  7. data/lib/predicated/lib/predicated/autogen_call.rb +37 -0
  8. data/lib/predicated/lib/predicated/constrain.rb +66 -0
  9. data/lib/predicated/lib/predicated/evaluate.rb +94 -0
  10. data/lib/predicated/lib/predicated/from/callable_object.rb +108 -0
  11. data/lib/predicated/lib/predicated/from/json.rb +59 -0
  12. data/lib/predicated/lib/predicated/from/ruby_code_string.rb +73 -0
  13. data/lib/predicated/lib/predicated/from/url_part.rb +104 -0
  14. data/lib/predicated/lib/predicated/from/xml.rb +61 -0
  15. data/lib/predicated/lib/predicated/gem_check.rb +34 -0
  16. data/lib/predicated/lib/predicated/predicate.rb +111 -0
  17. data/lib/predicated/lib/predicated/print.rb +62 -0
  18. data/lib/predicated/lib/predicated/selectable.rb +102 -0
  19. data/lib/predicated/lib/predicated/simple_templated_predicate.rb +79 -0
  20. data/lib/predicated/lib/predicated/string_utils.rb +20 -0
  21. data/lib/predicated/lib/predicated/to/arel.rb +41 -0
  22. data/lib/predicated/lib/predicated/to/json.rb +48 -0
  23. data/lib/predicated/lib/predicated/to/sentence.rb +94 -0
  24. data/lib/predicated/lib/predicated/to/solr.rb +15 -0
  25. data/lib/predicated/lib/predicated/to/xml.rb +67 -0
  26. data/lib/predicated/lib/predicated/version.rb +3 -0
  27. data/lib/predicated/predicated.gemspec +22 -0
  28. data/lib/predicated/test/autogen_call_test.rb +40 -0
  29. data/lib/predicated/test/canonical_transform_cases.rb +63 -0
  30. data/lib/predicated/test/constrain_test.rb +86 -0
  31. data/lib/predicated/test/enumerable_test.rb +32 -0
  32. data/lib/predicated/test/equality_test.rb +32 -0
  33. data/lib/predicated/test/evaluate_test.rb +149 -0
  34. data/lib/predicated/test/from/callable_object_canonical_test.rb +43 -0
  35. data/lib/predicated/test/from/callable_object_test.rb +78 -0
  36. data/lib/predicated/test/from/json_test.rb +83 -0
  37. data/lib/predicated/test/from/ruby_code_string_canonical_test.rb +37 -0
  38. data/lib/predicated/test/from/ruby_code_string_test.rb +103 -0
  39. data/lib/predicated/test/from/url_part_parser_test.rb +123 -0
  40. data/lib/predicated/test/from/url_part_test.rb +48 -0
  41. data/lib/predicated/test/from/xml_test.rb +57 -0
  42. data/lib/predicated/test/json_conversion_test.rb +33 -0
  43. data/lib/predicated/test/print_test.rb +66 -0
  44. data/lib/predicated/test/selectable_test.rb +123 -0
  45. data/lib/predicated/test/simple_templated_predicate_test.rb +39 -0
  46. data/lib/predicated/test/suite.rb +2 -0
  47. data/lib/predicated/test/test_helper.rb +64 -0
  48. data/lib/predicated/test/test_helper_with_wrong.rb +6 -0
  49. data/lib/predicated/test/to/arel_test.rb +85 -0
  50. data/lib/predicated/test/to/json_test.rb +74 -0
  51. data/lib/predicated/test/to/sentence_test.rb +90 -0
  52. data/lib/predicated/test/to/solr_test.rb +39 -0
  53. data/lib/predicated/test/to/xml_test.rb +72 -0
  54. data/lib/predicated/test/xml_conversion_test.rb +34 -0
  55. data/lib/predicated/test_integration/arel_integration_test.rb +52 -0
  56. data/lib/predicated/test_integration/canonical_integration_cases.rb +66 -0
  57. data/lib/predicated/test_integration/schema.xml +83 -0
  58. data/lib/predicated/test_integration/solr_integration_test.rb +71 -0
  59. data/lib/predicated/test_integration/sqlite_db +0 -0
  60. data/lib/predicated/test_integration/suite.rb +2 -0
  61. data/lib/predicated/test_integration/usage_test.rb +252 -0
  62. data/lib/wrong.rb +3 -1
  63. data/lib/wrong/adapters/test_unit.rb +1 -3
  64. data/lib/wrong/assert.rb +81 -24
  65. data/lib/wrong/chunk.rb +145 -0
  66. data/lib/wrong/message/string_diff.rb +2 -4
  67. data/lib/wrong/message/test_context.rb +2 -2
  68. data/lib/wrong/version.rb +2 -2
  69. data/test/adapters/minitest_test.rb +16 -9
  70. data/test/adapters/test_unit_test.rb +1 -1
  71. data/test/assert_test.rb +90 -0
  72. data/test/catch_raise_test.rb +2 -2
  73. data/test/chunk_test.rb +236 -0
  74. data/test/failures_test.rb +109 -74
  75. data/test/message/array_diff_test.rb +35 -19
  76. data/test/message/string_diff_test.rb +39 -15
  77. data/test/message/test_context_text.rb +2 -2
  78. data/test/test_helper.rb +25 -7
  79. metadata +86 -33
  80. data/test/basic_assert_test.rb +0 -38
@@ -1,9 +1,9 @@
1
- require "test/test_helper"
1
+ require "./test/test_helper"
2
2
 
3
3
  require "wrong/assert"
4
4
  require "wrong/adapters/minitest"
5
5
 
6
- apropos "a tool for rescuing errors" do
6
+ regarding "a tool for rescuing errors" do
7
7
 
8
8
  class RedError < StandardError; end
9
9
  class BlueError < StandardError; end
@@ -0,0 +1,236 @@
1
+ require "./test/test_helper"
2
+ require "wrong/chunk"
3
+
4
+ unless Object.const_defined?(:Chunk)
5
+ Chunk = Wrong::Chunk
6
+ end
7
+
8
+ regarding Chunk do
9
+ regarding "#from_block" do
10
+ test "reads the source location" do
11
+ file, line = __FILE__, __LINE__
12
+ chunk = Chunk.from_block(proc { "hi" })
13
+ assert(chunk.file == file)
14
+ assert(chunk.line_number == line+1)
15
+ end
16
+ end
17
+
18
+ regarding "line numbers" do
19
+ before do
20
+ @chunk = Wrong::Chunk.new("foo.rb", 10)
21
+ end
22
+ test "#line_index is zero-based" do
23
+ assert(@chunk.line_index == 9)
24
+ end
25
+ test "#location is one-based" do
26
+ assert(@chunk.location == "foo.rb:10")
27
+ end
28
+ end
29
+
30
+ regarding "#parse" do
31
+ test "reads a statement on a line by itself" do
32
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
33
+ "hi"
34
+ CODE
35
+ code = chunk.parse.to_ruby
36
+ assert(code == '"hi"')
37
+ end
38
+
39
+ test "reads a statement on multiple lines" do
40
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
41
+ proc do
42
+ "hi"
43
+ end
44
+ CODE
45
+ code = chunk.parse.to_ruby
46
+ assert(code == "proc { \"hi\" }")
47
+ end
48
+
49
+ test "fails if there's a stray close-paren symbol on the last line (sorry)" do
50
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
51
+ "hi" )
52
+ CODE
53
+ assert(chunk.parse.nil?)
54
+ end
55
+
56
+ test "fails if there's a stray close-block symbol on the last line (sorry)" do
57
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
58
+ "hi" }
59
+ CODE
60
+ assert(chunk.parse.nil?)
61
+ end
62
+
63
+ test "fails if it can't parse the code" do
64
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
65
+ }
66
+ CODE
67
+ assert(chunk.parse.nil?)
68
+ end
69
+
70
+ test "fails if it can't find the file" do
71
+ chunk = Chunk.new("nonexistent_file.rb", 0)
72
+ error = get_error { chunk.parse }
73
+ assert error.is_a? Errno::ENOENT
74
+ end
75
+
76
+ end
77
+
78
+ regarding "#claim" do
79
+ test "returns the part of the assertion statement inside the curly braces" do
80
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
81
+ assert { x == 5 }
82
+ CODE
83
+ full_code = chunk.parse.to_ruby
84
+ assert(full_code == "assert { (x == 5) }")
85
+ claim_code = chunk.claim.to_ruby
86
+ assert claim_code == "(x == 5)"
87
+ end
88
+
89
+
90
+ test "reads an assert statement on a line by itself" do
91
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
92
+ assert { x == 5 }
93
+ CODE
94
+ claim_code = chunk.claim.to_ruby
95
+ assert claim_code == "(x == 5)"
96
+ end
97
+
98
+ test "reads an assert statement on multiple lines" do
99
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
100
+ assert do
101
+ x == 5
102
+ end
103
+ CODE
104
+ claim_code = chunk.claim.to_ruby
105
+ assert claim_code == "(x == 5)"
106
+ end
107
+
108
+ def yielding
109
+ yield
110
+ end
111
+
112
+ if RUBY_VERSION > "1.9"
113
+ test "reads an assert statement that's nested inside another yield block on the same line (Ruby 1.9 only)" do
114
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
115
+ yielding { assert { x == 5 }}
116
+ CODE
117
+ code = chunk.claim.to_ruby
118
+ assert code == "(x == 5)"
119
+ end
120
+
121
+ # test "goes crazy if you try to nest two asserts on the same line"
122
+ end
123
+
124
+ test "if it can't find an assertion, it uses the whole chunk" do
125
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
126
+ yielding { x == 5 }
127
+ CODE
128
+ code = chunk.claim.to_ruby
129
+ assert code == "yielding { (x == 5) }"
130
+ end
131
+
132
+ test "fails if it can't parse the code" do
133
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
134
+ }
135
+ CODE
136
+ error = get_error {
137
+ chunk.claim
138
+ }
139
+ assert error.message.include?("Could not parse")
140
+ end
141
+ end
142
+
143
+ regarding "#parts" do
144
+ test "returns all unique sub-expressions of the main sexpression" do
145
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
146
+ assert { (x == 5) && (y == (z + 10)) }
147
+ CODE
148
+ code_parts = chunk.parts
149
+ assert code_parts == <<-PARTS.split("\n")
150
+ ((x == 5) and (y == (z + 10)))
151
+ (x == 5)
152
+ x
153
+ 5
154
+ (y == (z + 10))
155
+ y
156
+ (z + 10)
157
+ z
158
+ 10
159
+ PARTS
160
+ end
161
+ end
162
+ end
163
+
164
+ regarding Sexp do
165
+ regarding "#doop" do
166
+ test "deeply duplicates the sexp" do
167
+ original = RubyParser.new.parse("x == 5")
168
+ duplicate = original.doop
169
+ assert(original.object_id != duplicate.object_id)
170
+ assert(original[1].object_id != duplicate[1].object_id)
171
+ assert(original[1][3].object_id != duplicate[1][3].object_id)
172
+ assert(original[3].object_id != duplicate[3].object_id)
173
+ end
174
+ end
175
+
176
+ regarding "#to_ruby" do
177
+ test "converts the sexp to ruby code" do
178
+ sexp = RubyParser.new.parse("x == 5")
179
+ assert sexp.to_ruby == "(x == 5)"
180
+ end
181
+
182
+ test "leaves the original sexp alone" do
183
+ sexp = RubyParser.new.parse("x == 5")
184
+ assert sexp.to_ruby == "(x == 5)"
185
+ assert sexp.to_ruby == "(x == 5)"
186
+ end
187
+ end
188
+
189
+ regarding "#assertion? with a question mark" do
190
+ test "matches an sexp that looks like assert { }" do
191
+ sexp = RubyParser.new.parse("assert { true }")
192
+ assert sexp.assertion?
193
+ end
194
+
195
+ test "matches an sexp that looks like assert(message) { }" do
196
+ sexp = RubyParser.new.parse("assert('hi') { true }")
197
+ assert sexp.assertion?
198
+ end
199
+
200
+ test "matches an sexp that looks like deny { }" do
201
+ sexp = RubyParser.new.parse("deny { false }")
202
+ assert sexp.assertion?
203
+ end
204
+
205
+ test "doesn't match an sexp that calls assert without a block" do
206
+ sexp = RubyParser.new.parse("assert(true)")
207
+ assert !sexp.assertion?
208
+ end
209
+
210
+ test "doesn't match a normal sexp" do
211
+ sexp = RubyParser.new.parse("x == 5")
212
+ assert !sexp.assertion?
213
+ end
214
+ end
215
+
216
+ regarding "#assertion" do
217
+ test "matches a top-level sexp that looks like assert { }" do
218
+ sexp = RubyParser.new.parse("assert { true }")
219
+ code = sexp.assertion.to_ruby
220
+ assert code == "assert { true }"
221
+ end
222
+
223
+ test "matches a nested sexp that looks like assert { }" do
224
+ sexp = RubyParser.new.parse("nesting { assert { true } }")
225
+ code = sexp.assertion.to_ruby
226
+ assert code == "assert { true }"
227
+ end
228
+
229
+ test "matches the first nested sexp that looks like assert { }" do
230
+ sexp = RubyParser.new.parse("nesting { assert { true } or assert { false } }")
231
+ code = sexp.assertion.to_ruby
232
+ assert code == "assert { true }"
233
+ end
234
+ end
235
+
236
+ end
@@ -1,113 +1,148 @@
1
- require "test/test_helper"
1
+ require "./test/test_helper"
2
2
 
3
3
  require "wrong/assert"
4
4
 
5
- apropos "failures" do
6
-
5
+ regarding "failures" do
6
+
7
7
  before do
8
8
  @m = Module.new do
9
9
  extend Wrong::Assert
10
10
  end
11
11
  end
12
-
13
- apropos "simple" do
14
- test "raw boolean failure" do
15
- assert_match "false", get_error{@m.assert{false}}.message
16
- assert_match "true", get_error{@m.deny{true}}.message
12
+
13
+ regarding "simple" do
14
+
15
+ test "raw boolean assert failure" do
16
+ error = get_error { @m.assert { false } }
17
+ # puts error.message
18
+ assert_match "false", error.message
19
+ end
20
+
21
+ test "raw boolean deny failure" do
22
+ error = get_error {
23
+ @m.deny { true }
24
+ }
25
+ # puts error.message
26
+ assert_match "true", error.message
17
27
  end
18
-
28
+
19
29
  test "equality failure" do
20
- assert_match "1 is not equal to 2", get_error{@m.assert{1==2}}.message
21
- assert_match "1 is equal to 1", get_error{@m.deny{1==1}}.message
30
+ assert_match "1 is not equal to 2", get_error {
31
+ @m.assert { 1==2 }
32
+ }.message
33
+ assert_match "1 is equal to 1", get_error {
34
+ @m.deny { 1==1 }
35
+ }.message
22
36
  end
23
-
37
+
24
38
  test "failure of basic operations" do
25
- assert_match "1 is not greater than 2", get_error{@m.assert{1>2}}.message
26
- assert_match "2 is not less than 1", get_error{@m.assert{2<1}}.message
27
- assert_match "1 is not greater than or equal to 2", get_error{@m.assert{1>=2}}.message
28
- assert_match "2 is not less than or equal to 1", get_error{@m.assert{2<=1}}.message
29
-
30
- assert_match "2 is greater than 1", get_error{@m.deny{2>1}}.message
31
- assert_match "1 is less than 2", get_error{@m.deny{1<2}}.message
32
- assert_match "2 is greater than or equal to 1", get_error{@m.deny{2>=1}}.message
33
- assert_match "1 is less than or equal to 2", get_error{@m.deny{1<=2}}.message
34
- end
35
-
36
- class Color
37
- attr_reader :name
38
- def initialize(name)
39
- @name = name
40
- end
41
-
42
- def ==(other)
43
- other.is_a?(Color) && @name == other.name
44
- end
45
-
46
- def inspect
47
- "Color:#{@name}"
48
- end
39
+ assert_match "1 is not greater than 2", get_error {
40
+ @m.assert { 1>2 }
41
+ }.message
42
+ assert_match "2 is not less than 1", get_error {
43
+ @m.assert { 2<1 }
44
+ }.message
45
+ assert_match "1 is not greater than or equal to 2", get_error {
46
+ @m.assert { 1>=2 }
47
+ }.message
48
+ assert_match "2 is not less than or equal to 1", get_error {
49
+ @m.assert { 2<=1 }
50
+ }.message
51
+
52
+ assert_match "2 is greater than 1", get_error {
53
+ @m.deny { 2>1 }
54
+ }.message
55
+ assert_match "1 is less than 2", get_error {
56
+ @m.deny { 1<2 }
57
+ }.message
58
+ assert_match "2 is greater than or equal to 1", get_error {
59
+ @m.deny { 2>=1 }
60
+ }.message
61
+ assert_match "1 is less than or equal to 2", get_error {
62
+ @m.deny { 1<=2 }
63
+ }.message
49
64
  end
50
-
65
+
51
66
  test "object failure" do
52
- assert_match "'Color:red' is not equal to 2", get_error{@m.assert{Color.new("red")==2}}.message
67
+ assert_match "Color:red is not equal to 2", get_error {
68
+ @m.assert { Color.new("red")==2 }
69
+ }.message
53
70
  end
54
-
55
- test %{multiline assert block shouldn't look any different
71
+
72
+ test %{multiline assert block shouldn't look any different
56
73
  than when there everything is on one line} do
57
- assert_match("1 is not equal to 2", get_error{@m.assert{
58
- 1==
59
- 2
60
- }}.message)
74
+ assert_match("1 is not equal to 2", get_error {
75
+ @m.assert {
76
+ 1==
77
+ 2
78
+ }
79
+ }.message)
61
80
  end
62
81
 
63
82
  end
64
-
65
- apropos "accessing and printing values set outside of the assert" do
83
+
84
+ regarding "accessing and printing values set outside of the assert" do
66
85
  test "use a value in the assert defined outside of it" do
67
86
  a = 1
68
- assert_match "1 is not equal to 2", get_error{@m.assert{a==2}}.message
69
- assert_match "1 is equal to 1", get_error{@m.deny{a==1}}.message
87
+ assert_match "1 is not equal to 2", get_error {
88
+ @m.assert { a==2 }
89
+ }.message
90
+ assert_match "1 is equal to 1", get_error {
91
+ @m.deny { a==1 }
92
+ }.message
70
93
  end
71
94
  end
72
-
73
- apropos "the assert block has many statements" do
95
+
96
+ regarding "the assert block has many statements" do
74
97
  test "only pay attention to the final statement" do
75
- assert_match("1 is not equal to 2", get_error{@m.assert{
76
- a = "aaa"
77
- b = 1 + 2
78
- c = ["foo", "bar"].length / 3
79
- if a=="aaa"
80
- b = 4
81
- end; 1==2
82
- }}.message)
98
+ assert_match("1 is not equal to 2", get_error {
99
+ @m.assert {
100
+ a = "aaa"
101
+ b = 1 + 2
102
+ c = ["foo", "bar"].length / 3
103
+ if a=="aaa"
104
+ b = 4
105
+ end; 1==2
106
+ }
107
+ }.message)
83
108
  end
84
109
 
85
110
  test "works even if the assertion is based on stuff set previously in the block" do
86
- assert_match("'aaa' is not equal to 'bbb'", get_error{@m.assert{
87
- a = "aaa"
88
- a=="bbb"
89
- }}.message)
111
+ assert_match("\"aaa\" is not equal to \"bbb\"", get_error {
112
+ @m.assert {
113
+ a = "aaa"
114
+ a=="bbb"
115
+ }
116
+ }.message)
90
117
  end
91
118
  end
92
-
93
- apropos "array comparisons" do
119
+
120
+ regarding "array comparisons" do
94
121
  test "basic" do
95
- assert_match %{'[1, 2]' is not equal to '["a", "b"]'}, get_error{@m.assert{[1,2]==%w{a b}}}.message
122
+ assert_match %{[1, 2] is not equal to ["a", "b"]}, get_error {
123
+ @m.assert { [1, 2]==%w{a b} }
124
+ }.message
96
125
  end
97
126
  end
98
-
99
- apropos "hash comparisons" do
127
+
128
+ regarding "hash comparisons" do
100
129
  test "basic" do
101
- assert_match %{'{1=>2}' is not equal to '{"a"=>"b"}'},
102
- get_error{@m.assert{{1=>2}=={"a"=>"b"}}}.message
130
+ assert_match '{1=>2} is not equal to {"a"=>"b"}',
131
+ get_error {
132
+ @m.assert { {1=>2}=={"a"=>"b"} }
133
+ }.message
103
134
  end
104
135
  end
105
-
106
- apropos "methods that result in a boolean. this might be hard." do
136
+
137
+ regarding "methods that result in a boolean. this might be hard." do
107
138
  test "string include" do
108
- assert_match "'abc' does not include 'cd'", get_error{@m.assert{"abc".include?("cd")}}.message
109
- assert_match "'abc' includes 'bc'", get_error{@m.deny{"abc".include?("bc")}}.message
139
+ assert_match "\"abc\" does not include \"cd\"", get_error {
140
+ @m.assert { "abc".include?("cd") }
141
+ }.message
142
+ assert_match "\"abc\" includes \"bc\"", get_error {
143
+ @m.deny { "abc".include?("bc") }
144
+ }.message
110
145
  end
111
146
  end
112
147
 
113
- end
148
+ end