kintama 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -149,21 +149,19 @@ You can also add (several) global `setup` and `teardown` blocks, which will be r
149
149
  Helpers
150
150
  -------
151
151
 
152
- If you want to make methods available in your tests, you have a few options. You can define them inline:
152
+ If you want to make methods available in your tests, you can define them thusly:
153
153
 
154
154
  context "my face" do
155
155
  should "be awesome" do
156
156
  assert_equal "awesome", create_face.status
157
157
  end
158
158
 
159
- helpers do
160
- def create_face
161
- Face.new(:name => "james", :eyes => "blue", :something => "something else")
162
- end
159
+ def create_face
160
+ Face.new(:name => "james", :eyes => "blue", :something => "something else")
163
161
  end
164
162
  end
165
163
 
166
- Ideally I would've liked to make this syntatically similar to defining a private method in a class, but for various reasons that was not possible. Anyway, your other options are including a module:
164
+ Your other options are including a module:
167
165
 
168
166
  module FaceHelper
169
167
  def create_face
@@ -180,33 +178,71 @@ Ideally I would've liked to make this syntatically similar to defining a private
180
178
 
181
179
  Or, if you're going to use the method in all your tests, you can add the module globally:
182
180
 
183
- Kintama.add FaceHelper
181
+ Kintama.include FaceHelper
184
182
 
185
- or just define the method globally:
186
183
 
187
- Kintama.add do
188
- def create_face
189
- # etc ...
190
- end
191
- end
184
+ Extending
185
+ ---------
192
186
 
193
- ### Aside: what happens if you do define a method in the context?
187
+ If you want to add behaviour to Kintama itself (rather than to tests),
188
+ you can use extend:
194
189
 
195
- It becomes available within context (and subcontext) definitions. Here's an example:
190
+ module Doing
191
+ def doing(&block)
192
+ @doing = block
193
+ end
196
194
 
197
- context "blah" do
198
- def generate_tests_for(thing)
199
- it "should work with #{thing}" do
200
- assert thing.works
195
+ def should_change(&block)
196
+ doing_block = @doing
197
+ should "change something" do
198
+ previous_value = instance_eval(&block)
199
+ instance_eval(&doing_block)
200
+ subsequent_value = instance_eval(&block)
201
+ assert subsequent_value != previous_value, "it didn't change"
201
202
  end
202
203
  end
203
204
 
204
- [Monkey.new, Tiger.new].each do |t|
205
- generate_tests_for(t)
205
+ def expect(name, &block)
206
+ doing_block = @doing
207
+ test "expects #{name}" do
208
+ instance_eval(&block)
209
+ instance_eval(&doing_block)
210
+ end
206
211
  end
207
212
  end
208
213
 
