kintama 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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