kintama 0.1.1
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 +247 -0
- data/lib/kintama.rb +100 -0
- data/lib/kintama/assertions.rb +38 -0
- data/lib/kintama/context.rb +187 -0
- data/lib/kintama/runnable.rb +33 -0
- data/lib/kintama/runner.rb +153 -0
- data/lib/kintama/test.rb +68 -0
- data/test/aliases_test.rb +26 -0
- data/test/assertions_test.rb +42 -0
- data/test/automatic_running_test.rb +45 -0
- data/test/exceptions_test.rb +40 -0
- data/test/kintama_test.rb +114 -0
- data/test/matcher_test.rb +65 -0
- data/test/method_behaviour_test.rb +176 -0
- data/test/pending_test.rb +13 -0
- data/test/runners/base_runner_test.rb +153 -0
- data/test/runners/inline_runner_test.rb +64 -0
- data/test/runners/verbose_runner_test.rb +129 -0
- data/test/setup_test.rb +107 -0
- data/test/teardown_test.rb +92 -0
- data/test/test_and_subcontext_access_test.rb +110 -0
- data/test/test_helper.rb +36 -0
- metadata +89 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Kintama
|
2
|
+
class Runnable
|
3
|
+
class << self
|
4
|
+
attr_accessor :name
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
"<#{name} #{super}/#{is_a_test? ? 'Test' : 'Context'}>"
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_a_test?
|
11
|
+
ancestors.index(Kintama::Test) &&
|
12
|
+
ancestors.index(Kintama::Test) < ancestors.index(Kintama::Context)
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_a_context?
|
16
|
+
!is_a_test?
|
17
|
+
end
|
18
|
+
|
19
|
+
def parent
|
20
|
+
superclass.ancestors.include?(Kintama::Context) ? superclass : nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the full name of this context, taking any parent contexts into account
|
24
|
+
def full_name
|
25
|
+
if @name
|
26
|
+
[parent ? parent.full_name : nil, @name].compact.join(" ")
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Kintama
|
2
|
+
class Runner
|
3
|
+
|
4
|
+
def self.default
|
5
|
+
Verbose.new(*Kintama.default_context.subcontexts)
|
6
|
+
end
|
7
|
+
|
8
|
+
class Base
|
9
|
+
def initialize(*contexts)
|
10
|
+
@contexts = contexts
|
11
|
+
end
|
12
|
+
|
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?
|
25
|
+
end
|
26
|
+
|
27
|
+
def context_started(context); end
|
28
|
+
def context_finished(context); end
|
29
|
+
def test_started(test)
|
30
|
+
@test_count += 1
|
31
|
+
end
|
32
|
+
def test_finished(test); end
|
33
|
+
|
34
|
+
def passed?
|
35
|
+
failures.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
def failures
|
39
|
+
@contexts.map { |c| c.failures }.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
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
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
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)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
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)
|
132
|
+
end
|
133
|
+
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
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
data/lib/kintama/test.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Kintama
|
2
|
+
class TestFailure < StandardError; end
|
3
|
+
|
4
|
+
module Test
|
5
|
+
include Kintama::Assertions
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
class << base
|
9
|
+
attr_accessor :block
|
10
|
+
|
11
|
+
def pending?
|
12
|
+
@block.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
new.run
|
17
|
+
end
|
18
|
+
end
|
19
|
+
base.send :attr_reader, :failure
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(runner=nil)
|
23
|
+
@failure = nil
|
24
|
+
runner.test_started(self) if runner
|
25
|
+
unless pending?
|
26
|
+
begin
|
27
|
+
setup
|
28
|
+
instance_eval(&self.class.block)
|
29
|
+
rescue Exception => e
|
30
|
+
@failure = e
|
31
|
+
ensure
|
32
|
+
begin
|
33
|
+
teardown
|
34
|
+
rescue Exception => e
|
35
|
+
@failure = e
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
runner.test_finished(self) if runner
|
40
|
+
passed?
|
41
|
+
end
|
42
|
+
|
43
|
+
def pending?
|
44
|
+
self.class.pending?
|
45
|
+
end
|
46
|
+
|
47
|
+
def passed?
|
48
|
+
@failure.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def name
|
52
|
+
self.class.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def full_name
|
56
|
+
self.class.full_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def failure_message
|
60
|
+
"#{@failure.message} (at #{failure_line})"
|
61
|
+
end
|
62
|
+
|
63
|
+
def failure_line
|
64
|
+
base_dir = File.expand_path("../..", __FILE__)
|
65
|
+
@failure.backtrace.find { |line| File.expand_path(line).index(base_dir).nil? }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AliasesTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_should_provide_given_and_it_aliases_for_context_and_should
|
6
|
+
x = context "In a world without hope" do
|
7
|
+
given "a massive gun" do
|
8
|
+
it "should work out well in the end" do
|
9
|
+
assert true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
x.run
|
14
|
+
assert x.passed?
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_provide_testcase_alias_for_context
|
18
|
+
x = testcase "In a world without hope" do
|
19
|
+
should "work out well in the end" do
|
20
|
+
assert true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
x.run
|
24
|
+
assert x.passed?
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AssertionsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
class PseudoTest
|
6
|
+
include Kintama::Assertions
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@test = PseudoTest.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_provide_assert_nil
|
14
|
+
assert_assertion_fails { @test.assert_nil Object.new }
|
15
|
+
assert_assertion_passes { @test.assert_nil nil }
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_should_provide_assert_not_nil
|
19
|
+
assert_assertion_passes { @test.assert_not_nil Object.new }
|
20
|
+
assert_assertion_fails { @test.assert_not_nil nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_should_provide_assert_kind_of
|
24
|
+
assert_assertion_passes { @test.assert_kind_of Fixnum, 1 }
|
25
|
+
assert_assertion_passes { @test.assert_kind_of Object, 1 }
|
26
|
+
assert_assertion_passes { @test.assert_kind_of String, "hello" }
|
27
|
+
assert_assertion_fails { @test.assert_kind_of String, 1 }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def assert_assertion_passes
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
|
36
|
+
def assert_assertion_fails
|
37
|
+
yield
|
38
|
+
raise "assertion did not fail!"
|
39
|
+
rescue Kintama::TestFailure
|
40
|
+
# nothing
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AutomaticRunningTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_should_be_able_to_run_tests_automatically_when_file_is_loaded
|
6
|
+
assert_passes write_test %{
|
7
|
+
context "given a thing" do
|
8
|
+
should "work" do
|
9
|
+
assert true
|
10
|
+
end
|
11
|
+
end}
|
12
|
+
assert_fails write_test %{
|
13
|
+
context "given a thing" do
|
14
|
+
should "not work" do
|
15
|
+
flunk
|
16
|
+
end
|
17
|
+
end}
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def write_test(string)
|
23
|
+
f = File.open("/tmp/kintama_tmp_test.rb", "w") do |f|
|
24
|
+
f.puts %|$LOAD_PATH.unshift "#{File.expand_path("../../lib", __FILE__)}"; require "kintama"|
|
25
|
+
f.puts string
|
26
|
+
end
|
27
|
+
"/tmp/kintama_tmp_test.rb"
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_test(path)
|
31
|
+
prev = ENV["KINTAMA_EXPLICITLY_DONT_RUN"]
|
32
|
+
ENV["KINTAMA_EXPLICITLY_DONT_RUN"] = nil
|
33
|
+
output = `ruby #{path}`
|
34
|
+
ENV["KINTAMA_EXPLICITLY_DONT_RUN"] = prev
|
35
|
+
$?
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_passes(path)
|
39
|
+
assert_equal 0, run_test(path).exitstatus
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_fails(path)
|
43
|
+
assert_equal 1, run_test(path).exitstatus
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExceptionsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_should_capture_exceptions_in_tests_as_failing_tests
|
6
|
+
x = context "Given a test" do
|
7
|
+
should "that raises an exception" do
|
8
|
+
raise "aaargh"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
x.run
|
12
|
+
assert !x.passed?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_capture_exceptions_in_setups_as_failing_tests
|
16
|
+
x = context "Given a test with setup that fails" do
|
17
|
+
setup do
|
18
|
+
raise "aargh"
|
19
|
+
end
|
20
|
+
should "that would otherwise pass" do
|
21
|
+
assert true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
x.run
|
25
|
+
assert !x.passed?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_capture_exceptions_in_teardowns_as_failing_tests
|
29
|
+
x = context "Given a test with teardown that fails" do
|
30
|
+
teardown do
|
31
|
+
raise "aargh"
|
32
|
+
end
|
33
|
+
should "that would otherwise pass" do
|
34
|
+
assert true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
x.run
|
38
|
+
assert !x.passed?
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class KintamaTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_should_pass_when_all_tests_pass
|
6
|
+
x = context "Given something" do
|
7
|
+
should "work" do
|
8
|
+
assert true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
x.run
|
12
|
+
assert x.passed?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_fail_when_all_tests_fail
|
16
|
+
x = context "Given something" do
|
17
|
+
should "work" do
|
18
|
+
flunk
|
19
|
+
end
|
20
|
+
end
|
21
|
+
x.run
|
22
|
+
assert !x.passed?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_fail_when_any_tests_fail
|
26
|
+
x = context "Given something" do
|
27
|
+
should "work" do
|
28
|
+
flunk
|
29
|
+
end
|
30
|
+
should "also work" do
|
31
|
+
assert true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
x.run
|
35
|
+
assert !x.passed?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_fail_when_any_assertion_within_a_test_fails
|
39
|
+
x = context "Given something" do
|
40
|
+
should "ultimately not work" do
|
41
|
+
flunk
|
42
|
+
assert true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
x.run
|
46
|
+
assert !x.passed?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_should_not_run_any_code_beyond_a_failing_assertion
|
50
|
+
x = context "Given something" do
|
51
|
+
should "ultimately not work" do
|
52
|
+
flunk
|
53
|
+
raise "should not get here!"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
x.run
|
57
|
+
assert !x.passed?
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_should_allow_nesting_of_contexts
|
61
|
+
x = context "Given something" do
|
62
|
+
context "and another thing" do
|
63
|
+
should "work" do
|
64
|
+
flunk
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
x.run
|
69
|
+
assert !x.passed?
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_should_allow_multiple_subcontexts
|
73
|
+
x = context "Given something" do
|
74
|
+
context "and another thing" do
|
75
|
+
should "work" do
|
76
|
+
flunk
|
77
|
+
end
|
78
|
+
end
|
79
|
+
context "and another different thing" do
|
80
|
+
should "work" do
|
81
|
+
assert true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
x.run
|
86
|
+
assert !x.passed?
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_allow_deep_nesting_of_subcontexts
|
90
|
+
x = context "Given something" do
|
91
|
+
context "and another thing" do
|
92
|
+
context "and one more thing" do
|
93
|
+
should "work" do
|
94
|
+
flunk
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
x.run
|
100
|
+
assert !x.passed?
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_should_clear_previous_failure_when_running_test_again
|
104
|
+
$thing = 456
|
105
|
+
x = context "Given something" do
|
106
|
+
should "work" do
|
107
|
+
assert_equal 123, $thing
|
108
|
+
end
|
109
|
+
end
|
110
|
+
assert_equal false, x.run
|
111
|
+
$thing = 123
|
112
|
+
assert_equal true, x.run
|
113
|
+
end
|
114
|
+
end
|