209
- This is a bit like defining a 'class method' in a `TestCase` and then being able to call it to generate contexts or tests within that `TestCase`. It's not that tricky once you get used to it.
214
+ class Thing
215
+ attr_reader :total
216
+ def initialize
217
+ @total = 0
218
+ end
219
+ def increment
220
+ @total += 1
221
+ end
222
+ end
223
+
224
+ context "Given something" do
225
+ extend Doing
226
+
227
+ setup { @thing = Thing.new }
228
+
229
+ doing { @thing.increment }
230
+
231
+ should_change { @thing.total }
232
+
233
+ # NOTE: this assumes Mocha is present
234
+ expect("increment to be called} { @thing.expects(:increment) }
235
+
236
+ # etc...
237
+ end
238
+
239
+ As you can see, extending makes the method available at the context
240
+ level, so it can be used to construct tests, new context types, and so
241
+ on. This is really where the exciting stuff is.
242
+
243
+ Oh, and of course, behaviour can be added to all tests as above:
244
+
245
+ Kintama.extend Doing
210
246
 
211
247
 
212
248
  And now, the more experimental stuff
@@ -244,4 +280,4 @@ Well... TO BE CONTINUED.
244
280
  [Tryouts]: https://github.com/delano/tryouts
245
281
  [Zebra]: https://github.com/jamesgolick/zebra
246
282
  [Shindo]: https://github.com/geemus/shindo
247
- [Exemplor]: https://github.com/quackingduck/exemplor
283
+ [Exemplor]: https://github.com/quackingduck/exemplor
@@ -3,6 +3,7 @@ module Kintama
3
3
  autoload :Context, 'kintama/context'
4
4
  autoload :Test, 'kintama/test'
5
5
  autoload :TestFailure, 'kintama/test'
6
+ autoload :Reporter, 'kintama/reporter'
6
7
  autoload :Runner, 'kintama/runner'
7
8
  autoload :Assertions, 'kintama/assertions'
8
9
 
@@ -63,7 +64,7 @@ module Kintama
63
64
  # line or from within an editor
64
65
  def add_exit_hook
65
66
  return if @__added_exit_hook
66
- at_exit { exit(Runner.default.run ? 0 : 1) }
67
+ at_exit { exit(Runner.from_args(ARGV, Kintama.default_context.subcontexts).run ? 0 : 1) }
67
68
  @__added_exit_hook = true
68
69
  end
69
70
 
@@ -18,6 +18,7 @@ module Kintama
18
18
  c = Class.new(parent)
19
19
  c.send(:include, Kintama::Context)
20
20
  c.name = name.to_s
21
+ c.definition = caller.find { |line| line =~ /^#{block.__file__}:(\d+)$/ }
21
22
  c.class_eval(&block)
22
23
  c
23
24
  end
@@ -45,7 +46,7 @@ module Kintama
45
46
  # redefine setup for the current set of blocks
46
47
  blocks = self.setup_blocks
47
48
  define_method(:setup) do
48
- super
49
+ super()
49
50
  blocks.each { |b| instance_eval(&b) }
50
51
  end
51
52
  end
@@ -59,10 +60,28 @@ module Kintama
59
60
  blocks = self.teardown_blocks
60
61
  define_method(:teardown) do
61
62
  blocks.each { |b| instance_eval(&b) }
62
- super
63
+ super()
63
64
  end
64
65
  end
65
66
 
67
+ def on_start_blocks
68
+ @on_start_blocks ||= []
69
+ end
70
+
71
+ def on_start(&block)
72
+ self.on_start_blocks << block
73
+ end
74
+ alias_method :before_all, :on_start
75
+
76
+ def on_finish_blocks
77
+ @on_finish_blocks ||= []
78
+ end
79
+
80
+ def on_finish(&block)
81
+ self.on_finish_blocks << block
82
+ end
83
+ alias_method :after_all, :on_finish
84
+
66
85
  # Defines the subject of any matcher-based tests.
67
86
  def subject(&block)
68
87
  define_method(:subject, &block)
@@ -73,6 +92,7 @@ module Kintama
73
92
  c = Class.new(self)
74
93
  c.send(:include, Kintama::Test)
75
94
  c.name = name
95
+ c.definition = caller.find { |line| line =~ /^[^:]+:(\d+)$/ }
76
96
  c.block = block if block_given?
77
97
  end
78
98
 
@@ -121,6 +141,10 @@ module Kintama
121
141
  children.select { |c| c.is_a_context? }.sort_by { |s| s.name }
122
142
  end
123
143
 
144
+ def all_runnables
145
+ tests + subcontexts + subcontexts.map { |s| s.all_runnables }.flatten
146
+ end
147
+
124
148
  # Returns true if this context has no known failed tests.
125
149
  def passed?
126
150
  failures.empty?
@@ -133,7 +157,7 @@ module Kintama
133
157
  end
134
158
 
135
159
  def pending
136
- tests.select { |t| t.pending? } + subcontexts.map { |s| s.pending }.flatten
160
+ ran_tests.select { |t| t.pending? } + subcontexts.map { |s| s.pending }.flatten
137
161
  end
138
162
 
139
163
  def [](name)
@@ -164,15 +188,37 @@ module Kintama
164
188
 
165
189
  # Runs all tests in this context and any subcontexts.
166
190
  # Returns true if all tests passed; otherwise false
167
- def run(runner=nil)
191
+ def run(reporter=nil)
192
+ run_tests(tests, true, reporter)
193
+ end
194
+
195
+ # Run a specific set of tests using the given the reporter
196
+ def run_tests(test_set, run_subcontexts, reporter)
168
197
  @ran_tests = []
169
- runner.context_started(self) if runner
170
- tests.each { |t| instance = t.new; instance.run(runner); ran_tests << instance }
171
- subcontexts.each { |s| s.run(runner) }
172
- runner.context_finished(self) if runner
198
+ reporter.context_started(self) if reporter
199
+ on_start_blocks.each { |b| instance_eval(&b) }
200
+ test_set.each { |t| instance = t.new; instance.run(reporter); ran_tests << instance }
201
+ subcontexts.each { |s| s.run(reporter) } if run_subcontexts
202
+ on_finish_blocks.each { |b| instance_eval(&b) }
203
+ reporter.context_finished(self) if reporter
173
204
  passed?
174
205
  end
175
206
 
207
+ def runnable_on_line(line)
208
+ sorted_runnables = all_runnables.delete_if { |r| r.line_defined.nil? }.sort_by { |r| r.line_defined }
209
+ if line >= sorted_runnables.first.line_defined
210
+ next_runnable = sorted_runnables.find { |r| r.line_defined > line }
211
+ index = sorted_runnables.index(next_runnable)
212
+ if index != nil && index > 0
213
+ sorted_runnables[index-1]
214
+ else
215
+ sorted_runnables.last
216
+ end
217
+ else
218
+ nil
219
+ end
220
+ end
221
+
176
222
  private
177
223
 
178
224
  def de_methodize(name)
@@ -0,0 +1,12 @@
1
+ require "mocha"
2
+
3
+ Kintama.include Mocha::API
4
+ Kintama.teardown do
5
+ begin
6
+ mocha_verify
7
+ rescue Mocha::ExpectationError => e
8
+ raise e
9
+ ensure
10
+ mocha_teardown
11
+ end
12
+ end
@@ -0,0 +1,146 @@
1
+ module Kintama
2
+ class Reporter
3
+
4
+ def self.default
5
+ Verbose.new(colour=$stdin.tty?)
6
+ end
7
+
8
+ class Base
9
+ attr_reader :runner
10
+
11
+ def initialize
12
+ @test_count = 0
13
+ end
14
+
15
+ def started(runner)
16
+ @runner = runner
17
+ @start = Time.now
18
+ end
19
+
20
+ def context_started(context)
21
+ end
22
+
23
+ def context_finished(context)
24
+ end
25
+
26
+ def test_started(test)
27
+ @test_count += 1
28
+ end
29
+
30
+ def test_finished(test)
31
+ end
32
+
33
+ def finished
34
+ @duration = Time.now - @start
35
+ end
36
+
37
+ def test_summary
38
+ output = ["#{@test_count} tests", "#{runner.failures.length} failures"]
39
+ output << "#{runner.pending.length} pending" if runner.pending.any?
40
+ output.join(", ") + " (#{format("%.4f", @duration)} seconds)"
41
+ end
42
+
43
+ def show_results
44
+ puts
45
+ puts test_summary
46
+ puts "\n" + failure_messages.join("\n\n") if runner.failures.any?
47
+ end
48
+
49
+ def failure_messages
50
+ x = 0
51
+ runner.failures.map do |test|
52
+ x += 1
53
+ "#{x}) #{test.full_name}:\n #{test.failure_message}"
54
+ end
55
+ end
56
+
57
+ def character_status_of(test)
58
+ character = if test.pending?
59
+ 'P'
60
+ elsif test.passed?
61
+ '.'
62
+ else
63
+ 'F'
64
+ end
65
+ end
66
+ end
67
+
68
+ class Inline < Base
69
+ def test_finished(test)
70
+ print character_status_of(test)
71
+ end
72
+
73
+ def show_results
74
+ puts
75
+ super
76
+ end
77
+ end
78
+
79
+ class Verbose < Base
80
+ INDENT = " "
81
+
82
+ def initialize(colour=false)
83
+ super()
84
+ @colour = colour
85
+ @current_indent_level = 0
86
+ end
87
+
88
+ def indent
89
+ INDENT * @current_indent_level
90
+ end
91
+
92
+ def context_started(context)
93
+ print indent + context.name + "\n" if context.name
94
+ @current_indent_level += 1
95
+ end
96
+
97
+ def context_finished(context)
98
+ @current_indent_level -= 1
99
+ puts if @current_indent_level == 0 && context != runner.runnables.last
100
+ end
101
+
102
+ def test_started(test)
103
+ super
104
+ print indent + test.name + ": " unless @colour
105
+ end
106
+
107
+ def test_finished(test)
108
+ if @colour
109
+ puts coloured_name(test)
110
+ else
111
+ puts character_status_of(test)
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def coloured_name(test)
118
+ test_name = indent + test.name
119
+ if test.pending?
120
+ yellow(test_name)
121
+ elsif test.passed?
122
+ green(test_name)
123
+ else
124
+ red(test_name)
125
+ end
126
+ end
127
+
128
+ def color(text, color_code)
129
+ "#{color_code}#{text}\e[0m"
130
+ end
131
+
132
+ def green(text)
133
+ color(text, "\e[32m")
134
+ end
135
+
136
+ def red(text)
137
+ color(text, "\e[31m")
138
+ end
139
+
140
+ def yellow(text)
141
+ color(text, "\e[33m")
142
+ end
143
+ end
144
+
145
+ end
146
+ end
@@ -1,10 +1,10 @@
1
1
  module Kintama
2
2
  class Runnable
3
3
  class << self
4
- attr_accessor :name
4
+ attr_accessor :name, :definition
5
5
 
6
6
  def to_s
7
- "<#{name} #{super}/#{is_a_test? ? 'Test' : 'Context'}>"
7
+ "<#{is_a_test? ? 'Test' : 'Context'}:#{name}>"
8
8
  end
9
9
 
10
10
  def is_a_test?
@@ -28,6 +28,10 @@ module Kintama
28
28
  nil
29
29
  end
30
30
  end
31
+
32
+ def line_defined
33
+ definition ? definition.split(":").last.to_i : nil
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -1,153 +1,77 @@
1
1
  module Kintama
2
2
  class Runner
3
-
4
- def self.default
5
- Verbose.new(*Kintama.default_context.subcontexts)
3
+ def self.from_args(args, runnables)
4
+ if args[0] == "--line"
5
+ Kintama::Runner::Line.new(args[1], runnables)
6
+ else
7
+ Kintama::Runner::Default.new(runnables)
8
+ end
6
9
  end
7
10
 
8
11
  class Base
9
- def initialize(*contexts)
10
- @contexts = contexts
11
- end
12
+ attr_reader :runnables
12
13
 
13
- def run(colour=$stdin.tty?)
14
- @colour = colour
15
- @test_count = 0
16
- start = Time.now
17
- @contexts.each do |c|
18
- @current_indent = -1
19
- c.run(self)
20
- puts if c != @contexts.last
21
- end
22
- @duration = Time.now - start
23
- show_results
24
- passed?
14
+ def initialize(runnables)
15
+ @runnables = runnables
25
16
  end
26
17
 
27
- def context_started(context); end
28
- def context_finished(context); end
29
- def test_started(test)
30
- @test_count += 1
18
+ def run(reporter=Kintama::Reporter.default, args=ARGV)
19
+ reporter.started(self)
20
+ @ran_runnables = run_tests(reporter)
21
+ reporter.finished
22
+ reporter.show_results
23
+ passed?
31
24
  end
32
- def test_finished(test); end
33
25
 
34
26
  def passed?
35
27
  failures.empty?
36
28
  end
37
29
 
38
30
  def failures
39
- @contexts.map { |c| c.failures }.flatten
31
+ @ran_runnables.map { |r| r.failures }.flatten
40
32
  end
41
33
 
42
34
  def pending
43
- @contexts.map { |c| c.pending }.flatten
44
- end
45
-
46
- def test_summary
47
- output = ["#{@test_count} tests", "#{failures.length} failures"]
48
- output << "#{pending.length} pending" if pending.any?
49
- output.join(", ") + " (#{format("%.4f", @duration)} seconds)"
50
- end
51
-
52
- def show_results
53
- puts
54
- puts test_summary
55
- puts "\n" + failure_messages.join("\n\n") if failures.any?
56
- end
57
-
58
- def failure_messages
59
- x = 0
60
- failures.map do |test|
61
- x += 1
62
- "#{x}) #{test.full_name}:\n #{test.failure_message}"
63
- end
64
- end
65
-
66
- def character_status_of(test)
67
- character = if test.pending?
68
- 'P'
69
- elsif test.passed?
70
- '.'
71
- else
72
- 'F'
73
- end
35
+ @ran_runnables.map { |r| r.pending }.flatten
74
36
  end
75
37
  end
76
38
 
77
- class Inline < Base
78
- def test_finished(test)
79
- print character_status_of(test)
80
- end
81
-
82
- def show_results
83
- puts
84
- super
85
- end
86
- end
87
-
88
- class Verbose < Base
89
- INDENT = " "
90
-
91
- def initialize(*contexts)
92
- super
93
- @current_indent = -1
94
- end
95
-
96
- def indent
97
- INDENT * @current_indent
98
- end
99
-
100
- def context_started(context)
101
- @current_indent += 1
102
- print indent + context.name + "\n" if context.name
103
- end
104
-
105
- def context_finished(context)
106
- @current_indent -= 1
107
- end
108
-
109
- def test_started(test)
110
- super
111
- print indent + INDENT + test.name + ": " unless @colour
112
- end
113
-
114
- def test_finished(test)
115
- if @colour
116
- puts coloured_name(test)
117
- else
118
- puts character_status_of(test)
39
+ # Runs every test provided as part of the constructor
40
+ class Default < Base
41
+ def run_tests(reporter)
42
+ @runnables.each do |r|
43
+ r.run(reporter)
119
44
  end
45
+ @runnables
120
46
  end
47
+ end
121
48
 
122
- private
123
-
124
- def coloured_name(test)
125
- test_name = indent + INDENT + test.name
126
- if test.pending?
127
- yellow(test_name)
128
- elsif test.passed?
129
- green(test_name)
130
- else
131
- red(test_name)
49
+ # Runs only the test or context which contains the provided line
50
+ class Line < Base
51
+ def initialize(line, runnables)
52
+ super(runnables)
53
+ @line = line.to_i
54
+ end
55
+
56
+ def run_tests(reporter)
57
+ runnable = @runnables.map { |r| r.runnable_on_line(@line) }.compact.first
58
+ if runnable
59
+ if runnable.is_a_test?
60
+ heirarchy = []
61
+ parent = runnable.parent.parent
62
+ until parent == Kintama.default_context do
63
+ heirarchy.unshift parent
64
+ parent = parent.parent
65
+ end
66
+ heirarchy.each { |context| reporter.context_started(context) }
67
+ runnable.parent.run_tests([runnable], false, reporter)
68
+ [runnable.parent]
69
+ else
70
+ runnable.run(reporter)
71
+ [runnable]
72
+ end
132
73
  end
133
74
  end
134
-
135
- def color(text, color_code)
136
- "#{color_code}#{text}\e[0m"
137
- end
138
-
139
- def green(text)
140
- color(text, "\e[32m")
141
- end
142
-
143
- def red(text)
144
- color(text, "\e[31m")
145
- end
146
-
147
- def yellow(text)
148
- color(text, "\e[33m")
149
- end
150
75
  end
151
-
152
76
  end
153
77
  end
@@ -19,9 +19,9 @@ module Kintama
19
19
  base.send :attr_reader, :failure
20
20
  end
21
21
 
22
- def run(runner=nil)
22
+ def run(reporter=nil)
23
23
  @failure = nil
24
- runner.test_started(self) if runner
24
+ reporter.test_started(self) if reporter
25
25
  unless pending?
26
26
  begin
27
27
  setup
@@ -36,7 +36,7 @@ module Kintama
36
36
  end
37
37
  end
38
38
  end
39
- runner.test_finished(self) if runner
39
+ reporter.test_finished(self) if reporter
40
40
  passed?
41
41
  end
42
42
 
@@ -57,12 +57,12 @@ module Kintama
57
57
  end
58
58
 
59
59
  def failure_message
60
- "#{@failure.message} (at #{failure_line})"
60
+ "#{@failure.message}\n#{failure_backtrace}"
61
61
  end
62
62
 
63
- def failure_line
63
+ def failure_backtrace
64
64
  base_dir = File.expand_path("../..", __FILE__)
65
- @failure.backtrace.find { |line| File.expand_path(line).index(base_dir).nil? }
65
+ @failure.backtrace.select { |line| File.expand_path(line).index(base_dir).nil? }.map { |l| " "*4 + File.expand_path(l) }.join("\n")
66
66
  end
67
67
  end
68
68
  end
@@ -0,0 +1,120 @@
1
+ require "test_helper"
2
+
3
+ class LineBasedRunningTest < Test::Unit::TestCase
4
+ def test_should_be_able_to_run_the_test_by_giving_the_line_number_the_test_is_defined_on
5
+ test_file = %{
6
+ context "given a thing" do
7
+ should "run this test" do
8
+ assert true
9
+ end
10
+ should "not run this test" do
11
+ flunk
12
+ end
13
+ end}
14
+ assert_match /^#{passing("should run this test")}\n\n1 tests/, run_test(test_file, "--line 3")
15
+ assert_match /^1 tests, 0 failures/, run_test(test_file, "--line 3")
16
+
17
+ assert_match /^#{failing("should not run this test")}\n\n1 tests/, run_test(test_file, "--line 6")
18
+ assert_match /^1 tests, 1 failures/, run_test(test_file, "--line 6")
19
+ end
20
+
21
+ def test_should_be_able_to_run_the_test_by_giving_the_line_number_within_the_test_definition
22
+ test_file = %{
23
+ context "given a thing" do
24
+ should "run this test" do
25
+ assert true
26
+ end
27
+ should "not run this test" do
28
+ flunk
29
+ end
30
+ end}
31
+ assert_match /^#{passing("should run this test")}\n\n1 tests/, run_test(test_file, "--line 4")
32
+ assert_match /^#{failing("should not run this test")}\n\n1 tests/, run_test(test_file, "--line 7")
33
+ end
34
+
35
+ def test_should_be_able_to_run_all_tests_within_a_context_when_line_falls_on_a_context
36
+ test_file = %{
37
+ context "given a thing" do
38
+ should "not run this test" do
39
+ flunk
40
+ end
41
+ context "and another thing" do
42
+ should "run this test" do
43
+ end
44
+ should "run this test too" do
45
+ end
46
+ end
47
+ end}
48
+ assert_match /#{passing("should run this test")}\n#{passing("should run this test too")}\n\n\n2 tests/, run_test(test_file, "--line 6")
49
+ end
50
+
51
+ def test_should_be_able_to_run_a_test_defined_in_a_second_top_level_context
52
+ test_file = %{
53
+ context "given a thing" do
54
+ should "not run this test" do
55
+ flunk
56
+ end
57
+ end
58
+ context "and another thing" do
59
+ should "run this test" do
60
+ end
61
+ end}
62
+ assert_match /#{passing("should run this test")}\n\n\n1 tests/, run_test(test_file, "--line 8")
63
+ end
64
+
65
+ def test_should_print_out_the_full_nested_test_name
66
+ test_file = %{
67
+ context "given a test" do
68
+ context "that is nested deeply" do
69
+ should "print the full nesting name" do
70
+ end
71
+ end
72
+ end}
73
+ assert_match /given a test\n that is nested deeply\n/, run_test(test_file, "--line 5")
74
+ end
75
+
76
+ def test_should_not_show_pending_tests_in_the_same_context_as_pending_when_not_targeted
77
+ test_file = %{
78
+ context "given a context with a pending test" do
79
+ should "only show the run test" do
80
+ end
81
+ should "ignore the pending test"
82
+ end}
83
+ assert_no_match /1 pending/, run_test(test_file, "--line 3")
84
+ end
85
+
86
+ private
87
+
88
+ def write_test(string, path)
89
+ f = File.open(path, "w") do |f|
90
+ f.puts %|$LOAD_PATH.unshift "#{File.expand_path("../../lib", __FILE__)}"; require "kintama"|
91
+ f.puts string.strip
92
+ end
93
+ end
94
+
95
+ def run_test(test_content, options)
96
+ path = "/tmp/kintama_tmp_test.rb"
97
+ write_test(test_content.strip, path)
98
+ prev = ENV["KINTAMA_EXPLICITLY_DONT_RUN"]
99
+ ENV["KINTAMA_EXPLICITLY_DONT_RUN"] = nil
100
+ output = `ruby #{path} #{options}`
101
+ ENV["KINTAMA_EXPLICITLY_DONT_RUN"] = prev
102
+ output
103
+ end
104
+
105
+ def passing(test_name)
106
+ if $stdin.tty?
107
+ /\e\[32m\s*#{test_name}\e\[0m/
108
+ else
109
+ /\s*#{test_name}: ./
110
+ end
111
+ end
112
+
113
+ def failing(test_name)
114
+ if $stdin.tty?
115
+ /\e\[31m\s*#{test_name}\e\[0m/
116
+ else
117
+ /\s*#{test_name}: F/
118
+ end
119
+ end
120
+ end
@@ -1,6 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
- class BaseRunnerTest < Test::Unit::TestCase
3
+ class BaseReporterTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @reporter = Kintama::Reporter::Base.new
7
+ end
4
8
 
5
9
  def test_assert_output_works
6
10
  assert_output("yes\n") do
@@ -15,8 +19,8 @@ class BaseRunnerTest < Test::Unit::TestCase
15
19
  end
16
20
  end
17
21
  r = runner(c)
18
- capture_stdout { r.run }
19
- assert_match /^1 tests, 0 failures/, r.test_summary
22
+ capture_stdout { r.run(@reporter) }
23
+ assert_match /^1 tests, 0 failures/, @reporter.test_summary
20
24
  end
21
25
 
22
26
  def test_should_print_out_summary_when_multiple_tests_pass
@@ -29,8 +33,8 @@ class BaseRunnerTest < Test::Unit::TestCase
29
33
  end
30
34
  end
31
35
  r = runner(c)
32
- capture_stdout { r.run }
33
- assert_match /^2 tests, 0 failures/, r.test_summary
36
+ capture_stdout { r.run(@reporter) }
37
+ assert_match /^2 tests, 0 failures/, @reporter.test_summary
34
38
  end
35
39
 
36
40
  def test_should_print_out_summary_when_a_pending_test_exists
@@ -41,8 +45,8 @@ class BaseRunnerTest < Test::Unit::TestCase
41
45
  should "not be implemented yet"
42
46
  end
43
47
  r = runner(c)
44
- capture_stdout { r.run }
45
- assert_match /^2 tests, 0 failures, 1 pending/, r.test_summary
48
+ capture_stdout { r.run(@reporter) }
49
+ assert_match /^2 tests, 0 failures, 1 pending/, @reporter.test_summary
46
50
  end
47
51
 
48
52
  def test_should_print_out_failure_details_if_tests_fail
@@ -55,8 +59,8 @@ class BaseRunnerTest < Test::Unit::TestCase
55
59
  end
56
60
  end
57
61
  r = runner(c)
58
- capture_stdout { r.run }
59
- assert_match /^1\) given something should fail:\n flunked\./, r.failure_messages[0]
62
+ capture_stdout { r.run(@reporter) }
63
+ assert_match /^1\) given something should fail:\n flunked\./, @reporter.failure_messages[0]
60
64
  end
61
65
 
62
66
  def test_should_print_out_the_test_duration
@@ -66,8 +70,8 @@ class BaseRunnerTest < Test::Unit::TestCase
66
70
  end
67
71
  end
68
72
  r = runner(c)
69
- capture_stdout { r.run }
70
- assert_match /^1 tests, 0 failures \(0\.\d+ seconds\)/, r.test_summary
73
+ capture_stdout { r.run(@reporter) }
74
+ assert_match /^1 tests, 0 failures \(0\.\d+ seconds\)/, @reporter.test_summary
71
75
  end
72
76
 
73
77
  def test_should_be_able_to_run_tests_from_several_contexts
@@ -82,8 +86,8 @@ class BaseRunnerTest < Test::Unit::TestCase
82
86
  end
83
87
  end
84
88
  r = runner(c1, c2)
85
- capture_stdout { r.run }
86
- assert_match /^2 tests, 0 failures/, r.test_summary
89
+ capture_stdout { r.run(@reporter) }
90
+ assert_match /^2 tests, 0 failures/, @reporter.test_summary
87
91
  end
88
92
 
89
93
  def test_should_return_true_if_all_tests_pass
@@ -92,7 +96,7 @@ class BaseRunnerTest < Test::Unit::TestCase
92
96
  should("also pass") { assert true }
93
97
  end
94
98
  capture_stdout do
95
- assert_equal true, runner(c).run
99
+ assert_equal true, runner(c).run(@reporter)
96
100
  end
97
101
  end
98
102
 
@@ -102,7 +106,7 @@ class BaseRunnerTest < Test::Unit::TestCase
102
106
  should("fail") { flunk }
103
107
  end
104
108
  capture_stdout do
105
- assert_equal false, runner(c).run
109
+ assert_equal false, runner(c).run(@reporter)
106
110
  end
107
111
  end
108
112
 
@@ -118,7 +122,7 @@ class BaseRunnerTest < Test::Unit::TestCase
118
122
  end
119
123
  end
120
124
  capture_stdout do
121
- assert runner(c).run, "should not have run the context twice"
125
+ assert runner(c).run(@reporter), "should not have run the context twice"
122
126
  end
123
127
  end
124
128
 
@@ -129,8 +133,8 @@ class BaseRunnerTest < Test::Unit::TestCase
129
133
  end
130
134
  end
131
135
  r = runner(c)
132
- capture_stdout { r.run }
133
- assert_match /^1\) given something should fail:\n flunked\./, r.failure_messages[0]
136
+ capture_stdout { r.run(@reporter) }
137
+ assert_match /^1\) given something should fail:\n flunked\./, @reporter.failure_messages[0]
134
138
  end
