wrong 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -56,7 +56,7 @@ And a companion, 'deny':
56
56
 
57
57
  deny{'abc'.include?('bc')}
58
58
  ==> Didn't expect "abc".include?("bc")
59
-
59
+
60
60
  More examples are in the file `examples.rb` <http://github.com/alexch/wrong/blob/master/examples.rb>
61
61
 
62
62
  There's also a spreadsheet showing a translation from Test::Unit and RSpec to Wrong, with notes, at [this Google Doc](https://spreadsheets.google.com/pub?key=0AouPn6oLrimWdE0tZDVOWnFGMzVPZy0tWHZwdnhFYkE&hl=en&output=html). (Ask <alexch@gmail.com> if you want editing privileges.)
@@ -105,11 +105,34 @@ We also implement the most amazing debugging method ever, `d`, which gives you a
105
105
  x = 7
106
106
  d { x } # => prints "x is 7" to the console
107
107
  d { x * 2 } # => prints "(x * 2) is 14" to the console
108
+ d("math is hard") { 2 + 2 } #=> prints "math is hard: (2 + 2) is 4"
108
109
 
109
110
  `d` was originally implemented by Rob Sanheim in LogBuddy; as with Assert2 this version is a rewrite and homage. You may also enjoy [g](https://github.com/jugyo/g) by [jugyo](http://jugyo.org/).
110
111
 
111
112
  Remember, if you want `d` to work at runtime (e.g. in a webapp) then you must `include Wrong::D` inside your app, e.g. in your `environment.rb` file.
112
113
 
114
+ ### eventually
115
+
116
+ If you care that something is going to be true *soon*, but maybe not *right* now, use `eventually`. It will keep executing the block, up to 4 times a second, until either
117
+
118
+ * the block returns true(ish)
119
+ * 5 seconds elapse
120
+
121
+ If the block raises an exception, then `eventually` will treat that as a false and keep trying. The last time it fails, it'll raise that exception instead of a mere `AssertionFailedError`. That way, the following are all possible:
122
+
123
+ eventually { false }
124
+ eventually { assert { false } }
125
+ eventually { false.should be_true } # in RSpec
126
+
127
+ and you should get the expected failure after time expires.
128
+
129
+ You can also send options to eventually as hash parameters.
130
+
131
+ eventually(:timeout => 10) { false } # keep trying for 10 sec
132
+ eventually(:delay => 1) { false } # try every 1.0 sec, not every 0.25 sec
133
+
134
+ (For now, `eventually` is in its own module, but you get it when you `include Wrong`. Maybe it should be in Helpers like the rest?)
135
+
113
136
  ## Test Framework Adapters ##
114
137
 
115
138
  Adapters for various test frameworks sit under wrong/adapters.
@@ -297,11 +320,11 @@ We hope this structure lets your eyes focus on the meaningful values and differe
297
320
 
298
321
  Wrong tries to maintain indentation to improve readability. If the inspected VALUE contains newlines, or is longer than will fit on your console, the succeeding lines will be indented to a pleasant level.
299
322
 
300
- Sometimes Wrong will not be able to evaluate a detail without raising an exception. This exception will be duly noted, which might be misleading. For example,
323
+ Sometimes Wrong will not be able to evaluate a detail without raising an exception. This exception will be duly noted, which might be misleading. For example,
301
324
 
302
325
  a = [1,2,3,4]
303
326
  assert { a.all? {|i| i<4} }
304
-
327
+
305
328
  would fail, since on the final pass, `(i < 4)` is false. But the error message is a bit vague:
306
329
 
307
330
  Wrong::Assert::AssertionFailedError: Expected a.all? { |i| (i < 4) }, but
data/lib/wrong.rb CHANGED
@@ -12,12 +12,15 @@ require "wrong/irb"
12
12
  require "wrong/d"
13
13
  require "wrong/message/array_diff"
14
14
  require "wrong/message/string_comparison"
15
+ require "wrong/eventually"
15
16
 
16
17
  module Wrong
17
18
  include Wrong::Assert
18
19
  extend Wrong::Assert
19
20
  include Wrong::Helpers
20
21
  extend Wrong::Helpers
22
+ include Wrong::Eventually
23
+ extend Wrong::Eventually
21
24
  end
22
25
 
23
26
  # this does some magic; if you don't like it...
data/lib/wrong/d.rb CHANGED
@@ -37,7 +37,8 @@ module Wrong
37
37
  value = value.color(:magenta)
38
38
  end
39
39
 
40
- puts [code, "is", value].join(" ")
40
+ message = args.compact.join(", ") + ":" unless args.empty?
41
+ puts [message, code, "is", value].compact.join(" ")
41
42
  end
42
43
 
43
44
  extend D # this allows you to call Wrong::D.d if you like
@@ -0,0 +1,24 @@
1
+ module Wrong
2
+ module Eventually
3
+ NO_BLOCK_PASSED = "you must pass a block to the eventually method"
4
+
5
+ def eventually options = {}, &block
6
+ raise NO_BLOCK_PASSED if block.nil?
7
+ timeout = options[:timeout] || 5
8
+ delay = options[:delay] || 0.25
9
+ last_error = nil
10
+ success = nil
11
+ begin_time = Time.now
12
+ while (Time.now - begin_time) < timeout
13
+ begin
14
+ aver(:assert, &block)
15
+ return
16
+ rescue Exception => e
17
+ last_error = e
18
+ sleep delay
19
+ end
20
+ end
21
+ raise last_error
22
+ end
23
+ end
24
+ end
data/lib/wrong/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Wrong
2
- VERSION = "0.5.6" unless defined?(Wrong::VERSION)
2
+ VERSION = "0.6.0" unless defined?(Wrong::VERSION)
3
3
  end
data/test/chunk_test.rb CHANGED
@@ -164,8 +164,8 @@ describe Chunk do
164
164
  assert { (x == 5) && (y == (z + 10)) }
165
165
  CODE
166
166
  code_parts = chunk.parts
167
- assert code_parts == <<-PARTS.split("\n")
168
- ((x == 5) and (y == (z + 10)))
167
+ assert code_parts == <<-PARTS.split("\n"), code_parts
168
+ (x == 5) and (y == (z + 10))
169
169
  (x == 5)
170
170
  x
171
171
  5
data/test/d_test.rb CHANGED
@@ -29,11 +29,11 @@ describe "d" do
29
29
  output = capturing do
30
30
  d { x }
31
31
  end
32
- assert { output ==
33
- "x is [\"aaaaaaaaaa\",\n \"bbbbbbbbbb\"]\n"
32
+ assert { output ==
33
+ "x is [\"aaaaaaaaaa\",\n \"bbbbbbbbbb\"]\n"
34
34
  }
35
35
  ensure
36
- Wrong::Chunk.terminal_width = nil
36
+ Wrong::Chunk.terminal_width = nil
37
37
  end
38
38
  end
39
39
 
@@ -72,10 +72,24 @@ describe "d" do
72
72
 
73
73
  it "works when called on the D module" do
74
74
  x = 9
75
- output = capturing {
75
+ output = capturing {
76
76
  Wrong::D.d { x }
77
77
  }
78
78
  assert { output == "x is 9\n" }
79
79
  end
80
80
 
81
+ it "takes an optional message string" do
82
+ output = capturing {
83
+ Wrong::D.d("basic math") { 2 + 2 }
84
+ }
85
+ assert { output == "basic math: (2 + 2) is 4\n" }
86
+ end
87
+
88
+ it "takes a bunch of optional messages" do
89
+ output = capturing {
90
+ Wrong::D.d(2, "plus", :two) { 2 + 2 }
91
+ }
92
+ assert { output == "2, plus, two: (2 + 2) is 4\n" }
93
+ end
94
+
81
95
  end
@@ -0,0 +1,191 @@
1
+ # based on
2
+ # * https://gist.github.com/1228927
3
+ # * https://github.com/pivotal/selenium/blob/master/lib/selenium/wait_for.rb
4
+ # see
5
+ # http://rubyforge.org/pipermail/rspec-users/2011-September/020575.html
6
+
7
+ here = File.expand_path(File.dirname(__FILE__))
8
+
9
+ require "#{here}/test_helper"
10
+ require "wrong/assert"
11
+ require "wrong/helpers"
12
+ require "wrong/d"
13
+
14
+ require "wrong/eventually"
15
+
16
+ # todo: move this to a monkey patch file
17
+ class Object
18
+ unless Object.method_defined? :singleton_class
19
+ def singleton_class
20
+ class << self
21
+ self
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "eventually" do
28
+ include Wrong::Eventually
29
+ include Wrong::Assert
30
+ include Wrong::Helpers
31
+ include Wrong::D
32
+
33
+ # rolling our own mock clock and stubbing framework since we want these
34
+ # tests to run in MiniTest or in any version of RSpec
35
+
36
+ class ::Time
37
+ class << self
38
+ alias_method :real_now, :now
39
+ def now
40
+ # puts "in new now; original_now = #{original_now}, @now = #{@now}"
41
+ @now ||= real_now
42
+ end
43
+ def now= new_now
44
+ @now = new_now
45
+ end
46
+ end
47
+ end
48
+
49
+ def stub_it(receiver, method_name, &block)
50
+ receiver.singleton_class.send(:define_method, method_name, &block)
51
+ end
52
+
53
+ def unstub_it(receiver, method_name)
54
+ receiver.singleton_class.send(:remove_method, method_name)
55
+ end
56
+
57
+ before do
58
+ stub_it(self, :sleep) do |secs|
59
+ Time.now += secs
60
+ end
61
+ end
62
+
63
+ after do
64
+ unstub_it(self, :sleep)
65
+ end
66
+
67
+ it "requires a block" do
68
+ e = rescuing {
69
+ eventually
70
+ }
71
+ assert { e.message == Wrong::Eventually::NO_BLOCK_PASSED }
72
+ assert { e.message =~ /pass a block/ }
73
+ end
74
+
75
+ it "returns immediately if the block evaluates to true" do
76
+ original_now = Time.now
77
+ eventually { true }
78
+ assert { Time.now == original_now }
79
+ end
80
+
81
+ it "raises an exception after 5 seconds of being false" do
82
+ original_now = Time.now
83
+ e = rescuing do
84
+ eventually { false }
85
+ end
86
+ deny { e.nil? }
87
+ assert { Time.now == original_now + 5}
88
+ end
89
+
90
+ it "calls the block every 0.25 seconds" do
91
+ original_now = Time.now
92
+ called_at = []
93
+ rescuing {
94
+ eventually {
95
+ called_at << (Time.now - original_now)
96
+ false
97
+ }
98
+ }
99
+ assert { called_at.uniq == [
100
+ 0.0, 0.25, 0.5, 0.75,
101
+ 1.0, 1.25, 1.5, 1.75,
102
+ 2.0, 2.25, 2.5, 2.75,
103
+ 3.0, 3.25, 3.5, 3.75,
104
+ 4.0, 4.25, 4.5, 4.75,
105
+ ] }
106
+ end
107
+
108
+ it "puts the elapsed time in the exception message"
109
+ # assert { e.message =~ /\(after 5 sec\)$/}
110
+
111
+
112
+ it "returns after the condition is false for a while then true" do
113
+ original_now = Time.now
114
+ eventually {
115
+ # cleverly, I am asserting that time has passed
116
+ Time.now >= original_now + 2
117
+ }
118
+ assert {
119
+ Time.now == original_now + 2
120
+ }
121
+ end
122
+
123
+ it "raises a detailed Wrong exception if the result keeps being false" do
124
+ original_now = Time.now
125
+ e = rescuing do
126
+ eventually { false }
127
+ end
128
+ assert { e.message == "Expected false" }
129
+
130
+ x = 1
131
+ e = rescuing do
132
+ eventually { x + 2 == 4 }
133
+ end
134
+ assert { e.message == "Expected ((x + 2) == 4), but\n (x + 2) is 3\n x is 1\n" }
135
+ end
136
+
137
+ describe "if the block raises an exception" do
138
+ it "for 5 seconds, it raises that exception" do
139
+ original_now = Time.now
140
+ e = rescuing do
141
+ eventually { raise "nope" }
142
+ end
143
+ deny { e.nil? }
144
+ assert { Time.now == original_now + 5}
145
+ assert { e.is_a? RuntimeError }
146
+ assert { e.message == "nope" }
147
+ end
148
+
149
+ it "but then returns true, it succeeds silently" do
150
+ original_now = Time.now
151
+ eventually {
152
+ if Time.now < original_now + 2
153
+ raise "not yet"
154
+ else
155
+ true
156
+ end
157
+ }
158
+ assert {
159
+ Time.now == original_now + 2
160
+ }
161
+ end
162
+ end
163
+
164
+ describe "passes a context hash to the block" do
165
+ it "that influences the error message"
166
+ end
167
+
168
+ describe "takes an options hash" do
169
+ it "that can change the timeout" do
170
+ original_now = Time.now
171
+ rescuing {
172
+ eventually(:timeout => 2) { false }
173
+ }
174
+ assert {
175
+ Time.now == original_now + 2
176
+ }
177
+ end
178
+
179
+ it "that can change the delay" do
180
+ original_now = Time.now
181
+ called_at = []
182
+ rescuing {
183
+ eventually(:delay => 1.5) {
184
+ called_at << (Time.now - original_now)
185
+ false
186
+ }
187
+ }
188
+ assert { called_at.uniq == [0.0, 1.5, 3.0, 4.5] }
189
+ end
190
+ end
191
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrong
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-08-24 00:00:00.000000000Z
13
+ date: 2011-10-13 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: predicated
17
- requirement: &70326965279440 !ruby/object:Gem::Requirement
17
+ requirement: &70261729040380 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.2.3
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70326965279440
25
+ version_requirements: *70261729040380
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: ruby_parser
28
- requirement: &70326965278120 !ruby/object:Gem::Requirement
28
+ requirement: &70261729039880 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 2.0.4
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70326965278120
36
+ version_requirements: *70261729039880
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: ruby2ruby
39
- requirement: &70326965276680 !ruby/object:Gem::Requirement
39
+ requirement: &70261729039420 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '1.2'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70326965276680
47
+ version_requirements: *70261729039420
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: sexp_processor
50
- requirement: &70326965275820 !ruby/object:Gem::Requirement
50
+ requirement: &70261729038960 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '3.0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70326965275820
58
+ version_requirements: *70261729038960
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: diff-lcs
61
- requirement: &70326965274860 !ruby/object:Gem::Requirement
61
+ requirement: &70261729038500 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ~>
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.1.2
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *70326965274860
69
+ version_requirements: *70261729038500
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: ParseTree
72
- requirement: &70326965274080 !ruby/object:Gem::Requirement
72
+ requirement: &70261729038040 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '3.0'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *70326965274080
80
+ version_requirements: *70261729038040
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: sourcify
83
- requirement: &70326965273080 !ruby/object:Gem::Requirement
83
+ requirement: &70261729037580 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: 0.3.0
89
89
  type: :runtime
90
90
  prerelease: false
91
- version_requirements: *70326965273080
91
+ version_requirements: *70261729037580
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: file-tail
94
- requirement: &70326965272260 !ruby/object:Gem::Requirement
94
+ requirement: &70261729037120 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ~>
@@ -99,7 +99,7 @@ dependencies:
99
99
  version: '1.0'
100
100
  type: :runtime
101
101
  prerelease: false
102
- version_requirements: *70326965272260
102
+ version_requirements: *70261729037120
103
103
  description: ! 'Wrong provides a general assert method that takes a predicate block.
104
104
  Assertion failure
105
105
 
@@ -129,6 +129,7 @@ files:
129
129
  - lib/wrong/close_to.rb
130
130
  - lib/wrong/config.rb
131
131
  - lib/wrong/d.rb
132
+ - lib/wrong/eventually.rb
132
133
  - lib/wrong/failure_message.rb
133
134
  - lib/wrong/helpers.rb
134
135
  - lib/wrong/irb.rb
@@ -172,6 +173,7 @@ files:
172
173
  - test/close_to_test.rb
173
174
  - test/config_test.rb
174
175
  - test/d_test.rb
176
+ - test/eventually_test.rb
175
177
  - test/failure_message_test.rb
176
178
  - test/failures_test.rb
177
179
  - test/message/array_diff_test.rb
@@ -197,7 +199,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
199
  version: '0'
198
200
  segments:
199
201
  - 0
200
- hash: -1102052589902211149
202
+ hash: -2960303026263975082
201
203
  required_rubygems_version: !ruby/object:Gem::Requirement
202
204
  none: false
203
205
  requirements:
@@ -243,6 +245,7 @@ test_files:
243
245
  - test/close_to_test.rb
244
246
  - test/config_test.rb
245
247
  - test/d_test.rb
248
+ - test/eventually_test.rb
246
249
  - test/failure_message_test.rb
247
250
  - test/failures_test.rb
248
251
  - test/message/array_diff_test.rb