kintama 0.1.1 → 0.1.3

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.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.