135
139
 
136
140
  def test_should_include_line_in_test_of_error_in_failure_message
@@ -140,14 +144,14 @@ class BaseRunnerTest < Test::Unit::TestCase
140
144
  end
141
145
  end
142
146
  r = runner(c)
143
- capture_stdout { r.run }
144
- assert_match /at #{Regexp.escape(__FILE__)}:#{$line}/, r.failure_messages.first
147
+ capture_stdout { r.run(@reporter) }
148
+ assert_match /#{Regexp.escape(File.expand_path(__FILE__))}:#{$line}/, @reporter.failure_messages.first
145
149
  end
146
150
 
147
151
  private
148
152
 
149
153
  def runner(*args)
150
- Kintama::Runner::Base.new(*args)
154
+ Kintama::Runner::Default.new(args)
151
155
  end
152
156
 
153
157
  end
@@ -1,6 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
- class InlineRunnerTest < Test::Unit::TestCase
3
+ class InlineReporterTest < Test::Unit::TestCase
4
+ def setup
5
+ @reporter = Kintama::Reporter::Inline.new
6
+ end
7
+
4
8
  def test_should_print_out_dots_when_a_test_passes
5
9
  c = context "given something" do
6
10
  should "pass" do
@@ -9,7 +13,7 @@ class InlineRunnerTest < Test::Unit::TestCase
9
13
  end
