treetop 0.1.0 → 1.0.0

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.
Files changed (153) hide show
  1. data/README +3 -0
  2. data/Rakefile +35 -0
  3. data/bin/tt +25 -0
  4. data/lib/treetop.rb +10 -6
  5. data/lib/treetop/compiler.rb +7 -0
  6. data/lib/treetop/compiler/grammar_compiler.rb +21 -0
  7. data/lib/treetop/compiler/lexical_address_space.rb +17 -0
  8. data/lib/treetop/compiler/load_grammar.rb +7 -0
  9. data/lib/treetop/compiler/metagrammar.rb +2441 -0
  10. data/lib/treetop/compiler/metagrammar.treetop +384 -0
  11. data/lib/treetop/compiler/node_classes.rb +18 -0
  12. data/lib/treetop/compiler/node_classes/anything_symbol.rb +10 -0
  13. data/lib/treetop/compiler/node_classes/atomic_expression.rb +9 -0
  14. data/lib/treetop/compiler/node_classes/character_class.rb +10 -0
  15. data/lib/treetop/compiler/node_classes/choice.rb +31 -0
  16. data/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
  17. data/lib/treetop/compiler/node_classes/grammar.rb +28 -0
  18. data/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
  19. data/lib/treetop/compiler/node_classes/nonterminal.rb +11 -0
  20. data/lib/treetop/compiler/node_classes/optional.rb +19 -0
  21. data/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
  22. data/lib/treetop/compiler/node_classes/parsing_expression.rb +132 -0
  23. data/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
  24. data/lib/treetop/compiler/node_classes/predicate.rb +45 -0
  25. data/lib/treetop/compiler/node_classes/repetition.rb +56 -0
  26. data/lib/treetop/compiler/node_classes/sequence.rb +64 -0
  27. data/lib/treetop/compiler/node_classes/terminal.rb +10 -0
  28. data/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
  29. data/lib/treetop/compiler/ruby_builder.rb +109 -0
  30. data/lib/treetop/ruby_extensions.rb +2 -0
  31. data/lib/treetop/ruby_extensions/string.rb +19 -0
  32. data/lib/treetop/runtime.rb +9 -0
  33. data/lib/treetop/runtime/compiled_parser.rb +66 -0
  34. data/lib/treetop/runtime/node_cache.rb +27 -0
  35. data/lib/treetop/runtime/parse_cache.rb +19 -0
  36. data/lib/treetop/runtime/parse_failure.rb +32 -0
  37. data/lib/treetop/runtime/parse_result.rb +30 -0
  38. data/lib/treetop/runtime/syntax_node.rb +53 -0
  39. data/lib/treetop/runtime/terminal_parse_failure.rb +33 -0
  40. data/lib/treetop/runtime/terminal_syntax_node.rb +12 -0
  41. data/test/compilation_target/target.rb +143 -0
  42. data/test/compilation_target/target.treetop +15 -0
  43. data/test/compilation_target/target_test.rb +56 -0
  44. data/test/compiler/and_predicate_test.rb +33 -0
  45. data/test/compiler/anything_symbol_test.rb +24 -0
  46. data/test/compiler/character_class_test.rb +45 -0
  47. data/test/compiler/choice_test.rb +49 -0
  48. data/test/compiler/circular_compilation_test.rb +20 -0
  49. data/test/compiler/failure_propagation_functional_test.rb +20 -0
  50. data/test/compiler/grammar_compiler_test.rb +58 -0
  51. data/test/compiler/grammar_test.rb +33 -0
  52. data/test/compiler/nonterminal_symbol_test.rb +15 -0
  53. data/test/compiler/not_predicate_test.rb +35 -0
  54. data/test/compiler/one_or_more_test.rb +30 -0
  55. data/test/compiler/optional_test.rb +32 -0
  56. data/test/compiler/parsing_rule_test.rb +30 -0
  57. data/test/compiler/sequence_test.rb +68 -0
  58. data/test/compiler/terminal_symbol_test.rb +35 -0
  59. data/test/compiler/test_grammar.treetop +7 -0
  60. data/test/compiler/zero_or_more_test.rb +51 -0
  61. data/test/composition/a.treetop +11 -0
  62. data/test/composition/b.treetop +11 -0
  63. data/test/composition/c.treetop +10 -0
  64. data/test/composition/d.treetop +10 -0
  65. data/test/composition/grammar_composition_test.rb +23 -0
  66. data/test/parser/syntax_node_test.rb +53 -0
  67. data/test/parser/terminal_parse_failure_test.rb +22 -0
  68. data/test/ruby_extensions/string_test.rb +33 -0
  69. data/test/screw/Rakefile +16 -0
  70. data/test/screw/unit.rb +37 -0
  71. data/test/screw/unit/assertion_failed_error.rb +14 -0
  72. data/test/screw/unit/assertions.rb +615 -0
  73. data/test/screw/unit/auto_runner.rb +227 -0
  74. data/test/screw/unit/collector.rb +45 -0
  75. data/test/screw/unit/collector/dir.rb +107 -0
  76. data/test/screw/unit/collector/objectspace.rb +28 -0
  77. data/test/screw/unit/error.rb +48 -0
  78. data/test/screw/unit/failure.rb +45 -0
  79. data/test/screw/unit/sugar.rb +25 -0
  80. data/test/screw/unit/test_case.rb +176 -0
  81. data/test/screw/unit/test_result.rb +73 -0
  82. data/test/screw/unit/test_suite.rb +70 -0
  83. data/test/screw/unit/ui.rb +4 -0
  84. data/test/screw/unit/ui/console/test_runner.rb +118 -0
  85. data/test/screw/unit/ui/fox/test_runner.rb +268 -0
  86. data/test/screw/unit/ui/gtk/test_runner.rb +416 -0
  87. data/test/screw/unit/ui/gtk2/testrunner.rb +465 -0
  88. data/test/screw/unit/ui/test_runner_mediator.rb +58 -0
  89. data/test/screw/unit/ui/test_runner_utilities.rb +46 -0
  90. data/test/screw/unit/ui/tk/test_runner.rb +260 -0
  91. data/test/screw/unit/util.rb +4 -0
  92. data/test/screw/unit/util/backtrace_filter.rb +40 -0
  93. data/test/screw/unit/util/observable.rb +82 -0
  94. data/test/screw/unit/util/proc_wrapper.rb +48 -0
  95. data/test/test_helper.rb +89 -0
  96. metadata +127 -69
  97. data/lib/treetop/api.rb +0 -3
  98. data/lib/treetop/api/load_grammar.rb +0 -16
  99. data/lib/treetop/api/malformed_grammar_exception.rb +0 -9
  100. data/lib/treetop/grammar.rb +0 -7
  101. data/lib/treetop/grammar/grammar.rb +0 -48
  102. data/lib/treetop/grammar/grammar_builder.rb +0 -35
  103. data/lib/treetop/grammar/parsing_expression_builder.rb +0 -5
  104. data/lib/treetop/grammar/parsing_expression_builder_helper.rb +0 -121
  105. data/lib/treetop/grammar/parsing_expressions.rb +0 -18
  106. data/lib/treetop/grammar/parsing_expressions/and_predicate.rb +0 -17
  107. data/lib/treetop/grammar/parsing_expressions/anything_symbol.rb +0 -20
  108. data/lib/treetop/grammar/parsing_expressions/character_class.rb +0 -24
  109. data/lib/treetop/grammar/parsing_expressions/node_instantiating_parsing_expression.rb +0 -14
  110. data/lib/treetop/grammar/parsing_expressions/node_propagating_parsing_expression.rb +0 -4
  111. data/lib/treetop/grammar/parsing_expressions/nonterminal_symbol.rb +0 -42
  112. data/lib/treetop/grammar/parsing_expressions/not_predicate.rb +0 -18
  113. data/lib/treetop/grammar/parsing_expressions/one_or_more.rb +0 -12
  114. data/lib/treetop/grammar/parsing_expressions/optional.rb +0 -14
  115. data/lib/treetop/grammar/parsing_expressions/ordered_choice.rb +0 -27
  116. data/lib/treetop/grammar/parsing_expressions/parsing_expression.rb +0 -36
  117. data/lib/treetop/grammar/parsing_expressions/predicate.rb +0 -25
  118. data/lib/treetop/grammar/parsing_expressions/repeating_parsing_expression.rb +0 -29
  119. data/lib/treetop/grammar/parsing_expressions/sequence.rb +0 -41
  120. data/lib/treetop/grammar/parsing_expressions/terminal_parsing_expression.rb +0 -11
  121. data/lib/treetop/grammar/parsing_expressions/terminal_symbol.rb +0 -31
  122. data/lib/treetop/grammar/parsing_expressions/zero_or_more.rb +0 -11
  123. data/lib/treetop/grammar/parsing_rule.rb +0 -10
  124. data/lib/treetop/metagrammar.rb +0 -2
  125. data/lib/treetop/metagrammar/metagrammar.rb +0 -14
  126. data/lib/treetop/metagrammar/metagrammar.treetop +0 -320
  127. data/lib/treetop/parser.rb +0 -11
  128. data/lib/treetop/parser/node_cache.rb +0 -25
  129. data/lib/treetop/parser/parse_cache.rb +0 -17
  130. data/lib/treetop/parser/parse_failure.rb +0 -22
  131. data/lib/treetop/parser/parse_result.rb +0 -26
  132. data/lib/treetop/parser/parser.rb +0 -24
  133. data/lib/treetop/parser/sequence_syntax_node.rb +0 -14
  134. data/lib/treetop/parser/syntax_node.rb +0 -31
  135. data/lib/treetop/parser/terminal_parse_failure.rb +0 -18
  136. data/lib/treetop/parser/terminal_syntax_node.rb +0 -7
  137. data/lib/treetop/protometagrammar.rb +0 -16
  138. data/lib/treetop/protometagrammar/anything_symbol_expression_builder.rb +0 -13
  139. data/lib/treetop/protometagrammar/block_expression_builder.rb +0 -17
  140. data/lib/treetop/protometagrammar/character_class_expression_builder.rb +0 -25
  141. data/lib/treetop/protometagrammar/grammar_expression_builder.rb +0 -38
  142. data/lib/treetop/protometagrammar/nonterminal_symbol_expression_builder.rb +0 -45
  143. data/lib/treetop/protometagrammar/ordered_choice_expression_builder.rb +0 -21
  144. data/lib/treetop/protometagrammar/parsing_rule_expression_builder.rb +0 -23
  145. data/lib/treetop/protometagrammar/parsing_rule_sequence_expression_builder.rb +0 -14
  146. data/lib/treetop/protometagrammar/prefix_expression_builder.rb +0 -25
  147. data/lib/treetop/protometagrammar/primary_expression_builder.rb +0 -71
  148. data/lib/treetop/protometagrammar/protometagrammar.rb +0 -25
  149. data/lib/treetop/protometagrammar/sequence_expression_builder.rb +0 -37
  150. data/lib/treetop/protometagrammar/suffix_expression_builder.rb +0 -33
  151. data/lib/treetop/protometagrammar/terminal_symbol_expression_builder.rb +0 -52
  152. data/lib/treetop/protometagrammar/trailing_block_expression_builder.rb +0 -30
  153. data/lib/treetop/ruby_extension.rb +0 -11
