exemplor 2010.0.2 → 2010.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -6,20 +6,20 @@ An example-based test framework inspired by [testy](http://github.com/ahoward/te
6
6
  Simpler that BDD/TDD, fancier than a file with a bunch of print statements.
7
7
 
8
8
  Very tiny api. Here it is
9
-
9
+
10
10
  eg.helpers do
11
11
  ... your helpers ...
12
12
  end
13
-
13
+
14
14
  eg.setup { ... setup codez ... }
15
-
15
+
16
16
  eg "an example" do
17
17
  ... example code ...
18
18
  end
19
-
19
+
20
20
  eg "another example" do
21
21
  ... etc ...
22
- end
22
+ end
23
23
 
24
24
  The output is both human readable and machine parsable, which means you can test your tests.
25
25
 
@@ -29,29 +29,29 @@ Writing Examples
29
29
  See `examples.rb` and `/examples` for more examples.
30
30
 
31
31
  The simplest possible example:
32
-
32
+
33
33
  eg 'An example block without any checks prints the value of the block' do
34
34
  "foo"
35
35
  end
36
-
36
+
37
37
  #=>
38
-
38
+
39
39
  (i) An example block without any checks prints the value of the block: foo
40
40
 
41
41
  The 'i' stands for 'info' which means the example ran without error.
42
42
 
43
43
  Inspecting a few values, by default `Check` prints its argument and the value of the argument:
44
-
44
+
45
45
  eg 'Accessing different parts of an array' do
46
46
  list = [1, 2, 3]
47
47
  Check(list.first)
48
48
  Check(list[1])
49
49
  Check(list.last)
50
50
  end
51
-
51
+
52
52
  #=>
53
-
54
- (I) Accessing different parts of an array:
53
+
54
+ (I) Accessing different parts of an array:
55
55
  (i) list.first: 1
56
56
  (i) list[1]: 2
57
57
  (i) list.last: 3
@@ -66,31 +66,31 @@ Calls to `Check` with the same argument can be disambiguated with `[]`:
66
66
  list << 2
67
67
  Check(list.last)["after append"]
68
68
  end
69
-
69
+
70
70
  #=>
71
-
72
- (I) Array appending:
71
+
72
+ (I) Array appending:
73
73
  (i) list.last before append: 42
74
74
  (i) list.last after append: 2
75
75
 
76
76
  Errors are caught and reported nicely:
77
-
77
+
78
78
  eg 'Raising an error' do
79
- raise "boom!"
79
+ raise "boom!"
80
80
  end
81
81
 
82
82
  #=>
83
83
 
84
- (e) Raising an error:
84
+ (e) Raising an error:
85
85
  class: RuntimeError
86
86
  message: boom!
87
- backtrace:
87
+ backtrace:
88
88
  - examples/an_error.rb:4
89
89
  # ... more backtrace lines
90
90
 
91
91
  Once you're happy with how your code is running you can make some assertions about its behaviour by adding `is()` calls after your `Check()` statements:
92
-
93
-
92
+
93
+
94
94
  eg 'Asserting first is first' do
95
95
  list = [1, 2, 3]
96
96
  Check(list.first).is(1)
@@ -98,7 +98,7 @@ Once you're happy with how your code is running you can make some assertions abo
98
98
 
99
99
  #=>
100
100
 
101
- (s) Asserting first is first:
101
+ (s) Asserting first is first:
102
102
  (s) list.first: 1
103
103
 
104
104
  's' stands for 'success' and 'f' for failure:
@@ -110,8 +110,8 @@ Once you're happy with how your code is running you can make some assertions abo
110
110
 
111
111
  #=>
112
112
 
113
- (f) Assertion failure:
114
- (f) list.first:
113
+ (f) Assertion failure:
114
+ (f) list.first:
115
115
  expected: 2
116
116
  actual: 1
117
117
 
@@ -138,15 +138,15 @@ Running with `--list` or `-l` lists all examples:
138
138
  - called with some other arg (always interpreted as a regex)
139
139
 
140
140
  Otherwise the first argument is taken as a regex and only examples whose titles match are run:
141
-
141
+
142
142
  $> ruby examples.rb called
143
- (s) called with --list arg:
144
- (s) list:
143
+ (s) called with --list arg:
144
+ (s) list:
145
145
  - Modified env
146
146
  - Unmodified env
147
- (s) called with --l arg:
148
- (s) list:
147
+ (s) called with --l arg:
148
+ (s) list:
149
149
  - Modified env
150
150
  - Unmodified env
151
- (s) called with some other arg (always interpreted as a regex):
151
+ (s) called with some other arg (always interpreted as a regex):
152
152
  (s) tests_run: 1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2010.0.2
1
+ 2010.1.0
@@ -4,7 +4,7 @@ eg 'Some successes, then a fail' do
4
4
  list = [1, 2, 3]
5
5
  Check(list.first).is(1)
6
6
  Check(list[1]).is(2)
7
- Check(list.last).is(1)
7
+ Check(list.last).is(1) # fail!
8
8
  Check(list[2]).is(3) # would be successful but we never get here
9
9
  end
10
10
 
@@ -10,8 +10,8 @@ end
10
10
 
11
11
  __END__
12
12
 
13
- - name: Some successes, then a fail
14
- status: failure
13
+ - name: Some successes, then an info
14
+ status: info (with checks)
15
15
  result:
16
16
  - name: list.first
17
17
  status: success
@@ -0,0 +1,39 @@
1
+ module Exemplor
2
+ class Check
3
+
4
+ attr_reader :expectation, :value, :status
5
+
6
+ def initialize(name, value)
7
+ @name = name
8
+ @value = value
9
+ @status = :info
10
+ end
11
+
12
+ def [](disambiguate)
13
+ @disambiguate = disambiguate
14
+ self
15
+ end
16
+
17
+ def name
18
+ @name + (defined?(@disambiguate) ? " #{@disambiguate}" : '')
19
+ end
20
+
21
+ def is(expectation)
22
+ @expectation = expectation
23
+ @status = (value == expectation) ? :success : :failure
24
+ end
25
+
26
+ def success?
27
+ status == :success
28
+ end
29
+
30
+ def failure?
31
+ status == :failure
32
+ end
33
+
34
+ def info?
35
+ status == :info
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ # takes an array of command line arguments
2
+ def Exemplor(args)
3
+ args = args.dup
4
+ if args.delete('--list') || args.delete('-l')
5
+ Exemplor.examples.list(args)
6
+ else
7
+ exit Exemplor.examples.run(args)
8
+ end
9
+ end
@@ -0,0 +1,113 @@
1
+ module Exemplor
2
+
3
+ class ExampleEnv
4
+
5
+ class << self
6
+
7
+ alias_method :helpers, :class_eval
8
+ attr_accessor :setup_block
9
+
10
+ def setup(&blk) self.setup_block = blk end
11
+
12
+ # runs the block in the example environment, returns triple:
13
+ # [status, result, stderr]
14
+ def run(&code)
15
+ env = self.new
16
+ stderr = fake_stderr!
17
+ status, result = begin
18
+
19
+ env.instance_eval(&self.setup_block) if self.setup_block
20
+ value = env.instance_eval(&code)
21
+ result = env._status == :info ?
22
+ render_value(value) : render_checks(env._checks)
23
+ [env._status, result]
24
+
25
+ rescue Object => error
26
+ [:error, render_error(error)]
27
+ ensure
28
+ restore_stderr!
29
+ end
30
+ [status, result, stderr.rewind && stderr.read]
31
+ end
32
+
33
+ # tests are run with a fake stderr so warnings output can be assoicated
34
+ # with the specific test. this is still a little hokey and hard to test
35
+ # properly
36
+ def fake_stderr!
37
+ fake = StringIO.new
38
+ @real_stderr = $stderr
39
+ $stderr = fake
40
+ end
41
+
42
+ def restore_stderr!
43
+ $stderr = @real_stderr
44
+ end
45
+
46
+ # -- these "render" methods could probably be factored away
47
+
48
+ # yaml doesn't want to print a class
49
+ def render_value(value)
50
+ value.kind_of?(Class) ? value.inspect : value
51
+ end
52
+
53
+ def render_checks(checks)
54
+ failure = nil
55
+ out = []
56
+ checks.each do |check|
57
+ failure = check if check.failure?
58
+ break if failure
59
+ out << OrderedHash do |o|
60
+ o['name'] = check.name
61
+ o['status'] = check.status.to_s
62
+ o['result'] = render_value check.value
63
+ end
64
+ end
65
+ if failure
66
+ out << OrderedHash do |o|
67
+ o['name'] = failure.name
68
+ o['status'] = failure.status.to_s
69
+ o['expected'] = failure.expectation
70
+ o['actual'] = render_value failure.value
71
+ end
72
+ end
73
+ out
74
+ end
75
+
76
+ def render_error(error)
77
+ OrderedHash do |o|
78
+ o['class'] = error.class.name
79
+ o['message'] = error.message
80
+ o['backtrace'] = error.backtrace
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ attr_accessor :_checks
87
+
88
+ def initialize
89
+ @_checks = []
90
+ end
91
+
92
+ def Check(value)
93
+ file, line_number = caller.first.match(/^(.+):(\d+)/).captures
94
+ line = File.readlines(file)[line_number.to_i - 1].strip
95
+ name = line[/Check\((.+?)\)\s*($|#|\[|\.is.+)/,1]
96
+ check = Check.new(name, value)
97
+ _checks << check
98
+ check
99
+ end
100
+
101
+ def _status
102
+ (:info if _checks.empty?) ||
103
+ (:failure if _checks.any? { |c| c.failure? }) ||
104
+ (:success if _checks.all? { |c| c.success? }) ||
105
+ :infos
106
+ end
107
+
108
+ end
109
+
110
+ def environment
111
+ ExampleEnv
112
+ end
113
+ end
@@ -0,0 +1,62 @@
1
+ module Exemplor
2
+
3
+ def examples
4
+ @examples ||= Examples.new
5
+ end
6
+
7
+ # sets @example_file to first file that calls the `eg` method
8
+ def set_example_file_from(caller_trace)
9
+ @example_file ||= caller_trace.first.split(":").first
10
+ end
11
+
12
+ def example_file_set?
13
+ !!@example_file
14
+ end
15
+
16
+ def run_directly?
17
+ @example_file == $0
18
+ end
19
+
20
+ class ExampleDefinitionError < StandardError ; end
21
+
22
+ def make_example_name_from(caller_trace)
23
+ file, line_number = caller_trace.first.match(/^(.+):(\d+)/).captures
24
+ line = File.readlines(file)[line_number.to_i - 1].strip
25
+ name = line[/^eg\s*\{\s*(.+?)\s*\}$/,1]
26
+ raise Exemplor::ExampleDefinitionError, "example at #{caller_trace.first} has no name so must be on one line" if name.nil?
27
+ name
28
+ end
29
+
30
+ class Examples
31
+
32
+ def initialize
33
+ @examples = OrderedHash.new
34
+ end
35
+
36
+ def add(name, &body)
37
+ @examples[name] = body
38
+ end
39
+
40
+ def run(patterns)
41
+ fails = 0
42
+ # unoffically supports multiple patterns
43
+ patterns = Regexp.new(patterns.join('|'))
44
+ examples_to_run = @examples.select { |name,_| name =~ patterns }
45
+ return 0 if examples_to_run.empty?
46
+ examples_to_run.each do |name, code|
47
+ result = ResultPrinter.new(name, *ExampleEnv.run(&code))
48
+ fails +=1 if result.failure?
49
+ puts($stdout.tty? ? result.fancy : result.yaml)
50
+ end
51
+ (fails.to_f/examples_to_run.size)*100
52
+ end
53
+
54
+ def list(patterns)
55
+ patterns = Regexp.new(patterns.join('|'))
56
+ list = @examples.keys.select { |name| name =~ patterns }
57
+ print YAML.without_header(list)
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -1,305 +1,67 @@
1
+ # -- Implementation
2
+
1
3
  require 'orderedhash'
2
4
  require 'yaml'
3
5
 
4
- def OrderedHash(&blk)
5
- ohsh = OrderedHash.new
6
- blk.call(ohsh)
7
- ohsh
8
- end
9
-
10
- def YAML.without_header(obj)
11
- obj.to_yaml.match(/^--- \n?/).post_match
12
- end
13
-
14
- class String
15
- def indent
16
- self.split("\n").map { |line| ' ' + line }.join("\n")
17
- end
18
- end
19
-
20
6
  module Exemplor
21
7
 
22
- def self.version() File.read(__FILE__.sub('lib/exemplor.rb','VERSION')) end
23
-
24
- class ExampleDefinitionError < StandardError ; end
25
-
26
- class Check
27
-
28
- attr_reader :expectation, :value
29
-
30
- def initialize(name, value)
31
- @name = name
32
- @value = value
33
- end
34
-
35
- def [](disambiguate)
36
- @disambiguate = disambiguate
37
- self
38
- end
39
-
40
- def name
41
- @name + (defined?(@disambiguate) ? " #{@disambiguate}" : '')
42
- end
43
-
44
- def is(expectation)
45
- @expectation = expectation
46
- end
47
-
48
- def status
49
- return :info unless defined? @expectation
50
- @value == @expectation ? :success : :failure
51
- end
52
-
53
- def success?
54
- status == :success
55
- end
56
-
57
- def failure?
58
- status == :failure
59
- end
60
-
61
- def info?
62
- status == :info
63
- end
8
+ extend self
64
9
 
10
+ def path(rel_path)
11
+ File.join(File.dirname(__FILE__), rel_path)
65
12
  end
66
13
 
67
- class ResultPrinter
68
-
69
- attr_reader :name,:status,:result,:stderr
70
-
71
- def initialize(name,status,result,stderr)
72
- @name,@status,@result,@stderr = name,status,result,stderr
73
- end
74
-
75
- def failure?
76
- [:error,:failure].include?(self.status)
77
- end
78
-
79
- def yaml
80
- hsh = OrderedHash do |o|
81
- o['name'] = self.name
82
- o['status'] = case status = self.status
83
- when :info : 'info (no checks)'
84
- when :infos : 'info (with checks)'
85
- else ; status.to_s
86
- end
87
- o['result'] = self.result
88
- end
89
- YAML.without_header([hsh])# prints an array
90
- end
91
-
92
- def fancy
93
- # •∙ are inverted in my terminal font (Incosolata) so I'm swapping them
94
- require 'term/ansicolor'
95
- case status
96
- when :info : blue format_info("• #{name}", result)
97
- when :infos
98
- formatted_result = result.map do |r|
99
- # TODO: successful ones should be green
100
- format_info("#{{'success' => '✓', 'info' => '•' }[r['status']]} #{r['name']}", r['result']).rstrip
101
- end.join("\n")
102
- blue("∙ #{name}\n#{formatted_result.indent}")
103
- when :success
104
- green("✓ #{name}")
105
- when :failure
106
- # sooo hacky
107
- failure = result.find { |r| r['status'] == 'failure' }
108
- out = failure.dup
109
- out.delete('status')
110
- out.delete('name')
111
- color(:red, "✗ #{name} - #{failure['name']}\n#{YAML.without_header(out).indent}")
112
- when :error
113
- class_and_message = "#{result['class']} - #{result['message']}"
114
- backtrace = result['backtrace'].join("\n")
115
- color(:red, "☠ #{name}\n#{class_and_message.indent}\n#{backtrace.indent}")
116
- end
117
- end
118
-
119
- def blue(str) color(:blue,str) end
120
- def green(str) color(:green,str) end
121
-
122
- def color(color, str)
123
- [Term::ANSIColor.send(color), str, Term::ANSIColor.reset].join
124
- end
125
-
126
- # whatahack
127
- def format_info(str, result)
128
- YAML.without_header({'FANCY' => result}).sub('FANCY', str)
129
- end
130
-
14
+ def version
15
+ File.read(path('/../VERSION'))
131
16
  end
132
17
 
133
- class ExampleEnv
134
-
135
- class << self
136
-
137
- alias_method :helpers, :class_eval
138
- attr_accessor :setup_block
139
-
140
- def setup(&blk) self.setup_block = blk end
141
-
142
- # runs the block in the example environment, returns triple:
143
- # [status, result, stderr]
144
- def run(&code)
145
- env = self.new
146
- stderr = StringIO.new
147
- status, result = begin
148
- real_stderr = $stderr ; $stderr = stderr # swap stderr
149
-
150
- env.instance_eval(&self.setup_block) if self.setup_block
151
- value = env.instance_eval(&code)
152
- result = env._status == :info ?
153
- render_value(value) : render_checks(env._checks)
154
- [env._status, result]
155
-
156
- rescue Object => error
157
- [:error, render_error(error)]
158
- ensure
159
- $stderr = real_stderr # swap stderr back
160
- end
161
- [status, result, stderr.rewind && stderr.read]
162
- end
163
-
164
- # -- these "render" methods could probably be factored away
165
-
166
- # yaml doesn't want to print a class
167
- def render_value(value)
168
- value.kind_of?(Class) ? value.inspect : value
169
- end
170
-
171
- def render_checks(checks)
172
- failure = nil
173
- out = []
174
- checks.each do |check|
175
- failure = check if check.failure?
176
- break if failure
177
- out << OrderedHash do |o|
178
- o['name'] = check.name
179
- o['status'] = check.status.to_s
180
- o['result'] = render_value check.value
181
- end
182
- end
183
- if failure
184
- out << OrderedHash do |o|
185
- o['name'] = failure.name
186
- o['status'] = failure.status.to_s
187
- o['expected'] = failure.expectation
188
- o['actual'] = render_value failure.value
189
- end
190
- end
191
- out
192
- end
193
-
194
- def render_error(error)
195
- OrderedHash do |o|
196
- o['class'] = error.class.name
197
- o['message'] = error.message
198
- o['backtrace'] = error.backtrace
199
- end
200
- end
201
-
202
- end
203
-
204
- attr_accessor :_checks
205
-
206
- def initialize
207
- @_checks = []
208
- end
209
-
210
- def Check(value)
211
- file, line_number = caller.first.match(/^(.+):(\d+)/).captures
212
- line = File.readlines(file)[line_number.to_i - 1].strip
213
- name = line[/Check\((.+?)\)\s*($|#|\[|\.is.+)/,1]
214
- check = Check.new(name, value)
215
- _checks << check
216
- check
217
- end
218
-
219
- def _status
220
- (:info if _checks.empty?) ||
221
- (:failure if _checks.any? { |c| c.failure? }) ||
222
- (:success if _checks.all? { |c| c.success? }) ||
223
- :infos
224
- end
225
-
226
- end
227
-
228
- class Examples
229
-
230
- def initialize
231
- @examples = OrderedHash.new
232
- end
233
-
234
- def add(name, &body)
235
- @examples[name] = body
236
- end
237
-
238
- def run(patterns)
239
- fails = 0
240
- # unoffically supports multiple patterns
241
- patterns = Regexp.new(patterns.join('|'))
242
- examples_to_run = @examples.select { |name,_| name =~ patterns }
243
- return 0 if examples_to_run.empty?
244
- examples_to_run.each do |name, code|
245
- result = ResultPrinter.new(name, *ExampleEnv.run(&code))
246
- fails +=1 if result.failure?
247
- puts($stdout.tty? ? result.fancy : result.yaml)
248
- end
249
- (fails.to_f/examples_to_run.size)*100
250
- end
251
-
252
- def list(patterns)
253
- patterns = Regexp.new(patterns.join('|'))
254
- list = @examples.keys.select { |name| name =~ patterns }
255
- print YAML.without_header(list)
256
- end
257
-
258
- end
259
-
260
- class << self
261
-
262
- def examples
263
- @examples ||= Examples.new
264
- end
265
-
266
- def extract_example_file(caller_trace)
267
- @example_file ||= caller_trace.first.split(":").first
268
- end
269
-
270
- # attr_reader :example_file
18
+ end
271
19
 
272
- def run_directly?
273
- @example_file == $0
274
- end
20
+ require Exemplor.path('/ext')
21
+ require Exemplor.path('/checker')
22
+ require Exemplor.path('/result_printer')
23
+ require Exemplor.path('/environment')
24
+ require Exemplor.path('/examples')
25
+ require Exemplor.path('/command')
26
+
27
+ # -- Public API
28
+
29
+ # Interface for defining examples and configuring their environment.
30
+ #
31
+ # To define an example call eg with a name and block
32
+ #
33
+ # eg "yellling" do
34
+ # "hi".capitalize
35
+ # end
36
+ #
37
+ # `eg` can be called without a name if the entire call is on one line, in
38
+ # that case the code in the example is used as its name:
39
+ #
40
+ # eg { the_duck_swims_in_the_pond }
41
+ # same as:
42
+ # eg("the_duck_swims_in_the_pond") { the_duck_swims_in_the_pond }
43
+ #
44
+ # Call `eg` without args to configure the examples enviornment:
45
+ #
46
+ # eg.setup do
47
+ # # code here will run before each example
48
+ # end
49
+ #
50
+ # eg.helpers do
51
+ # # methods defined here can be called from inside an example
52
+ # end
53
+ #
54
+ def eg(name = nil, &example)
55
+ called_without_args = name.nil? && example.nil?
56
+ return Exemplor.environment if called_without_args
275
57
 
276
- end
58
+ Exemplor.set_example_file_from caller unless Exemplor.example_file_set?
277
59
 
278
- end
60
+ called_without_explicit_name = name.nil? && !example.nil?
61
+ name = Exemplor.make_example_name_from caller if called_without_explicit_name
279
62
 
280
- # Defines an example. After definition, an example is an entry in the
281
- # Examples.examples ordered hash, the key is the name, the body is the example
282
- # code
283
- def eg(name = nil, &example)
284
- return Exemplor::ExampleEnv if name.nil? && example.nil?
285
- Exemplor.extract_example_file caller # only runs once
286
- if name.nil?
287
- file, line_number = caller.first.match(/^(.+):(\d+)/).captures
288
- line = File.readlines(file)[line_number.to_i - 1].strip
289
- name = line[/^eg\s*\{\s*(.+?)\s*\}$/,1] if name.nil?
290
- raise Exemplor::ExampleDefinitionError, "example at #{caller.first} has no name so must be on one line" if name.nil?
291
- end
292
63
  Exemplor.examples.add(name, &example)
293
64
  end
294
65
 
295
- # Parses the command line args and either runs or lists the examples.
296
- at_exit do
297
- if Exemplor.run_directly?
298
- args = ARGV.dup
299
- if args.delete('--list') || args.delete('-l')
300
- Exemplor.examples.list(args)
301
- else
302
- exit Exemplor.examples.run(args)
303
- end
304
- end
305
- end
66
+ # Command line interface
67
+ at_exit { Exemplor(ARGV) if Exemplor.run_directly? }
@@ -0,0 +1,15 @@
1
+ def OrderedHash(&blk)
2
+ ohsh = OrderedHash.new
3
+ blk.call(ohsh)
4
+ ohsh
5
+ end
6
+
7
+ def YAML.without_header(obj)
8
+ obj.to_yaml.match(/^--- \n?/).post_match
9
+ end
10
+
11
+ class String
12
+ def indent
13
+ self.split("\n").map { |line| ' ' + line }.join("\n")
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ module Exemplor
2
+ class ResultPrinter
3
+
4
+ attr_reader :name,:status,:result,:stderr
5
+
6
+ def initialize(name,status,result,stderr)
7
+ @name,@status,@result,@stderr = name,status,result,stderr
8
+ end
9
+
10
+ def failure?
11
+ [:error,:failure].include?(self.status)
12
+ end
13
+
14
+ def yaml
15
+ hsh = OrderedHash do |o|
16
+ o['name'] = self.name
17
+ o['status'] = case status = self.status
18
+ when :info : 'info (no checks)'
19
+ when :infos : 'info (with checks)'
20
+ else ; status.to_s
21
+ end
22
+ o['result'] = self.result
23
+ end
24
+ YAML.without_header([hsh])# prints an array
25
+ end
26
+
27
+ def fancy
28
+ # •∙ are inverted in my terminal font (Incosolata) so I'm swapping them
29
+ require 'term/ansicolor'
30
+ case status
31
+ when :info : blue format_info("• #{name}", result)
32
+ when :infos
33
+ formatted_result = result.map do |r|
34
+ # TODO: successful ones should be green
35
+ format_info("#{{'success' => '✓', 'info' => '•' }[r['status']]} #{r['name']}", r['result']).rstrip
36
+ end.join("\n")
37
+ blue("∙ #{name}\n#{formatted_result.indent}")
38
+ when :success
39
+ green("✓ #{name}")
40
+ when :failure
41
+ # sooo hacky
42
+ failure = result.find { |r| r['status'] == 'failure' }
43
+ out = failure.dup
44
+ out.delete('status')
45
+ out.delete('name')
46
+ color(:red, "✗ #{name} - #{failure['name']}\n#{YAML.without_header(out).indent}")
47
+ when :error
48
+ class_and_message = "#{result['class']} - #{result['message']}"
49
+ backtrace = result['backtrace'].join("\n")
50
+ color(:red, "☠ #{name}\n#{class_and_message.indent}\n#{backtrace.indent}")
51
+ end
52
+ end
53
+
54
+ def blue(str) color(:blue,str) end
55
+ def green(str) color(:green,str) end
56
+
57
+ def color(color, str)
58
+ [Term::ANSIColor.send(color), str, Term::ANSIColor.reset].join
59
+ end
60
+
61
+ # whatahack
62
+ def format_info(str, result)
63
+ YAML.without_header({'FANCY' => result}).sub('FANCY', str)
64
+ end
65
+
66
+ end
67
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 2010
7
+ - 1
7
8
  - 0
8
- - 2
9
- version: 2010.0.2
9
+ version: 2010.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Myles Byrne
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-27 00:00:00 -05:00
17
+ date: 2010-03-31 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -77,7 +77,13 @@ files:
77
77
  - examples/ten_percent_failures.rb
78
78
  - examples/with_checks.rb
79
79
  - examples/with_setup.rb
80
+ - lib/checker.rb
81
+ - lib/command.rb
82
+ - lib/environment.rb
83
+ - lib/examples.rb
80
84
  - lib/exemplor.rb
85
+ - lib/ext.rb
86
+ - lib/result_printer.rb
81
87
  has_rdoc: true
82
88
  homepage: http://github.com/quackingduck/exemplor
83
89
  licenses: []