10
14
  r = runner(c)
11
15
  assert_output(/^\.\n/) do
12
- r.run
16
+ r.run(@reporter)
13
17
  end
14
18
  end
15
19
 
@@ -24,7 +28,7 @@ class InlineRunnerTest < Test::Unit::TestCase
24
28
  end
25
29
  r = runner(c)
26
30
  assert_output(/^\.\.\n/) do
27
- r.run
31
+ r.run(@reporter)
28
32
  end
29
33
  end
30
34
 
@@ -39,7 +43,7 @@ class InlineRunnerTest < Test::Unit::TestCase
39
43
  end
40
44
  r = runner(c)
41
45
  assert_output(/^F\./) do
42
- r.run
46
+ r.run(@reporter)
43
47
  end
44
48
  end
45
49
 
@@ -52,13 +56,13 @@ class InlineRunnerTest < Test::Unit::TestCase
52
56
  end
53
57
  r = runner(c)
54
58
  assert_output(/^P\./) do
55
- r.run
59
+ r.run(@reporter)
56
60
  end
57
61
  end
58
62
 
59
63
  private
60
64
 
61
65
  def runner(*args)
62
- Kintama::Runner::Inline.new(*args)
66
+ Kintama::Runner::Default.new(args)
63
67
  end
64
68
  end
