wrong 0.1.0 → 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.
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