@@ -0,0 +1,45 @@
1
+ module Screw
2
+ module Unit
3
+
4
+ # Encapsulates a test failure. Created by Screw::Unit::TestCase
5
+ # when an assertion fails.
6
+ class Failure
7
+ attr_reader :test_name, :location, :message
8
+
9
+ SINGLE_CHARACTER = 'F'
10
+
11
+ # Creates a new Failure with the given location and
12
+ # message.
13
+ def initialize(test_name, location, message)
14
+ @test_name = test_name
15
+ @location = location
16
+ @message = message
17
+ end
18
+
19
+ # Returns a single character representation of a failure.
20
+ def single_character_display
21
+ SINGLE_CHARACTER
22
+ end
23
+
24
+ # Returns a brief version of the error description.
25
+ def short_display
26
+ "#@test_name: #{@message.split("\n")[0]}"
27
+ end
28
+
29
+ # Returns a verbose version of the error description.
30
+ def long_display
31
+ location_display = if(location.size == 1)
32
+ location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
33
+ else
34
+ "\n [#{location.join("\n ")}]"
35
+ end
36
+ "Failure:\n#@test_name#{location_display}:\n#@message"
37
+ end
38
+
39
+ # Overridden to return long_display.
40
+ def to_s
41
+ long_display
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ class Object
2
+ def context(description, options = {}, &block)
3
+ superclass = options[:extend] || Screw::Unit::TestCase
4
+ test_case_class = Class.new(superclass, &block)
5
+ test_case_class.test_case_description = description
6
+ Object.send(:const_set, unique_test_case_name(description.sanitize.camelize), test_case_class)
7
+ end
8
+
9
+ def unique_test_case_name(name, n=1)
10
+ candidate_name = (n > 1 ? "#{name}#{n}" : name).to_sym
11
+ if Object.const_defined?(candidate_name)
12
+ unique_test_case_name(name, n + 1)
13
+ else
14
+ candidate_name
15
+ end
16
+ end
17
+
18
+ alias :describe :context
19
+ end
20
+
21
+ class String
22
+ def sanitize
23
+ self.gsub(/[^\w]+/, "_")
24
+ end
25
+ end
@@ -0,0 +1,176 @@
1
+ module Screw
2
+ module Unit
3
+
4
+ # Ties everything together. If you subclass and add your own
5
+ # test methods, it takes care of making them into tests and
6
+ # wrapping those tests into a suite. It also does the
7
+ # nitty-gritty of actually running an individual test and
8
+ # collecting its results into a Screw::Unit::TestResult object.
9
+ class TestCase
10
+ class << self
11
+
12
+ attr_writer :test_case_description
13
+
14
+ def test_case_description
15
+ @test_case_description || self.to_s
16
+ end
17
+
18
+ # Rolls up all of the test* methods in the fixture into
19
+ # one suite, creating a new instance of the fixture for
20
+ # each method.
21
+ def suite
22
+ method_names = public_instance_methods(true)
23
+ tests = method_names.delete_if {|method_name| method_name !~ /^test./}
24
+ suite = TestSuite.new(name)
25
+ tests.sort.each do
26
+ |test|
27
+ catch(:invalid_test) do
28
+ suite << new(test)
29
+ end
30
+ end
31
+ return suite
32
+ end
33
+
34
+ def test_names
35
+ @test_names ||= Hash.new
36
+ end
37
+
38
+ # Creates a test method by prefixing string with 'test_' and replacing non word characters with underbars
39
+ def test(name_string, &block)
40
+ method_name = unique_test_name("test_" + name_string.sanitize)
41
+ test_names[method_name] = name_string
42
+ define_method(method_name, &block)
43
+ end
44
+
45
+ def unique_test_name(name, n=1)
46
+ candidate_name = (n > 1 ? "#{name}#{n}" : name).to_sym
47
+ if method_defined?(candidate_name)
48
+ unique_test_name(name, n + 1)
49
+ else
50
+ candidate_name
51
+ end
52
+ end
53
+
54
+
55
+ alias :it :test
56
+ end
57
+
58
+
59
+ include Assertions
60
+ include Spec::Matchers
61
+ include Util::BacktraceFilter
62
+
63
+ attr_reader :method_name
64
+
65
+ STARTED = name + "::STARTED"
66
+ FINISHED = name + "::FINISHED"
67
+
68
+ ##
69
+ # These exceptions are not caught by #run.
70
+
71
+ PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,
72
+ SystemExit]
73
+
74
+ # Creates a new instance of the fixture for running the
75
+ # test represented by test_method_name.
76
+ def initialize(test_method_name)
77
+ unless(respond_to?(test_method_name) and
78
+ (method(test_method_name).arity == 0 ||
79
+ method(test_method_name).arity == -1))
80
+ throw :invalid_test
81
+ end
82
+ @method_name = test_method_name
83
+ @test_passed = true
84
+ end
85
+
86
+ # Runs the individual test method represented by this
87
+ # instance of the fixture, collecting statistics, failures
88
+ # and errors in result.
89
+ def run(result)
90
+ yield(STARTED, name)
91
+ @_result = result
92
+ begin
93
+ setup
94
+ __send__(@method_name)
95
+ rescue AssertionFailedError => e
96
+ add_failure(e.message, e.backtrace)
97
+ rescue Exception
98
+ raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
99
+ add_error($!)
100
+ ensure
101
+ begin
102
+ teardown
103
+ rescue AssertionFailedError => e
104
+ add_failure(e.message, e.backtrace)
105
+ rescue Exception
106
+ raise if PASSTHROUGH_EXCEPTIONS.include? $!.class
107
+ add_error($!)
108
+ end
109
+ end
110
+ result.add_run
111
+ yield(FINISHED, name)
112
+ end
113
+
114
+ # Called before every test method runs. Can be used
115
+ # to set up fixture information.
116
+ def setup
117
+ end
118
+
119
+ # Called after every test method runs. Can be used to tear
120
+ # down fixture information.
121
+ def teardown
122
+ end
123
+
124
+ def default_test
125
+ flunk("No tests were specified")
126
+ end
127
+
128
+ # Returns whether this individual test passed or
129
+ # not. Primarily for use in teardown so that artifacts
130
+ # can be left behind if the test fails.
131
+ def passed?
132
+ return @test_passed
133
+ end
134
+ private :passed?
135
+
136
+ def size
137
+ 1
138
+ end
139
+
140
+ def add_assertion
141
+ @_result.add_assertion
142
+ end
143
+ private :add_assertion
144
+
145
+ def add_failure(message, all_locations=caller())
146
+ @test_passed = false
147
+ @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message))
148
+ end
149
+ private :add_failure
150
+
151
+ def add_error(exception)
152
+ @test_passed = false
153
+ @_result.add_error(Error.new(name, exception))
154
+ end
155
+ private :add_error
156
+
157
+ # Returns a human-readable name for the specific test that
158
+ # this instance of TestCase represents.
159
+ def name
160
+ "#{self.class.test_case_description}: #{self.class.test_names[@method_name] || @method_name}"
161
+ end
162
+
163
+ # Overridden to return #name.
164
+ def to_s
165
+ name
166
+ end
167
+
168
+ # It's handy to be able to compare TestCase instances.
169
+ def ==(other)
170
+ return false unless(other.kind_of?(self.class))
171
+ return false unless(@method_name == other.method_name)
172
+ self.class == other.class
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,73 @@
1
+ module Screw
2
+ module Unit
3
+
4
+ # Collects Screw::Unit::Failure and Screw::Unit::Error so that
5
+ # they can be displayed to the user. To this end, observers
6
+ # can be added to it, allowing the dynamic updating of, say, a
7
+ # UI.
8
+ class TestResult
9
+ include Util::Observable
10
+
11
+ CHANGED = "CHANGED"
12
+ FAULT = "FAULT"
13
+
14
+ attr_reader(:run_count, :assertion_count)
15
+
16
+ # Constructs a new, empty TestResult.
17
+ def initialize
18
+ @run_count, @assertion_count = 0, 0
19
+ @failures, @errors = Array.new, Array.new
20
+ end
21
+
22
+ # Records a test run.
23
+ def add_run
24
+ @run_count += 1
25
+ notify_listeners(CHANGED, self)
26
+ end
27
+
28
+ # Records a Screw::Unit::Failure.
29
+ def add_failure(failure)
30
+ @failures << failure
31
+ notify_listeners(FAULT, failure)
32
+ notify_listeners(CHANGED, self)
33
+ end
34
+
35
+ # Records a Screw::Unit::Error.
36
+ def add_error(error)
37
+ @errors << error
38
+ notify_listeners(FAULT, error)
39
+ notify_listeners(CHANGED, self)
40
+ end
41
+
42
+ # Records an individual assertion.
43
+ def add_assertion
44
+ @assertion_count += 1
45
+ notify_listeners(CHANGED, self)
46
+ end
47
+
48
+ # Returns a string contain the recorded runs, assertions,
49
+ # failures and errors in this TestResult.
50
+ def to_s
51
+ "#{run_count} tests, #{assertion_count} assertions, #{failure_count} failures, #{error_count} errors"
52
+ end
53
+
54
+ # Returns whether or not this TestResult represents
55
+ # successful completion.
56
+ def passed?
57
+ return @failures.empty? && @errors.empty?
58
+ end
59
+
60
+ # Returns the number of failures this TestResult has
61
+ # recorded.
62
+ def failure_count
63
+ return @failures.size
64
+ end
65
+
66
+ # Returns the number of errors this TestResult has
67
+ # recorded.
68
+ def error_count
69
+ return @errors.size
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,70 @@
1
+ module Screw
2
+ module Unit
3
+
4
+ # A collection of tests which can be #run.
5
+ #
6
+ # Note: It is easy to confuse a TestSuite instance with
7
+ # something that has a static suite method; I know because _I_
8
+ # have trouble keeping them straight. Think of something that
9
+ # has a suite method as simply providing a way to get a
10
+ # meaningful TestSuite instance.
11
+ class TestSuite
12
+ attr_reader :name, :tests
13
+
14
+ STARTED = name + "::STARTED"
15
+ FINISHED = name + "::FINISHED"
16
+
17
+ # Creates a new TestSuite with the given name.
18
+ def initialize(name="Unnamed TestSuite")
19
+ @name = name
20
+ @tests = []
21
+ end
22
+
23
+ # Runs the tests and/or suites contained in this
24
+ # TestSuite.
25
+ def run(result, &progress_block)
26
+ yield(STARTED, name)
27
+ @tests.each do |test|
28
+ test.run(result, &progress_block)
29
+ end
30
+ yield(FINISHED, name)
31
+ end
32
+
33
+ # Adds the test to the suite.
34
+ def <<(test)
35
+ @tests << test
36
+ self
37
+ end
38
+
39
+ def delete(test)
40
+ @tests.delete(test)
41
+ end
42
+
43
+ # Retuns the rolled up number of tests in this suite;
44
+ # i.e. if the suite contains other suites, it counts the
45
+ # tests within those suites, not the suites themselves.
46
+ def size
47
+ total_size = 0
48
+ @tests.each { |test| total_size += test.size }
49
+ total_size
50
+ end
51
+
52
+ def empty?
53
+ tests.empty?
54
+ end
55
+
56
+ # Overridden to return the name given the suite at
57
+ # creation.
58
+ def to_s
59
+ @name
60
+ end
61
+
62
+ # It's handy to be able to compare TestSuite instances.
63
+ def ==(other)
64
+ return false unless(other.kind_of?(self.class))
65
+ return false unless(@name == other.name)
66
+ @tests == other.tests
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ dir = File.dirname(__FILE__)
2
+ require File.join(dir, 'ui', 'test_runner_mediator')
3
+ require File.join(dir, 'ui', 'test_runner_utilities')
4
+ #require File.join(dir, 'ui', 'console', 'test_runner')
@@ -0,0 +1,118 @@
1
+ module Screw
2
+ module Unit
3
+ module UI
4
+ module Console
5
+
6
+ # Runs a Screw::Unit::TestSuite on the console.
7
+ class TestRunner
8
+ extend TestRunnerUtilities
9
+
10
+ # Creates a new TestRunner for running the passed
11
+ # suite. If quiet_mode is true, the output while
12
+ # running is limited to progress dots, errors and
13
+ # failures, and the final result. io specifies
14
+ # where runner output should go to; defaults to
15
+ # STDOUT.
16
+ def initialize(suite, output_level=NORMAL, io=STDOUT)
17
+ if (suite.respond_to?(:suite))
18
+ @suite = suite.suite
19
+ else
20
+ @suite = suite
21
+ end
22
+ @output_level = output_level
23
+ @io = io
24
+ @already_outputted = false
25
+ @faults = []
26
+ end
27
+
28
+ # Begins the test run.
29
+ def start
30
+ setup_mediator
31
+ attach_to_mediator
32
+ return start_mediator
33
+ end
34
+
35
+ private
36
+ def setup_mediator
37
+ @mediator = create_mediator(@suite)
38
+ suite_name = @suite.to_s
39
+ if ( @suite.kind_of?(Module) )
40
+ suite_name = @suite.name
41
+ end
42
+ output("Loaded suite #{suite_name}")
43
+ end
44
+
45
+ def create_mediator(suite)
46
+ return TestRunnerMediator.new(suite)
47
+ end
48
+
49
+ def attach_to_mediator
50
+ @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
51
+ @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
52
+ @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
53
+ @mediator.add_listener(TestCase::STARTED, &method(:test_started))
54
+ @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
55
+ end
56
+
57
+ def start_mediator
58
+ return @mediator.run_suite
59
+ end
60
+
61
+ def add_fault(fault)
62
+ @faults << fault
63
+ output_single(fault.single_character_display, PROGRESS_ONLY)
64
+ @already_outputted = true
65
+ end
66
+
67
+ def started(result)
68
+ @result = result
69
+ output("Started")
70
+ end
71
+
72
+ def finished(elapsed_time)
73
+ nl
74
+ output("Finished in #{elapsed_time} seconds.")
75
+ @faults.each_with_index do |fault, index|
76
+ nl
77
+ output("%3d) %s" % [index + 1, fault.long_display])
78
+ end
79
+ nl
80
+ output(@result)
81
+ end
82
+
83
+ def test_started(name)
84
+ output_single(name + ": ", VERBOSE)
85
+ end
86
+
87
+ def test_finished(name)
88
+ output_single(".", PROGRESS_ONLY) unless (@already_outputted)
89
+ nl(VERBOSE)
90
+ @already_outputted = false
91
+ end
92
+
93
+ def nl(level=NORMAL)
94
+ output("", level)
95
+ end
96
+
97
+ def output(something, level=NORMAL)
98
+ @io.puts(something) if (output?(level))
99
+ @io.flush
100
+ end
101
+
102
+ def output_single(something, level=NORMAL)
103
+ @io.write(something) if (output?(level))
104
+ @io.flush
105
+ end
106
+
107
+ def output?(level)
108
+ level <= @output_level
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ if __FILE__ == $0
117
+ Screw::Unit::UI::Console::TestRunner.start_command_line_test
118
+ end