Skip to content

Commit dbaf06a

Browse files
committed
reads settings from a .wrong file
improve README can parse a here doc defined inside the block better Ruby version printing in test_helper
1 parent 04747d4 commit dbaf06a

12 files changed

+206
-102
lines changed

.wrong

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test_setting = "xyzzy"
2+
color = false # sadly, we must disable this when testing wrong

HISTORY.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
== 0.4.1
2+
3+
* reads settings from a .wrong file
4+
15
== 0.4.0
26

37
* "require 'wrong'" and "include Wrong' now get everything; see README for details on how to get less than the whole enchilada

README.markdown

+50-32
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## Abstract ##
66

7-
Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail. The Wrong idea is to replace all those countless assert\_this, assert\_that, should\_something library methods which only exist to give a more useful failure message than "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it in Ruby, Wrong can make a sensible failure message out of it.
7+
Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail. The Wrong idea is to replace all those countless `assert\_this`, `assert\_that`, `should\_something` library methods which only exist to give a failure message that's not simply "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it in Ruby, Wrong can make a sensible failure message out of it.
88

99
We'd very much appreciate feedback and bug reports. There are plenty of things left to be done to make the results look uniformly clean and beautiful. We want your feedback, and especially to give us cases where either it blows up or the output is ugly or uninformative.
1010

@@ -16,11 +16,7 @@ Inspired by [assert { 2.0 }](http://assert2.rubyforge.org/) but rewritten from s
1616

1717
gem install wrong
1818

19-
Under JRuby, the above may cause errors; if so, then try
20-
21-
gem install wrong-jruby
22-
23-
which untangles some dependencies.
19+
We have deployed gems for both Ruby and JRuby; if you get dependency issues on your platform, please let us know what Ruby interpreter and version you're using and what errors you get, and we'll try to track it down.
2420

2521
## Usage ##
2622

@@ -139,30 +135,33 @@ or this
139135
? The Wrong way has the advantage of being plain, transparent Ruby code, not an awkward DSL that moves "equal" out of its natural place between the comparands. Plus, WYSIWYG! You know just from looking at it that "equal" means `==`, not `eql?` or `===` or `=~`.
140136

141137
Moreover, much like TDD itself, Wrong encourages you to write cleaner code. If your assertion messages are not clear and "Englishy", then maybe it's time for you to refactor a bit -- extract an informatively named variable or method, maybe push some function onto its natural object *a la* the [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter)...
138+
Also, try not to call any methods with side effects inside an assert. In addition to being bad form, this can cause messed-up failure messages, since the side effects may occur several times in the process of building the message.
142139

143140
Wrong also lets you put the expected and actual values in any order you want! Consider the failure messages for
144141

145142
assert { current_user == "joe" } # => Expected (current_user == "joe") but current_user is "fred"
146143
assert { "joe" == current_user } # => Expected ("joe" == current_user) but current_user is "fred"
147144

148-
You get just the information you want, and none you don't want. At least, that's the plan! :-)
145+
You get all the information you want, and none you don't want. At least, that's the plan! :-)
149146

150147
## Algorithm ##
151148

