wrong 0.4.0 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.markdown +97 -49
  2. data/lib/wrong/adapters/minitest.rb +5 -2
  3. data/lib/wrong/adapters/rspec.rb +36 -15
  4. data/lib/wrong/assert.rb +1 -33
  5. data/lib/wrong/chunk.rb +34 -24
  6. data/lib/wrong/config.rb +42 -7
  7. data/lib/wrong/failure_message.rb +59 -0
  8. data/lib/wrong/helpers.rb +13 -12
  9. data/lib/wrong/message/array_diff.rb +1 -1
  10. data/lib/wrong/rainbow.rb +9 -4
  11. data/lib/wrong/sexp_ext.rb +6 -6
  12. data/lib/wrong/version.rb +1 -1
  13. data/lib/wrong.rb +14 -3
  14. data/test/adapters/minitest_test.rb +2 -3
  15. data/test/adapters/railsapp/app/controllers/application_controller.rb +3 -0
  16. data/test/adapters/railsapp/app/helpers/application_helper.rb +2 -0
  17. data/test/adapters/railsapp/autotest/discover.rb +2 -0
  18. data/test/adapters/railsapp/config/application.rb +42 -0
  19. data/test/adapters/railsapp/config/boot.rb +13 -0
  20. data/test/adapters/railsapp/config/environment.rb +5 -0
  21. data/test/adapters/railsapp/config/environments/development.rb +26 -0
  22. data/test/adapters/railsapp/config/environments/production.rb +49 -0
  23. data/test/adapters/railsapp/config/environments/test.rb +35 -0
  24. data/test/adapters/railsapp/config/initializers/backtrace_silencers.rb +7 -0
  25. data/test/adapters/railsapp/config/initializers/inflections.rb +10 -0
  26. data/test/adapters/railsapp/config/initializers/mime_types.rb +5 -0
  27. data/test/adapters/railsapp/config/initializers/secret_token.rb +7 -0
  28. data/test/adapters/railsapp/config/initializers/session_store.rb +8 -0
  29. data/test/adapters/railsapp/config/routes.rb +58 -0
  30. data/test/adapters/railsapp/db/seeds.rb +7 -0
  31. data/test/adapters/railsapp/spec/spec_helper.rb +28 -0
  32. data/test/adapters/railsapp/spec/wrong_spec.rb +8 -0
  33. data/test/adapters/rspec_rails_test.rb +58 -0
  34. data/test/adapters/rspec_test.rb +0 -61
  35. data/test/adapters/test_unit_test.rb +2 -2
  36. data/test/assert_advanced_test.rb +4 -4
  37. data/test/chunk_test.rb +14 -0
  38. data/test/config_test.rb +98 -51
  39. data/test/failure_message_test.rb +66 -16
  40. data/test/failures_test.rb +40 -86
  41. data/test/message/array_diff_test.rb +6 -2
  42. data/test/string_comparison_test.rb +3 -1
  43. data/test/test_helper.rb +26 -3
  44. metadata +190 -215
@@ -20,18 +20,18 @@ describe "advanced assert features" do
20
20
  end
21
21
  end
22
22
 
23
- xit "can parse a here doc defined inside the block" do
23
+ it "can parse a here doc defined inside the block" do
24
24
  # todo: test in Chunk too