@@ -1,6 +1,11 @@
1
1
  require 'test_helper'
2
2
 
3
- class VerboseRunnerTest < Test::Unit::TestCase
3
+ class VerboseReporterTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @reporter = Kintama::Reporter::Verbose.new(false)
7
+ end
8
+
4
9
  def test_should_print_out_test_names
5
10
  c = context "given something" do
6
11
  should "also pass" do
@@ -11,7 +16,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
11
16
  end
12
17
  end
13
18
  assert_output(/^given something\n should also pass: \.\n should pass: \./) do
14
- runner(c).run(false)
19
+ runner(c).run(@reporter)
15
20
  end
16
21
  end
17
22
 
@@ -23,7 +28,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
23
28
  end
24
29
  end
25
30
  assert_output(/^given something\n should not be implemented: P\n should pass: \./) do
26
- runner(c).run(false)
31
+ runner(c).run(@reporter)
27
32
  end
28
33
  end
29
34
 
@@ -44,7 +49,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
44
49
  end
45
50
  end
46
51
  assert_output(/^given something\n should pass: \.\n and something else\n should pass: \.\n and then this\n should also pass: \./) do
47
- runner(c).run(false)
52
+ runner(c).run(@reporter)
48
53
  end
49
54
  end
50
55
 
@@ -54,7 +59,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
54
59
  assert 1 == 2, "1 should equal 2"