152149
So wait a second. How do we do it? Doesn't Ruby have [poor support for AST introspection](http://blog.zenspider.com/2009/04/parsetree-eol.html)? Well, yes, it does, so we cheat: we figure out what file and line the assert block is defined in, then open the file, read the code, and parse it directly using Ryan Davis' amazing [RubyParser](http://parsetree.rubyforge.org/ruby_parser/) and [Ruby2Ruby](http://seattlerb.rubyforge.org/ruby2ruby/). You can bask in the kludge by examining `chunk.rb` and `assert.rb`. If you find some code it can't parse, please send it our way.
153150

154151
Before you get your knickers in a twist about how this is totally unacceptable because it doesn't support this or that use case, here are our caveats and excuses:
155152

156-
* It works! Tested in 1.8.6, 1.8.7, 1.9.1, and 1.9.2-rc2. (Thank you, [rvm](http://rvm.beginrescueend.com/)!)
153+
* It works! Tested in MRI 1.8.6, 1.8.7, 1.9.1, 1.9.2, and JRuby 1.5.3. (Thank you, [rvm](http://rvm.beginrescueend.com/)!)
157154
* Your code needs to be in a file.
158155
* If you're developing Ruby code without saving it to a mounted disk, then sorry, Wrong is not right for you.
159-
* We monkey-patch IRB so if you do `irb -rwrong` it'll save off your session in a place Wrong can read it.
156+
* We monkey-patch IRB so if you do `irb -rwrong` it'll save off your session in memory where Wrong can read it.
157+
* It'd be nice if it could work inside a `-e` block but as far as we can tell, there's no way to grab that `-e` code from inside Ruby.
160158
* It's a development-time testing library, not a production runtime library, so there are no security or filesystem issues.
161159
* `eval` isn't evil, it's just misunderstood.
162160
* It makes a few assumptions about the structure of your code, leading to some restrictions:
163-
* You can't have more than one call to `assert` per line. (This should not be a problem since even if you're nesting asserts for some bizarre reason, we assume you know where your Return key is. And actually, technically you can put two asserts on a line, but it always describes the first one it sees, which means that if the second one executes, its failure message will be incorrect or broken.)
161+
* You can't have more than one call to `assert` per line. (This should not be a problem since even if you're nesting asserts for some bizarre reason, we assume you know where your Return key is.)
164162
* You can't use metaprogramming to write your assert blocks.
165-
* All variables and methods must be available in the binding of the assertion block.
163+
* All variables and methods must be available in the binding of the assert block.
164+
* Passing a proc around and eventually calling assert on it might not work in some Ruby implementations.
166165

167166
## Adapters ##
168167

@@ -172,9 +171,9 @@ Currently we support
172171

173172
* Test::Unit - `require 'wrong/adapters/test_unit'`
174173
* Minitest - `require 'wrong/adapters/minitest'`
175-
* RSpec - `require 'wrong/adapters/rspec'`
174+
* RSpec - `require 'wrong/adapters/rspec'` (now supports both 1.3 and 2.0)
176175

177-
To use these, put the appropriate `require` in your helper; it should extend the framework enough that you can use `assert { }` in your test cases without extra fussing around.
176+
To use these, put the appropriate `require` in your helper, **after** requiring your test framework; it should extend the framework enough that you can use `assert { }` in your test cases without extra fussing around.
178177

179178
## Explanations ##
180179

@@ -248,34 +247,52 @@ To use these formatters, you have to explicitly `require` them! You may also nee
248247

249248
[Bug: turns out 'diff' and 'diff-lcs' are incompatible with each other. We're working on a fix.]
250249

251-
## Color ##
250+
## Config ##
251+
252+
These settings can either be set at runtime on the `Wrong.config` singleton, or inside a `.wrong` file in the current directory or a parent. In the `.wrong` file just pretend every line is preceded with `Wrong.config.` -- e.g. if there's a setting called `ice_cream`, you can do any of these in your `.wrong` file
253+
254+
ice_cream # => Wrong.config[:ice_cream] => true
255+
ice_cream = true # => Wrong.config[:ice_cream] => true
256+
ice_cream = "vanilla" # => Wrong.config[:ice_cream] => "vanilla"
257+
258+
or any of these at runtime:
259+
260+
Wrong.config.ice_cream # => Wrong.config[:ice_cream] => true
261+
Wrong.config.ice_cream = true # => Wrong.config[:ice_cream] => true
262+
Wrong.config.ice_cream = "vanilla" # => Wrong.config[:ice_cream] => "vanilla"
263+
264+
### Color ###
265+
266+
Apparently, no test framework is successful unless and until it supports console colors. So now we do. Call
267+
268+
Wrong.config.color
252269

253-
Apparently, no test framework is successful unless and until it supports console colors. So now we do. Put
270+
in your test helper or rakefile or wherever, or put
254271

255-
Wrong.config[:color] = true
272+
color
256273

257-
in your test helper or rakefile or wherever and get ready to be **bedazzled**. If you need custom colors, let us know.
274+
in your `.wrong` file and get ready to be **bedazzled**. If you need custom colors, let us know.
258275

259-
## Aliases ##
276+
### Aliases ###
260277

261-
An end to the language wars! Name your "assert" and "deny" methods anything you want. Here are some suggestions:
278+
An end to the language wars! Name your "assert" and "deny" methods anything you want. In your code, use `Wrong.config.alias_assert` and `Wrong.config.alias_deny`, and in your `.wrong` file, use Here are some suggestions:
262279

263-
Wrong.config.alias_assert(:expect)
264-
Wrong.config.alias_assert(:should) # This looks nice with RSpec
265-
Wrong.config.alias_assert(:confirm)
266-
Wrong.config.alias_assert(:be)
280+
alias_assert :expect
281+
alias_assert :should # This looks nice in RSpec
282+
alias_assert :confirm
283+
alias_assert :be
267284

268-
Wrong.config.alias_assert(:is)
269-
Wrong.config.alias_deny(:aint)
285+
alias_assert :is
286+
alias_deny :aint
270287

271-
Wrong.config.alias_assert(:assure)
272-
Wrong.config.alias_deny(:refute)
288+
alias_assert :assure
289+
alias_deny :refute
273290

274-
Wrong.config.alias_assert(:yep)
275-
Wrong.config.alias_deny(:nope)
291+
alias_assert :yep
292+
alias_deny :nope
276293

277-
Wrong.config.alias_assert(:yay!)
278-
Wrong.config.alias_deny(:boo!)
294+
alias_assert :yay!
295+
alias_deny :boo!
279296

280297
Just don't use "`aver`" since we took that one for an internal method in `Wrong::Assert`.
281298

@@ -294,7 +311,8 @@ If you're in Ruby 1.8, you **really** shouldn't do it! But if you do, you can us
294311

295312
## Etc ##
296313

297-
* Github projects: <http://github.com/alexch/wrong>, <http://github.com/sconover/wrong>
314+
* Mailing list: <http://groups.google.com/group/wrong-rb>
315+
* Github project: <http://github.com/sconover/wrong>
298316
* Tracker project: <http://www.pivotaltracker.com/projects/109993>
299317
* the [Wrong way translation table (from RSpec and Test::Unit)](https://spreadsheets.google.com/pub?key=0AouPn6oLrimWdE0tZDVOWnFGMzVPZy0tWHZwdnhFYkE&hl=en&output=html). (Ask <[email protected]> if you want editing privileges.)
300318
* the [Wrong slides](http://www.slideshare.net/alexchaffee/wrong-5069976) that Alex presented at Carbon Five and GoGaRuCo

examples.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
include Wrong
1313

14-
Wrong.config[:color] = true
14+
Wrong.config.color # or just put the line "color" in a file called ".wrong" in the current dir
1515

1616
def failing
1717
e = rescuing do

lib/wrong/chunk.rb

+10-8
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,19 @@ def build_sexp
7272
end)
7373
end
7474

75-
def read_source_file(file, dir = ".")
76-
File.read "#{dir}/#{file}"
75+
def read_source_file(file)
76+
Chunk.read_here_or_higher(file)
77+
end
7778

79+
def self.read_here_or_higher(file, dir = ".")
80+
File.read "#{dir}/#{file}"
7881
rescue Errno::ENOENT, Errno::EACCES => e
7982
# we may be in a chdir underneath where the file is, so move up one level and try again
8083
parent = "#{dir}/..".gsub(/^(\.\/)*/, '')
8184
if File.expand_path(dir) == File.expand_path(parent)
8285
raise Errno::ENOENT, "couldn't find #{file}"
8386
end
84-
read_source_file(file, parent)
85-
87+
read_here_or_higher(file, parent)
8688
end
8789

8890
# Algorithm:
@@ -196,10 +198,10 @@ def details
196198
raises = raises.bold.color(:red)
197199
end
198200
formatted_exeption = if e.message and e.message != e.class.to_s
199-
indent(2, part, " ", raises, ": ", indent_all(3, e.message))
200-
else
201-
indent(2, part, " ", raises)
202-
end
201+
indent(2, part, " ", raises, ": ", indent_all(3, e.message))
202+
else
203+
indent(2, part, " ", raises)
204+
end
203205
details << formatted_exeption
204206
end
205207
end

lib/wrong/config.rb

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,38 @@
1+
require "wrong/chunk"
2+
13
module Wrong
4+
def self.load_config
5+
settings = begin
6+
Chunk.read_here_or_higher(".wrong")
7+
rescue Errno::ENOENT => e
8+
# couldn't find it
9+
end
10+
Config.new settings
11+
end
12+
213
def self.config
3-
@config ||= Config.new
14+
@config ||= load_config
15+
end
16+
17+
def self.config=(new_config)
18+
@config = load_config
419
end
520

621
class Config < Hash
22+
def initialize(string = nil)
23+
if string
24+
instance_eval string.gsub(/^(.*=)/, "self.\\1")
25+
end
26+
end
27+
28+
def method_missing(name, value = true)
29+
name = name.to_s
30+
if name =~ /=$/
31+
name.gsub!(/=$/, '')
32+
end
33+
self[name.to_sym] = value
34+
end
35+
736
def alias_assert(method_name)
837
Wrong::Assert.send(:alias_method, method_name, :assert)
938
self.assert_method_names << method_name.to_sym unless self.assert_method_names.include?(method_name)

lib/wrong/sexp_ext.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ def to_ruby
1212

1313
# visit every node in the tree, including the root, that is an Sexp
1414
# todo: test
15-
def each_subexp(&block)
16-
yield self
15+
def each_subexp(include_root = true, &block)
16+
yield self if include_root
1717
each do |child|
1818
if child.is_a?(Sexp)
1919
child.each_subexp(&block)
@@ -42,7 +42,7 @@ def assertion
4242
private
4343
def nested_assertions
4444
assertions = []
45-
self.each_of_type(:iter) { |sexp| assertions << sexp if sexp.assertion? }
45+
self.each_subexp(false) { |sexp| assertions << sexp if sexp.assertion? }
4646
assertions
4747
end
4848

lib/wrong/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Wrong
2-
VERSION = "0.4.0" unless defined?(Wrong::VERSION)
2+
VERSION = "0.4.1" unless defined?(Wrong::VERSION)
33
end

test/assert_advanced_test.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ def assert_later(&p)
2020
end
2121
end
2222

23-
xit "can parse a here doc defined inside the block" do
23+
it "can parse a here doc defined inside the block" do
2424
# todo: test in Chunk too
25-
assert { "123\n456" == <<-TEXT
25+
assert { "123\n456\n" == <<-TEXT
2626
123
2727
456
2828
TEXT
2929
}
3030
end
3131

32-
xit "can parse a here doc defined outside the block" do
32+
it "can parse a here doc defined outside the block" do
3333
# todo: test in Chunk too
34-
assert { "123\n456" == <<-TEXT }
34+
assert { "123\n456\n" == <<-TEXT }
3535
123
3636
456
3737
TEXT

0 commit comments

Comments
 (0)