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