55
60
  end
56
61
  end
57
- assert_output(/given something should fail:\n 1 should equal 2/) { runner(c).run(false) }
62
+ assert_output(/given something should fail:\n 1 should equal 2/) { runner(c).run(@reporter) }
58
63
  end
59
64
 
60
65
  def test_should_print_out_a_summary_of_the_failing_tests_if_an_exception_occurs_in_a_test
@@ -63,7 +68,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
63
68
  raise "unexpected issue!"
64
69
  end
65
70
  end
66
- assert_output(/given something should fail:\n unexpected issue!/) { runner(c).run(false) }
71
+ assert_output(/given something should fail:\n unexpected issue!/) { runner(c).run(@reporter) }
67
72
  end
68
73
 
69
74
  def test_should_print_out_a_summary_of_the_failing_tests_if_a_nested_test_fails
@@ -74,7 +79,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
74
79
  end
75
80
  end
76
81
  end
77
- assert_output(/given something and something else should fail:\n 1 should equal 2/) { runner(c).run(false) }
82
+ assert_output(/given something and something else should fail:\n 1 should equal 2/) { runner(c).run(@reporter) }
78
83
  end
79
84
 
80
85
  def test_should_nest_verbose_output_properly_when_running_tests_from_several_contexts
@@ -89,7 +94,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
89
94
  end