25
- assert { "123\n456" == <<-TEXT
25
+ assert { "123\n456\n" == <<-TEXT
26
26
  123
27
27
  456
28
28
  TEXT
29
29
  }
30
30
  end
31
31
 
32
- xit "can parse a here doc defined outside the block" do
32
+ it "can parse a here doc defined outside the block" do
33
33
  # todo: test in Chunk too
34
- assert { "123\n456" == <<-TEXT }
34
+ assert { "123\n456\n" == <<-TEXT }
35
35
  123
36
36
  456
37
37
  TEXT
data/test/chunk_test.rb CHANGED
@@ -175,6 +175,13 @@ z
175
175
  code_parts = chunk.parts
176
176
  assert !code_parts.include?("rescuing")
177
177
  end
178
+
179
+ it "skips assignments" do
180
+ chunk = Chunk.new(__FILE__, __LINE__ + 1); <<-CODE
181
+ x = 7; x
182
+ CODE
183
+ assert !chunk.parts.include?("(x = 7)")
184
+ end
178
185
  end
179
186
 
180
187
  describe "#details" do
@@ -247,6 +254,13 @@ z
247
254
  # this means it's a literal slash plus t inside double quotes -- i.e. it shows the escaped (inspected) string
248
255
  assert d == "\n" + ' x is "flavor:\tvanilla"' + "\n"
249
256
  end
257
+
258
+ it "skips assignments" do
259
+ y = 14
260
+ d = details { x = 7; y }
261
+ assert d !~ /x = 7/
262
+ assert d =~ /y is 14/
263
+ end
250
264
 
251
265
  it "indents unescaped newlines inside the inspected value" do
252
266
  weirdo = Object.new
data/test/config_test.rb CHANGED
@@ -10,80 +10,127 @@ describe Wrong::Config do
10
10
  include Wrong
11
11
 
12
12
  before do
13
- Wrong.config.clear
13
+ @config = Wrong::Config.new
14
14
  end
15
15
 
16
- it "singleton" do
17
- c = Wrong.config
18
- assert { c.is_a?(Wrong::Config) }
19
- c2 = Wrong.config
20
- assert { c.object_id == c2.object_id }
21
- end
22
-
23
- # it "reads from a .wrong file"
16
+ it "has magic setters" do
17
+ config = Wrong::Config.new
18
+ config.foo = "bar"
19
+ assert { config[:foo] == "bar" }
24
20
 
25
- it "getting an undeclared setting" do
26
- assert { Wrong.config[:foo].nil? }
21
+ config.baz
22
+ assert { config[:baz] }
27
23
  end
28
24
 
29
- it "setting and getting" do
30
- Wrong.config[:foo] = "bar"
31
- assert { Wrong.config[:foo] == "bar" }
25
+ it "reads from a string" do
26
+ config = Wrong::Config.new <<-SETTINGS
27
+ cold
28
+ flavor = "chocolate"
29
+ alias_assert :yum
30
+ SETTINGS
31
+ assert { config[:cold] }
32
+ assert { config[:flavor] == "chocolate" }
33
+ assert { config.assert_method_names.include? :yum }
32
34
  end
33
35
 
34
- describe "adding aliases for assert" do
35
- before do
36
- Wrong.config.alias_assert(:is)
36
+ describe "Wrong.config" do
37
+ it "is a singleton" do
38
+ c = Wrong.config
39
+ assert { c.is_a?(Wrong::Config) }
40
+ c2 = Wrong.config
41
+ assert { c.object_id == c2.object_id }
37
42
  end
38
43
 
39
- it "succeeds" do
40
- is { 2 + 2 == 4 }
44
+ it "reads from a .wrong file in the current directory" do
45
+ wrong_settings = File.read(".wrong")
46
+ assert { wrong_settings != "" }
47
+ assert { Wrong.config[:test_setting] == "xyzzy" }
41
48
  end
42
49
 
43
- it "fails" do
44
- e = rescuing {
45
- is("math is hard") { 2 + 2 == 5 }
46
- }
47
- expected = <<-FAIL
48
- math is hard: Expected ((2 + 2) == 5), but 4 is not equal to 5
49
- (2 + 2) is 4
50
- FAIL
51
- assert { e.message == expected }
50
+ it "reads from a .wrong file in a parent directory" do
51
+ wrong_settings = File.read(".wrong")
52
+ Dir.chdir("test") do # move into a subdirectory
53
+ assert { Wrong.load_config[:test_setting] == "xyzzy" }
54
+ end
52
55
  end
53
56
 
54
- it "doesn't keep aliasing the same word" do
55
- Wrong.config.alias_assert(:is)
56
- Wrong.config.alias_assert(:is)
57
- assert { Wrong.config.assert_method_names == [:assert, :is] }
57
+ it "uses defaults if there is no .wrong file" do
58
+ Dir.chdir("/tmp") do # hopefull there's no .wrong file here or in /
59
+ config = Wrong.load_config
60
+ assert { config[:test_setting] == nil }
61
+ end
58
62
  end
63
+
59
64
  end
60
65
 
61
- describe "adding aliases for deny" do
62
- before do
63
- Wrong.config.alias_deny(:aint)
64
- end
66
+ it "getting an undeclared setting" do
67
+ assert { @config[:foo].nil? }
68
+ end
69
+
70
+ it "setting and getting" do
71
+ @config[:foo] = "bar"
72
+ assert { @config[:foo] == "bar" }
73
+ end
65
74
 
66
- it "succeeds" do
67
- aint { 2 + 2 == 5 }
75
+ describe "adding aliases" do
76
+ after do
77
+ Wrong.config = Wrong::Config.new
68
78
  end
69
79
 
70
- it "fails" do
71
- e = rescuing {
72
- aint("math is hard") { 2 + 2 == 4 }
73
- }
74
- expected = <<-FAIL
75
- math is hard: Didn't expect ((2 + 2) == 4), but 4 is equal to 4
80
+ describe "for assert" do
81
+ before do
82
+ Wrong.config.alias_assert(:is)
83
+ end
84
+
85
+ it "succeeds" do
86
+ is { 2 + 2 == 4 }
87
+ end
88
+
89
+ it "fails" do
90
+ e = rescuing {
91
+ is("math is hard") { 2 + 2 == 5 }
92
+ }
93
+ expected = <<-FAIL
94
+ math is hard: Expected ((2 + 2) == 5), but
76
95
  (2 + 2) is 4
77
- FAIL
78
- assert { e.message == expected }
96
+ FAIL
97
+ assert { e.message == expected }
98
+ end
99
+
100
+ it "doesn't keep aliasing the same word" do
101
+ @config.alias_assert(:is)
102
+ @config.alias_assert(:is)
103
+ assert { @config.assert_method_names == [:assert, :is] }
104
+ end
79
105
  end
80
106
 
81
- it "doesn't keep aliasing the same word" do
82
- Wrong.config.alias_deny(:aint)
83
- Wrong.config.alias_deny(:aint)
84
- assert { Wrong.config.deny_method_names == [:deny, :aint] }
107
+ describe "for deny" do
108
+ before do
109
+ Wrong.config.alias_deny(:aint)
110
+ end
111
+
112
+ it "succeeds" do
113
+ aint { 2 + 2 == 5 }
114
+ end
115
+
116
+ it "fails" do
117
+ e = rescuing {
118
+ aint("math is hard") { 2 + 2 == 4 }
119
+ }
120
+ expected = <<-FAIL
121
+ math is hard: Didn't expect ((2 + 2) == 4), but
122
+ (2 + 2) is 4
123
+ FAIL
124
+ assert { e.message == expected }
125
+ end
126
+
127
+ it "doesn't keep aliasing the same word" do
128
+ @config.alias_deny(:aint)
129
+ @config.alias_deny(:aint)
130
+ assert { @config.deny_method_names == [:deny, :aint] }
131
+ end
132
+
85
133
  end
86
134
 
87
135
  end
88
-
89
136
  end
@@ -2,22 +2,22 @@ require "./test/test_helper"
2
2
  require "wrong/assert"
3
3
  require "wrong/failure_message"
4
4
 
5
- module Wrong
6
-
7
- class BogusFormatter < FailureMessage::Formatter
8
- def match?
9
- predicate.is_a? BogusPredicate
10
- end
11
-
12
- def describe
13
- "bogus #{predicate.object_id}"
14
- end
5
+ class BogusFormatter < Wrong::FailureMessage::Formatter
6
+ def match?
7
+ predicate.is_a? BogusPredicate
15
8
  end
16
9
 
17
- class BogusPredicate < Predicated::Predicate
10
+ def describe
11
+ "bogus #{predicate.object_id}"
18
12
  end
13
+ end
14
+
15
+ class BogusPredicate < Predicated::Predicate
16
+ end
17
+
18
+ module Wrong
19
19
 
20
- describe FailureMessage::Formatter do
20
+ describe Wrong::FailureMessage::Formatter do
21
21
  include Wrong::Assert
22
22
 
23
23
  it "describes a predicate" do
@@ -27,13 +27,63 @@ module Wrong
27
27
  end
28
28
  end
29
29
 
30
- describe FailureMessage do
30
+ describe Wrong::FailureMessage do
31
31
  include Wrong::Assert
32
32
 
33
33
  it "can register a formatter class for a predicate pattern" do
34
- FailureMessage.register_formatter(BogusFormatter)
35
- assert { FailureMessage.formatter_for(BogusPredicate.new).is_a? BogusFormatter }
36
- assert { FailureMessage.formatters.include?(BogusFormatter)}
34
+ Wrong::FailureMessage.register_formatter(::BogusFormatter)
35
+ assert { Wrong::FailureMessage.formatter_for(::BogusPredicate.new).is_a? ::BogusFormatter }
36
+ assert { Wrong::FailureMessage.formatters.include?(::BogusFormatter)}
37
+ end
38
+
39
+ before do
40
+ @chunk = Wrong::Chunk.new(__FILE__, __LINE__ + 1) do
41
+ 2 + 2 == 5
42
+ end
43
+ end
44
+
45
+ def message(options = {}, &block)
46
+ valence = options[:valence] || :assert
47
+ explanation = options[:explanation]
48
+ Wrong::FailureMessage.new(@chunk, valence, explanation)
49
+ end
50
+
51
+
52
+ describe "#basic" do
53
+ it "shows the code" do
54
+ assert { message.basic == "Expected ((2 + 2) == 5)" }
55
+ end
56
+
57
+ it "reverses the message for :deny valence" do
58
+ assert { message(:valence => :deny).basic == "Didn't expect ((2 + 2) == 5)" }
59
+ end
60
+ end
61
+
62
+ describe '#full' do
63
+ it "contains the basic message" do
64
+ assert { message.full.include? message.basic }
65
+ end
66
+
67
+ it "contains the explanation if there is one" do
68
+ msg = message(:explanation => "the sky is falling")
69
+ assert { msg.full.include? "the sky is falling" }
70
+ end
71
+
72
+ it "doesn't say 'but' if there are no details" do
73
+ @chunk = Wrong::Chunk.new(__FILE__, __LINE__ + 1) do
74
+ 2
75
+ end
76
+ assert { @chunk.details.empty? }
77
+ deny { message.full.include? ", but"}
78
+ end
79
+
80
+ it "says 'but' if there are details" do
81
+ @chunk = Wrong::Chunk.new(__FILE__, __LINE__ + 1) do
82
+ 2 + 2 == 5
83
+ end
84
+ assert { message.full.include? ", but\n (2 + 2) is 4"}
85
+ end
86
+
37
87
  end
38
88
 
39
89
  end
@@ -1,6 +1,7 @@
1
1
  require "./test/test_helper"
2
2
 
3
3
  require "wrong/assert"
4
+ require "wrong/sexp_ext"
4
5
 
5
6
  describe "failures" do
6
7
 
@@ -25,51 +26,17 @@ describe "failures" do
25
26
  end
26
27
 
27
28
  it "equality failure" do
28
- assert_match "1 is not equal to 2", get_error {
29
+ assert_match "Expected (1 == 2)", get_error {
29
30
  @m.assert { 1==2 }
30
31
  }.message
31
- assert_match "1 is equal to 1", get_error {
32
+ assert_match "Didn't expect (1 == 1)", get_error {
32
33
  @m.deny { 1==1 }
33
34
  }.message
34
35
  end
35
36
 
36
- it "failure of basic operations" do
37
- assert_match "1 is not greater than 2", get_error {
38
- @m.assert { 1>2 }
39
- }.message
40
- assert_match "2 is not less than 1", get_error {
41
- @m.assert { 2<1 }
42
- }.message
43
- assert_match "1 is not greater than or equal to 2", get_error {
44
- @m.assert { 1>=2 }
45
- }.message
46
- assert_match "2 is not less than or equal to 1", get_error {
47
- @m.assert { 2<=1 }
48
- }.message
49
-
50
- assert_match "2 is greater than 1", get_error {
51
- @m.deny { 2>1 }
52
- }.message
53
- assert_match "1 is less than 2", get_error {
54
- @m.deny { 1<2 }
55
- }.message
56
- assert_match "2 is greater than or equal to 1", get_error {
57
- @m.deny { 2>=1 }
58
- }.message
59
- assert_match "1 is less than or equal to 2", get_error {
60
- @m.deny { 1<=2 }
61
- }.message
62
- end
63
-
64
- it "object failure" do
65
- assert_match "Color:red is not equal to 2", get_error {
66
- @m.assert { Color.new("red")==2 }
67
- }.message
68
- end
69
-
70
37
  it %{multiline assert block shouldn't look any different
71
38
  than when there everything is on one line} do
72
- assert_match("1 is not equal to 2", get_error {
39
+ assert_match("Expected (1 == 2)", get_error {
73
40
  @m.assert {
74
41
  1==
75
42
  2
@@ -82,52 +49,44 @@ describe "failures" do
82
49
  describe "accessing and printing values set outside of the assert" do
83
50
  it "use a value in the assert defined outside of it" do
84
51
  a = 1
85
- assert_match "1 is not equal to 2", get_error {
52
+ assert_match "Expected (a == 2), but", get_error {
86
53
  @m.assert { a==2 }
87
54
  }.message
88
- assert_match "1 is equal to 1", get_error {
55
+ assert_match "Didn't expect (a == 1)", get_error {
89
56
  @m.deny { a==1 }
90
57
  }.message
91
58
  end
92
59
  end
93
60
 
94
- describe "conjunctions (and and or)" do
95
- it "omit a primary failure message since 'This is not true etc.' is more obscuring than clarifying" do
96
- m = get_error {
97
- x = 5
98
- @m.assert { x == 5 && x != 5 }
99
- }.message
100
- assert m == "Expected ((x == 5) and (not (x == 5))), but \n (x == 5) is true\n x is 5\n (not (x == 5)) is false\n"
101
- end
102
- end
103
-
104
- describe "the assert block has many statements" do
105
- it "only pay attention to the final statement" do
106
- assert_match("1 is not equal to 2", get_error {
107
- @m.assert {
108
- a = "aaa"
109
- b = 1 + 2
110
- c = ["foo", "bar"].length / 3
111
- if a=="aaa"
112
- b = 4
113
- end; 1==2
114
- }
115
- }.message)
116
- end
117
-
118
- it "works even if the assertion is based on stuff set previously in the block" do
119
- assert_match("\"aaa\" is not equal to \"bbb\"", get_error {
120
- @m.assert {
121
- a = "aaa"
122
- a=="bbb"
123
- }
124
- }.message)
125
- end
126
- end
61
+ # describe "the assert block has many statements" do
62
+ # this is not true anymore -- should it be?
63
+ # it "only pay attention to the final statement" do
64
+ # assert_match("Expected (1 == 2)", get_error {
65
+ # @m.assert {
66
+ # a = "aaa"
67
+ # b = 1 + 2
68
+ # c = ["foo", "bar"].length / 3
69
+ # if a=="aaa"
70
+ # b = 4
71
+ # end; 1==2
72
+ # }
73
+ # }.message)
74
+ # end
75
+
76
+ # this raises an error trying to evaluate 'a'
77
+ it "works even if the assertion is based on stuff set previously in the block"
78
+ # do
79
+ # assert_match(/Expected.*\(a == "bbb"\)/, get_error {
80
+ # @m.assert {
81
+ # a = "aaa"
82
+ # a=="bbb"
83
+ # }
84
+ # }.message)
85
+ # end
127
86
 
128
87
  describe "array comparisons" do
129
88
  it "basic" do
130
- assert_match %{[1, 2] is not equal to ["a", "b"]}, get_error {
89
+ assert_match 'Expected ([1, 2] == ["a", "b"])', get_error {
131
90
  @m.assert { [1, 2]==%w{a b} }
132
91
  }.message
133
92
  end
@@ -138,19 +97,14 @@ describe "failures" do
138
97
  e = get_error {
139
98
  @m.assert { {1=>2}=={"a"=>"b"} }
140
99
  }
141
- assert_match '{1=>2} is not equal to {"a"=>"b"}',
142
- e.message
143
- end
144
- end
145
-
146
- describe "methods that result in a boolean. this might be hard." do
147
- it "string include" do
148
- assert_match "\"abc\" does not include \"cd\"", get_error {
149
- @m.assert { "abc".include?("cd") }
150
- }.message
151
- assert_match "\"abc\" includes \"bc\"", get_error {
152
- @m.deny { "abc".include?("bc") }
153
- }.message
100
+ # this is weird; it should realize those details are truisms -- must be a whitespace thing
101
+ expected =<<-TEXT
102
+ Expected ({ 1 => 2 } == { "a" => "b" }), but
103
+ { 1 => 2 } is {1=>2}
104
+ { "a" => "b" } is {"a"=>"b"}
105
+ TEXT
106
+
107
+ assert_equal expected, e.message
154
108
  end
155
109
  end
156
110
 
@@ -2,14 +2,13 @@ require "./test/test_helper"
2
2
  require "wrong/assert"
3
3
  require "wrong/helpers"
4
4
  require "wrong/adapters/minitest"
5
-
6
5
  require "wrong/message/array_diff"
7
6
 
8
7
  describe "when you're comparing strings and they don't match, show me the diff message" do
9
8
 
10
9
  def assert_string_diff_message(first_array, second_array, expected_error_message)
11
10
  e = rescuing {
12
- Wrong.assert { first_array == second_array }
11
+ assert { first_array == second_array }
13
12
  }
14
13
  assert {
15
14
  e.message.include?(expected_error_message.strip)
@@ -27,6 +26,11 @@ describe "when you're comparing strings and they don't match, show me the diff m
27
26
  assert { nil==[1] }
28
27
  }.message.include?("^")
29
28
  }
29
+ deny {
30
+ rescuing {
31
+ assert { {:a=>1}==[1] }
32
+ }.message.include?("^")
33
+ }
30
34
  end
31
35
 
32
36
  it "simple" do
@@ -5,6 +5,8 @@ require "wrong/message/string_comparison"
5
5
  module Wrong
6
6
  describe StringComparison do
7
7
 
8
+ StringComparison = Wrong::StringComparison # so Ruby 1.9.1 can find it
9
+
8
10
  before do
9
11
  # crank the window and prelude down for these tests
10
12
  @old_window = StringComparison.window
@@ -153,7 +155,7 @@ second: ..."kl*nopqrstuvwxyz"
153
155
  error = rescuing do
154
156
  assert { "xyz" == "abc" }
155
157
  end
156
- assert { error.message =~ /Strings differ/ }
158
+ assert { error.message =~ /Strings differ at position 0:/ }
157
159
  end
158
160
  end
159
161
  end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,8 @@
1
- puts "RUBY_VERSION=#{RUBY_VERSION}#{" (JRuby)" if Object.const_defined?(:JRuby)}"
1
+ puts(if Object.const_defined? :RUBY_DESCRIPTION
2
+ RUBY_DESCRIPTION
3
+ else
4
+ "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"
5
+ end)
2
6
 
3
7
  dir = File.dirname(__FILE__)
4
8
  $LOAD_PATH.unshift "#{dir}/../lib"
@@ -26,7 +30,26 @@ def get_error
26
30
  error
27
31
  end
28
32
 
29
- class MiniTest::Unit::TestCase
33
+ def sys(cmd, expected_status = 0)
34
+ start_time = Time.now
35
+ $stderr.print cmd
36
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thread|
37
+ # in Ruby 1.8, wait_thread is nil :-( so just pretend the process was successful (status 0)
38
+ exit_status = (wait_thread.value.exitstatus if wait_thread) || 0
39
+ output = stdout.read + stderr.read
40
+ unless expected_status.nil?
41
+ assert { output and exit_status == expected_status }
42
+ end
43
+ yield output if block_given?
44
+ output
45
+ end
46
+ ensure
47
+ $stderr.puts " (#{"%.2f" % (Time.now - start_time)} sec)"
48
+ end
49
+
50
+ def clear_bundler_env
51
+ # Bundler inherits its environment by default, so clear it here
52
+ %w{BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE}.each { |var| ENV.delete(var) }
30
53
  end
31
54
 
32
55
  module Kernel
@@ -37,7 +60,7 @@ end
37
60
 
38
61
  class MiniTest::Spec
39
62
  include MiniTest::Assertions
40
-
63
+
41
64
  class << self
42
65
  def xit(str)
43
66
  puts "x'd out test \"#{str}\""