exemplor 2010.0.2 → 2010.1.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.
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: []