90
95
  end
91
96
  assert_output(/^given something\n should pass: \.\n\ngiven another thing\n should also pass: \./) do
92
- runner(c1, c2).run(false)
97
+ runner(c1, c2).run(@reporter)
93
98
  end
94
99
  end
95
100
 
@@ -104,7 +109,7 @@ class VerboseRunnerTest < Test::Unit::TestCase
104
109
  should "be yellow"
105
110
  end
106
111
  assert_output(/^given something\n\e\[32m should be green\e\[0m\n\e\[31m should be red\e\[0m\n\e\[33m should be yellow\e\[0m/) do
107
- runner(c).run(colour=true)
112
+ runner(c).run(Kintama::Reporter::Verbose.new(true))
108
113
  end
109
114
  end
110
115
 
@@ -117,13 +122,13 @@ class VerboseRunnerTest < Test::Unit::TestCase
117
122
  end
118
123
  end
119
124
  assert_output(/^In a world without hope\n given a massive gun\n it should work out well in the end: \./) do
120
- runner(c).run(false)
125
+ runner(c).run(@reporter)
121
126
  end
122
127
  end
123
128
 
124
129
  private
125
130
 
126
131
  def runner(*args)
127
- Kintama::Runner::Verbose.new(*args)
132
+ Kintama::Runner::Default.new(args)
128
133
  end
129
134
  end
@@ -0,0 +1,94 @@
1
+ require "test_helper"
2
+
3
+ class StartAndFinishTest < Test::Unit::TestCase
4
+
5
+ def test_should_call_any_on_start_block_when_running_a_context
6
+ $ran = 0
7
+ c = context "A context with a startup block" do
8
+ on_start { $ran += 1 }
9
+ should "have run the on_start block" do
10
+ end
11
+ end
12
+ c.run
13
+ assert_equal 1, $ran
14
+ end
15
+
16
+ def test_should_only_call_on_start_block_once_when_running_a_context
17
+ $ran = 0
18
+ c = context "A context with a startup block" do
19
+ on_start { $ran += 1 }
20
+ should "have run the on_start block" do
21
+ end
22
+ should "not run that block again" do
23
+ end
24
+ end
25
+ c.run
26
+ assert_equal 1, $ran
27
+ end
28
+
29
+ def test_should_only_call_on_start_block_before_any_test
30
+ $ran = 0
31
+ c = context "A context with a startup block" do
32
+ on_start { $ran += 1 }
33
+ should "have run the on_start block" do
34
+ assert_equal 1, $ran
35
+ end
36
+ should "not run that block again" do
37
+ assert_equal 1, $ran
38
+ end
39
+ end
40
+ c.run
41
+ assert c.passed?
42
+ end
43
+
44
+ def test_should_call_any_on_finish_block_when_running_a_context
45
+ $ran = 0
46
+ c = context "A context with a startup block" do
47
+ should "have run the on_start block" do
48
+ end
49
+ on_finish { $ran += 1 }
50
+ end
51
+ c.run
52
+ assert_equal 1, $ran
53
+ end
54
+
55
+ def test_should_only_call_on_finish_block_once_when_running_a_context
56
+ $ran = 0
57
+ c = context "A context with a startup block" do
58
+ should "have run the on_start block" do
59
+ end
60
+ should "not run that block again" do
61
+ end
62
+ on_finish { $ran += 1 }
63
+ end
64
+ c.run
65
+ assert_equal 1, $ran
66
+ end
67
+
68
+ def test_should_only_call_on_finish_block_after_all_tests
69
+ $ran = 0
70
+ c = context "A context with a startup block" do
71
+ should "have run the on_start block" do
72
+ assert_equal 0, $ran
73
+ end
74
+ should "not run that block again" do
75
+ assert_equal 0, $ran
76
+ end
77
+ on_finish { $ran += 1 }
78
+ end
79
+ c.run
80
+ assert c.passed?
81
+ end
82
+
83
+ def test_should_be_able_to_use_rspec_like_aliases
84
+ $ran = 0
85
+ c = context "A context with a startup block" do
86
+ before_all { $ran += 1 }
87
+ should "have run the on_start block" do
88
+ end
89
+ after_all { $ran += 1 }
90
+ end
91
+ c.run
92
+ assert_equal 2, $ran
93
+ end
94
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kintama
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease: false
4
+ hash: 29
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Adam
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-05 00:00:00 +00:00
18
+ date: 2011-04-04 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -34,18 +34,22 @@ files:
34
34
  - test/automatic_running_test.rb
35
35
  - test/exceptions_test.rb
36
36
  - test/kintama_test.rb
37
+ - test/line_based_running_test.rb
37
38
  - test/matcher_test.rb
38
39
  - test/method_behaviour_test.rb
39
40
  - test/pending_test.rb
40
- - test/runners/base_runner_test.rb
41
- - test/runners/inline_runner_test.rb
42
- - test/runners/verbose_runner_test.rb
41
+ - test/reporters/base_reporter_test.rb
42
+ - test/reporters/inline_reporter_test.rb
43
+ - test/reporters/verbose_reporter_test.rb
43
44
  - test/setup_test.rb
45
+ - test/start_and_finish_test.rb
44
46
  - test/teardown_test.rb
45
47
  - test/test_and_subcontext_access_test.rb
46
48
  - test/test_helper.rb
47
49
  - lib/kintama/assertions.rb
48
50
  - lib/kintama/context.rb
51
+ - lib/kintama/mocha.rb
52
+ - lib/kintama/reporter.rb
49
53
  - lib/kintama/runnable.rb
50
54
  - lib/kintama/runner.rb
51
55
  - lib/kintama/test.rb
@@ -81,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
85
  requirements: []
82
86
 
83
87
  rubyforge_project:
84
- rubygems_version: 1.3.7
88
+ rubygems_version: 1.4.1
85
89
  signing_key:
86
90
  specification_version: 3
87
91
  summary: It's for writing tests.