specdown 0.1.4 → 0.1.5

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 (38) hide show
  1. data/CHANGELOG.markdown +6 -0
  2. data/README.markdown +18 -10
  3. data/features/command.feature +2 -2
  4. data/features/config.feature +22 -11
  5. data/features/exception_facade.feature +46 -0
  6. data/features/report_summary.feature +61 -0
  7. data/features/{report.feature → reporter.feature} +19 -18
  8. data/features/reporter_factory.feature +63 -0
  9. data/features/runner.feature +1 -1
  10. data/features/specdown_examples/after_hooks/specdown/env.rb +1 -0
  11. data/features/specdown_examples/around_hooks/specdown/env.rb +1 -0
  12. data/features/specdown_examples/before_hooks/specdown/env.rb +1 -0
  13. data/features/specdown_examples/nested_directories_test/specdown/env.rb +1 -0
  14. data/features/specdown_examples/no_ruby/specdown/env.rb +1 -0
  15. data/features/specdown_examples/scoped_hooks/specdown/env.rb +1 -0
  16. data/features/specdown_examples/with_ruby/specdown/env.rb +1 -0
  17. data/features/step_definitions/config.rb +5 -2
  18. data/features/step_definitions/exception_facade.rb +16 -0
  19. data/features/step_definitions/report_summary.rb +3 -0
  20. data/features/step_definitions/{report.rb → reporter.rb} +8 -0
  21. data/features/step_definitions/reporter_factory.rb +39 -0
  22. data/lib/specdown/config.rb +8 -1
  23. data/lib/specdown/event_handlers/command_complete.rb +1 -2
  24. data/lib/specdown/event_handlers/test_failed.rb +1 -1
  25. data/lib/specdown/event_handlers/test_passed.rb +1 -1
  26. data/lib/specdown/reporter/color_terminal_reporter.rb +29 -0
  27. data/lib/specdown/reporter/terminal_reporter.rb +40 -0
  28. data/lib/specdown/reporter_factory.rb +18 -0
  29. data/lib/specdown/runner/exception_facade.rb +24 -0
  30. data/lib/specdown/runner/report_summary.rb +29 -0
  31. data/lib/specdown/runner/reporter.rb +27 -0
  32. data/lib/specdown/runner.rb +1 -1
  33. data/lib/specdown/specdown.rb +4 -0
  34. data/lib/specdown/templates/color_summary.erb +15 -0
  35. data/lib/specdown/templates/summary.erb +14 -0
  36. data/lib/specdown.rb +8 -1
  37. metadata +50 -13
  38. data/lib/specdown/runner/report.rb +0 -46
data/CHANGELOG.markdown CHANGED
@@ -1,5 +1,11 @@
1
1
  ## CHANGELOG
2
2
 
3
+ ## 0.1.5
4
+
5
+ Terminal output is now colorized, by default. To turn it off, add the following to your env.rb:
6
+
7
+ Specdown::Config.reporter = :terminal
8
+
3
9
  ## 0.1.4
4
10
 
5
11
  The `specdown` command now allows you to pass off directories of tests as well as individual tests.
data/README.markdown CHANGED
@@ -36,13 +36,16 @@ This is our very first test. It's going to blow your mind.
36
36
 
37
37
  Ok, if you've been following along, then `ls -R` should return the following directory structure:
38
38
 
39
- $ ls -R
40
-
41
- specdown/
42
- example.markdown
39
+ ```sh
40
+ $ ls -R
41
+
42
+ specdown/
43
+ example.markdown
44
+ ```
43
45
 
44
46
  Great. Now run the `specdown` command:
45
47
 
48
+ ```sh
46
49
  $ specdown
47
50
 
48
51
  .
@@ -50,6 +53,7 @@ Great. Now run the `specdown` command:
50
53
  1 markdown
51
54
  1 test
52
55
  0 failures
56
+ ```
53
57
 
54
58
  Booya!
55
59
 
@@ -89,16 +93,19 @@ Read through that. I'm giving you some important scoping hints in it.
89
93
 
90
94
  Save it, run it.
91
95
 
92
- $ specdown
96
+ ```sh
97
+ $ specdown
93
98
 
94
- ..
95
-
96
- 1 markdown
97
- 2 tests
98
- 0 failures
99
+ ..
100
+
101
+ 1 markdown
102
+ 2 tests
103
+ 0 failures
104
+ ```
99
105
 
100
106
  Notice how the headers in your markdown form a tree?
101
107
 
108
+ ```sh
102
109
  #Our first test!
103
110
  / \
104
111
  / \
@@ -112,6 +119,7 @@ Notice how the headers in your markdown form a tree?
112
119
  /
113
120
  /
114
121
  ###A sub subsection
122
+ ```
115
123
 
116
124
  Specdown turned that tree into two tests. The first test (#Our first test! --> ##A Subsection --> ###A sub subsection):
117
125
 
@@ -91,8 +91,8 @@ Feature: `specdown` command
91
91
  2 tests
92
92
  2 failures
93
93
 
94
- In parser_example.markdown: <NoMethodError> undefined method `be'
95
- In parser_example.markdown: <NoMethodError> undefined method `satisfy'
94
+ In parser_example.markdown: <#NoMethodError> undefined method `be'
95
+ In parser_example.markdown: <#NoMethodError> undefined method `satisfy'
96
96
  """
97
97
 
98
98
 
@@ -35,12 +35,29 @@ Feature: Specdown::Config
35
35
  assert_equal 1, 1
36
36
  end
37
37
 
38
+ \### Colorized Terminal Output
38
39
 
39
- Scenario: Reset the Specdown::Config
40
+ By default, Specdown will colorize your terminal output. If you'd prefer Specdown not to colorize your terminal output, simply set the `reporter` to `:terminal`:
41
+
42
+ Specdown.reporter == :terminal
43
+
44
+ \## Other reporting formats
45
+
46
+ If you prefer that specdown not output your test results to STDOUT, you can choose two other formats: `:text` and `:html`.
40
47
 
48
+
49
+ Scenario: Specdown::Config defaults
50
+ * Specdown::Config.expectations #==> nil
51
+ * Specdown::Config.reporter #==> :color_terminal
52
+ * Specdown::Config.root #==> "specdown"
53
+
54
+
55
+ Scenario: Reset the Specdown::Config
41
56
  Given I have configured Specdown:
42
57
  """
43
58
  Specdown::Config.expectations = :rspec
59
+ Specdown::Config.reporter = :html
60
+ Specdown::Config.root = "dir/"
44
61
  """
45
62
 
46
63
  When I reset Specdown:
@@ -48,11 +65,10 @@ Feature: Specdown::Config
48
65
  Specdown::Config.reset!
49
66
  """
50
67
 
51
- Then my specdown configuration should return to it's defaults:
52
- """
53
- Specdown::Config.expectations.should be(nil)
54
- """
55
-
68
+ Then my specdown configuration should return to its defaults:
69
+ * Specdown::Config.expectations #==> nil
70
+ * Specdown::Config.reporter #==> :color_terminal
71
+ * Specdown::Config.root #==> "specdown"
56
72
 
57
73
  Scenario: Default to Rspec expectations
58
74
 
@@ -89,8 +105,3 @@ Feature: Specdown::Config
89
105
  assert_equal 1, 1
90
106
  end
91
107
  """
92
-
93
-
94
-
95
-
96
-
@@ -0,0 +1,46 @@
1
+ Feature: Specdown::ExceptionFacade
2
+
3
+ A `Specdown::ExceptionFacade` is simply a convenient, no fuss way to retrieve useful information about an exception thrown during a specdown test run. You simply have to supply it with a stat, and the raw exception, and Specdown will do the rest.
4
+
5
+ For example, given the following exception:
6
+
7
+ exception = Exception.new "exception simulation"
8
+
9
+ And given the following fake test_runner:
10
+
11
+ runner = Class.new { attr_accessor :file_name }.new
12
+ runner.file_name = "test_file.markdown"
13
+
14
+ We can now generate an exception facade:
15
+
16
+ exception_facade = Specdown::ExceptionFacade.new exception, runner
17
+
18
+ exception_facade.test_filename.should == "test_file.markdown"
19
+ exception_facade.exception_class.should == Exception
20
+ exception_facade.exception_backtrace.should include("exception simulation")
21
+
22
+
23
+ Scenario: Exception report generated from a test run
24
+ Given the following exception:
25
+ """
26
+ @exception = Exception.new "exception simulation"
27
+ """
28
+
29
+ And the following fake runner:
30
+ """
31
+ @runner = Class.new { attr_accessor :file_name }.new
32
+ @runner.file_name = "test_file.markdown"
33
+ """
34
+
35
+ When I generate an exception facade:
36
+ """
37
+ @exception_facade = Specdown::ExceptionFacade.new @exception, @runner
38
+ """
39
+
40
+ Then it should return all kinds of information about the exception and it's context:
41
+ """
42
+ @exception_facade.test_filename.should == "test_file.markdown"
43
+ @exception_facade.exception_class.should == Exception
44
+ @exception_facade.exception_backtrace.should be(nil)
45
+ """
46
+
@@ -0,0 +1,61 @@
1
+ Feature: Specdown::ReportSummary
2
+
3
+ A `Specdown::ReportSummary` will provide you with aggregate statistical information about your test suite runners.
4
+
5
+ For example, suppose you have several runners that you've executed. You could pass one or more of them off to a `Specdown::ReportSummary` to obtain the aggregate totals:
6
+
7
+ summary = Specdown::ReportSummary.new(runners)
8
+ summary.num_markdowns
9
+ summary.num_tests
10
+ summary.num_failures
11
+ summary.num_successes
12
+
13
+ Scenario: A Specdown::Reporter instantiated with a single stats object
14
+
15
+ Given the following specdown example file located at 'features/fixtures/parser_example.markdown':
16
+ """
17
+ # Specdown Example
18
+
19
+ This is an example specdown file.
20
+
21
+ ## Child Node
22
+
23
+ This section is a child node. It contains some ruby code:
24
+
25
+ "simple code".should_not == nil
26
+
27
+ ### First Leaf
28
+
29
+ This section has a failure simulation:
30
+
31
+ raise "specdown error simulation!"
32
+
33
+ ## Last Leaf
34
+
35
+ This section is a leaf node. It contains some ruby code:
36
+
37
+ 1.should == 1
38
+ """
39
+
40
+ And the following runner:
41
+ """
42
+ @runner = Specdown::Runner.new("features/fixtures/parser_example.markdown")
43
+ """
44
+
45
+ When I run the tests in the runner:
46
+ """
47
+ @runner.run
48
+ """
49
+
50
+ Then `Specdown::ReportSummary.new(@runner)` should give me aggregate statistics about my run:
51
+ """
52
+ summary = Specdown::ReportSummary.new(@runner)
53
+ summary.num_markdowns.should == 1
54
+ summary.num_tests.should == 2
55
+ summary.num_failures.should == 1
56
+ summary.num_successes.should == 1
57
+ summary.exceptions.count.should == 1
58
+ summary.exceptions.first.test_filename.should == "parser_example.markdown"
59
+ summary.exceptions.first.exception_class.should == RuntimeError
60
+ summary.exceptions.first.exception_message.should include("specdown error simulation!")
61
+ """
@@ -1,7 +1,6 @@
1
- Feature: Report
1
+ Feature: Reporter
2
2
 
3
- Specdown comes with a generic reporting class. If you provide it with a runner (or an array of runners), then it will generate a report for you.
4
-
3
+ Specdown comes with a generic reporting class. By itself, the Specdown::Reporter does little (most methods throw a `NotImplementedError` exception). However, the `Specdown::ReporterFactory` will generate an instance of this class, then decorate based on your configuration.
5
4
 
6
5
  For example, suppose we have the following markdown file:
7
6
 
@@ -32,19 +31,17 @@ Feature: Report
32
31
  runner = Specdown::Runner.new("/features/fixtures/parser_example.markdown")
33
32
  runner.run
34
33
 
35
- We could then pass it off to our reporter class and receive the following report:
34
+ We could then retrieve a report summary like so:
36
35
 
37
- Specdown::Report.new(runner).generate.should == %{
38
- 1 markdown
39
- 3 tests
40
- 2 successes
41
- 1 failure
36
+ Specdown::Reporter.new.summary(runner).class.should == Specdown::ReportSummary
42
37
 
43
- StandardError: error simulation
44
- %}
38
+ The generic reporter doesn't actually print anything:
39
+
40
+ proc { Specdown::Reporter.new.print_summary(runner) }.should raise_exception(NotImplementedError)
41
+ proc { Specdown::Reporter.new.print_success(test) }.should raise_exception(NotImplementedError)
42
+ proc { Specdown::Reporter.new.print_failure(test) }.should raise_exception(NotImplementedError)
45
43
 
46
-
47
- Scenario: A Specdown::Report instantiated with a single stats object
44
+ Scenario: A Specdown::Reporter instantiated with a single stats object
48
45
 
49
46
  Given the following specdown example file located at 'features/fixtures/parser_example.markdown':
50
47
  """
@@ -81,11 +78,15 @@ Feature: Report
81
78
  @runner.run
82
79
  """
83
80
 
84
- Then `Specdown::Report.new(@runner).generate` should include the following output:
81
+ Then `Specdown::Reporter.new.summary(@runner)` should return a report summary object:
82
+ """
83
+ @reporter = Specdown::Reporter.new
84
+ @reporter.summary(@runner).class.should == Specdown::ReportSummary
85
85
  """
86
- 1 markdown
87
- 2 tests
88
- 1 failure
89
86
 
90
- error simulation
87
+ And the generic reporter shouldn't actually print anything:
88
+ """
89
+ proc { @reporter.print_summary(nil) }.should raise_exception(NotImplementedError)
90
+ proc { @reporter.print_success(nil) }.should raise_exception(NotImplementedError)
91
+ proc { @reporter.print_failure(nil) }.should raise_exception(NotImplementedError)
91
92
  """
@@ -0,0 +1,63 @@
1
+ Feature: Specdown::ReporterFactory
2
+
3
+ The `Specdown::ReporterFactory` will generate a `Specdown::Reporter` instance, then decorate it in various ways depending on your specdown configuration.
4
+
5
+ The `Specdown::ReporterFactory` has an API that allows you to configure new decorators for reports. Use the `Specdown::ReporterFactory.decorate` method:
6
+
7
+ Specdown::ReporterFactory.decorate do |report|
8
+ if Specdown::Config.reporter == :color_terminal
9
+ report.extend MyDecoratorModule
10
+ end
11
+ end
12
+
13
+ For example, if you configure specdown to output colorized terminal output (the default value for Specdown::Config.reporter, :color_terminal), then `Specdown::ReporterFactory` will mix the `Specdown::AnsiColor` decorator into your `Specdown::Reporter` instance.
14
+
15
+ Specdown::Config.reporter = :color_terminal
16
+ Specdown::ReporterFactory.generate.ancestors.should include(Specdown::AnsiColor)
17
+
18
+
19
+ Scenario: Adding a new decorator to Specdown::ReporterFactory
20
+
21
+ Given I have added the following decorator to `Specdown::ReporterFactory`:
22
+ """
23
+ Specdown::ReporterFactory.decorate do |reporter|
24
+ module FactoryTester
25
+ end
26
+
27
+ reporter.extend FactoryTester
28
+
29
+ reporter
30
+ end
31
+ """
32
+
33
+ Then reporters should be decorated with my new decorator:
34
+ """
35
+ Specdown::ReporterFactory.generate.kind_of?(FactoryTester).should be(true)
36
+ """
37
+
38
+
39
+ Scenario: Specdown::Config.reporter = :terminal
40
+
41
+ Given that I want a non-colorized text output report:
42
+ """
43
+ Specdown::Config.reporter = :terminal
44
+ """
45
+
46
+ Then `Specdown::ReporterFactory.generate` should return a `Specdown::Reporter` decorated with `Specdown::TerminalReporter`:
47
+ """
48
+ Specdown::ReporterFactory.generate.kind_of?(Specdown::TerminalReporter).should be(true)
49
+ """
50
+
51
+
52
+ Scenario: Specdown::Config.reporter = :color_terminal
53
+
54
+ Given that I want a colorized Specdown::Reporter:
55
+ """
56
+ Specdown::Config.reporter = :color_terminal
57
+ """
58
+
59
+ Then `Specdown::ReporterFactory.generate` should return a `Specdown::Reporter` decorated with `Specdown::TerminalReporter` and `Specdown::ColorTerminalReporter`:
60
+ """
61
+ Specdown::ReporterFactory.generate.kind_of?(Specdown::TerminalReporter).should be(true)
62
+ Specdown::ReporterFactory.generate.kind_of?(Specdown::ColorTerminalReporter).should be(true)
63
+ """
@@ -83,5 +83,5 @@ Feature: Runner
83
83
  @runner.stats.tests.should == 2
84
84
  @runner.stats.failures.should == 1
85
85
  @runner.stats.successes.should == 1
86
- @runner.stats.exceptions.map(&:to_s).should == ["specdown error simulation!"]
86
+ @runner.stats.exceptions.map(&:exception_message).should == ["specdown error simulation!"]
87
87
  """
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :rspec
2
+ Specdown::Config.reporter = :terminal
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :rspec
2
+ Specdown::Config.reporter = :terminal
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :rspec
2
+ Specdown::Config.reporter = :terminal
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :test_unit
2
+ Specdown::Config.reporter = :terminal
@@ -0,0 +1 @@
1
+ Specdown::Config.reporter = :terminal
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :rspec
2
+ Specdown::Config.reporter = :terminal
@@ -1 +1,2 @@
1
1
  Specdown::Config.expectations = :test_unit
2
+ Specdown::Config.reporter = :terminal
@@ -6,8 +6,7 @@ When /^I reset Specdown:$/ do |string|
6
6
  eval string
7
7
  end
8
8
 
9
- Then /^my specdown configuration should return to it's defaults:$/ do |string|
10
- eval string
9
+ Then /^my specdown configuration should return to its defaults:$/ do
11
10
  end
12
11
 
13
12
  Given /^I have rspec installed$/ do
@@ -32,3 +31,7 @@ end
32
31
  Then /^Specdown should provide Test::Unit assertions within the sandbox:$/ do |string|
33
32
  eval string
34
33
  end
34
+
35
+ Given /^Specdown::Config\.([^\ ]+)\ *#==>\ *(.*)$/ do |config_key, default_value|
36
+ Specdown::Config.send(config_key).should == eval(default_value)
37
+ end
@@ -0,0 +1,16 @@
1
+
2
+ Given /^the following exception:$/ do |string|
3
+ eval string
4
+ end
5
+
6
+ Given /^the following fake runner:$/ do |string|
7
+ eval string
8
+ end
9
+
10
+ When /^I generate an exception facade:$/ do |string|
11
+ eval string
12
+ end
13
+
14
+ Then /^it should return all kinds of information about the exception and it's context:$/ do |string|
15
+ eval string
16
+ end
@@ -0,0 +1,3 @@
1
+ Then /^`Specdown::ReportSummary\.new\(@runner\)` should give me aggregate statistics about my run:$/ do |string|
2
+ eval string
3
+ end
@@ -16,3 +16,11 @@ end
16
16
  Given /^the following of Specdown::Stats instances:$/ do |string|
17
17
  eval string
18
18
  end
19
+
20
+ Then /^`Specdown::Reporter\.new\.summary\(@runner\)` should return a report summary object:$/ do |string|
21
+ eval string
22
+ end
23
+
24
+ Then /^the generic reporter shouldn't actually print anything:$/ do |string|
25
+ eval string
26
+ end
@@ -0,0 +1,39 @@
1
+ Given /^that I want a non\-colorized text output report:$/ do |string|
2
+ eval string
3
+ end
4
+
5
+ Then /^`Specdown::ReporterFactory\.generate` should return a undecorated `Specdown::Reporter`:$/ do |string|
6
+ eval string
7
+ end
8
+
9
+ Given /^that I want a colorized Specdown::Reporter:$/ do |string|
10
+ eval string
11
+ end
12
+
13
+ Then /^`Specdown::ReporterFactory\.generate` should return a `Specdown::Reporter` decorated with `Specdown::AnsiColor`$/ do |string|
14
+ eval string
15
+ end
16
+
17
+ Given /^that I want an html report:$/ do |string|
18
+ eval string
19
+ end
20
+
21
+ Then /^`Specdown::ReporterFactory\.generate` should return a `Specdown::Reporter` decorated with `Specdown::HtmlReporter`$/ do |string|
22
+ eval string
23
+ end
24
+
25
+ Given /^I have added the following decorator to `Specdown::ReporterFactory`:$/ do |string|
26
+ eval string
27
+ end
28
+
29
+ Then /^reporters should be decorated with my new decorator:$/ do |string|
30
+ eval string
31
+ end
32
+
33
+ Then /^`Specdown::ReporterFactory\.generate` should return a `Specdown::Reporter` decorated with `Specdown::TerminalReporter`:$/ do |string|
34
+ eval string
35
+ end
36
+
37
+ Then /^`Specdown::ReporterFactory\.generate` should return a `Specdown::Reporter` decorated with `Specdown::TerminalReporter` and `Specdown::ColorTerminalReporter`:$/ do |string|
38
+ eval string
39
+ end
@@ -5,9 +5,16 @@ module Specdown
5
5
  attr_accessor :expectations
6
6
  attr_accessor :tests
7
7
  attr_accessor :root
8
+ attr_accessor :reporter
9
+
10
+ def reporter
11
+ @reporter ||= :color_terminal
12
+ end
8
13
 
9
14
  def reset!
10
- self.expectations = nil
15
+ @expectations = nil
16
+ @reporter = nil
17
+ @root = nil
11
18
  end
12
19
 
13
20
  def root
@@ -1,4 +1,3 @@
1
1
  Specdown::EventServer.register :command_complete do |results|
2
- puts "\n\n"
3
- puts Specdown::Report.new(results).generate
2
+ Specdown.reporter.print_summary(results)
4
3
  end
@@ -1,3 +1,3 @@
1
1
  Specdown::EventServer.register :test_failed do
2
- print "F"
2
+ Specdown.reporter.print_failure nil
3
3
  end
@@ -1,3 +1,3 @@
1
1
  Specdown::EventServer.register :test_passed do
2
- print "."
2
+ Specdown.reporter.print_success nil
3
3
  end
@@ -0,0 +1,29 @@
1
+ module Specdown
2
+ module ColorTerminalReporter
3
+ def success
4
+ super.green
5
+ end
6
+
7
+ def failure
8
+ super.red.bold
9
+ end
10
+
11
+ private
12
+ def template
13
+ ERB.new File.read(File.join(File.dirname(__FILE__), "../templates/color_summary.erb"))
14
+ end
15
+ end
16
+ end
17
+
18
+ Specdown::ReporterFactory.decorate do |reporter|
19
+ if Specdown::Config.reporter == :color_terminal
20
+ class ::String
21
+ include ::Term::ANSIColor
22
+ end
23
+
24
+ reporter.extend Specdown::TerminalReporter
25
+ reporter.extend Specdown::ColorTerminalReporter
26
+ end
27
+
28
+ reporter
29
+ end
@@ -0,0 +1,40 @@
1
+ module Specdown
2
+ module TerminalReporter
3
+ def success
4
+ "."
5
+ end
6
+
7
+ def failure
8
+ "F"
9
+ end
10
+
11
+ def print_success(test)
12
+ print success
13
+ end
14
+
15
+ def print_failure(test)
16
+ print failure
17
+ end
18
+
19
+ def print_summary(runners)
20
+ @report_summary = summary(runners)
21
+ template.run(proc {})
22
+ end
23
+
24
+ private
25
+ def template
26
+ ERB.new File.read(File.join(File.dirname(__FILE__), "../templates/summary.erb"))
27
+ end
28
+
29
+ def format_stat(word, number)
30
+ "#{number} #{number == 1 ? word : word + "s"}"
31
+ end
32
+ end
33
+ end
34
+
35
+ Specdown::ReporterFactory.decorate do |reporter|
36
+ if Specdown::Config.reporter == :terminal
37
+ reporter.extend Specdown::TerminalReporter
38
+ end
39
+ reporter
40
+ end
@@ -0,0 +1,18 @@
1
+ module Specdown
2
+ module ReporterFactory
3
+ extend self
4
+
5
+ def decorate(&block)
6
+ decorators << block
7
+ end
8
+
9
+ def generate
10
+ decorators.inject(Reporter.new) {|reporter, decorator| decorator.call(reporter) }
11
+ end
12
+
13
+ private
14
+ def decorators
15
+ @decorators ||= []
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module Specdown
2
+ class ExceptionFacade
3
+ def initialize(exception, runner)
4
+ @exception = exception
5
+ @runner = runner
6
+ end
7
+
8
+ def exception_class
9
+ @exception.class
10
+ end
11
+
12
+ def exception_backtrace
13
+ @exception.backtrace
14
+ end
15
+
16
+ def exception_message
17
+ @exception.to_s
18
+ end
19
+
20
+ def test_filename
21
+ @runner.file_name
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module Specdown
2
+ class ReportSummary
3
+ attr_reader :runners
4
+
5
+ def initialize(runners)
6
+ @runners = runners.respond_to?(:map) ? runners : [runners]
7
+ end
8
+
9
+ def num_markdowns
10
+ @num_markdowns ||= @runners.count
11
+ end
12
+
13
+ def num_tests
14
+ @num_tests ||= @runners.map(&:stats).map(&:tests).inject(0, &:+)
15
+ end
16
+
17
+ def num_failures
18
+ @num_failures ||= @runners.map(&:stats).map(&:failures).inject(0, &:+)
19
+ end
20
+
21
+ def num_successes
22
+ @num_successes ||= @runners.map(&:stats).map(&:successes).inject(0, &:+)
23
+ end
24
+
25
+ def exceptions
26
+ @exceptions ||= @runners.map(&:stats).map(&:exceptions).flatten
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Specdown
2
+ class Reporter
3
+ def summary(runners)
4
+ ReportSummary.new(runners)
5
+ end
6
+
7
+ def success
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def failure
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def print_summary(runners)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def print_success(test)
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def print_failure(test)
24
+ raise NotImplementedError
25
+ end
26
+ end
27
+ end
@@ -43,7 +43,7 @@ module Specdown
43
43
  EventServer.event :test_passed, self
44
44
 
45
45
  rescue Exception => e
46
- @stats.exceptions << e
46
+ @stats.exceptions << ExceptionFacade.new(e, self)
47
47
 
48
48
  EventServer.event :test_failed, self
49
49
  end
@@ -10,6 +10,10 @@ module Specdown
10
10
  SandboxFactory.generate
11
11
  end
12
12
 
13
+ def reporter
14
+ @reporter ||= ReporterFactory.generate
15
+ end
16
+
13
17
  def before(*filters, &callback)
14
18
  Hooks.before << Hook.new(*filters, &callback)
15
19
  end
@@ -0,0 +1,15 @@
1
+
2
+
3
+ ---------------------------------------------------------------------------
4
+ <%= format_stat("markdown", @report_summary.num_markdowns).bold %>
5
+ <%= format_stat("test", @report_summary.num_tests).bold %>
6
+ <%= format_stat("success", @report_summary.num_successes).green %>
7
+ <%= format_stat("failure", @report_summary.num_failures).red %>
8
+ ---------------------------------------------------------------------------
9
+
10
+ <% runners.map(&:stats).each do |stat| %>
11
+ <% stat.exceptions.each do |e| %>
12
+ <%= "In #{e.test_filename}".blue.bold %>: <%= "#<#{e.exception_class}>:".red.bold%> <%=e.exception_message%>
13
+ <%= e.exception_backtrace.join("\n").red %>
14
+ <% end %>
15
+ <% end %>
@@ -0,0 +1,14 @@
1
+
2
+
3
+ ---------------------------------------------------------------------------
4
+ <%= format_stat("markdown", @report_summary.num_markdowns) %>
5
+ <%= format_stat("test", @report_summary.num_tests) %>
6
+ <%= format_stat("success", @report_summary.num_successes) %>
7
+ <%= format_stat("failure", @report_summary.num_failures) %>
8
+ ---------------------------------------------------------------------------
9
+ <% runners.map(&:stats).each do |stat| %>
10
+ <% stat.exceptions.each do |e| %>
11
+ In <%=e.test_filename%>: <#<%=e.exception_class%>> <%=e.exception_message%>
12
+ <%= e.exception_backtrace.join "\n" %>
13
+ <% end %>
14
+ <% end %>
data/lib/specdown.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  require 'kramdown'
2
+ require 'term/ansicolor'
3
+ require 'erb'
2
4
  require 'optparse'
3
5
  require 'specdown/parser'
4
6
  require 'specdown/node'
5
7
  require 'specdown/tree'
6
8
  require 'specdown/runner'
7
- require 'specdown/runner/report'
9
+ require 'specdown/runner/reporter'
8
10
  require 'specdown/runner/stats'
9
11
  require 'specdown/command'
10
12
  require 'specdown/event_server'
@@ -21,3 +23,8 @@ require 'specdown/sandbox_factory'
21
23
  require 'specdown/hooks'
22
24
  require 'specdown/hook'
23
25
  require 'specdown/command/option_parser'
26
+ require 'specdown/reporter_factory'
27
+ require 'specdown/runner/report_summary'
28
+ require 'specdown/runner/exception_facade'
29
+ require 'specdown/reporter/terminal_reporter'
30
+ require 'specdown/reporter/color_terminal_reporter'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: specdown
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 4
10
- version: 0.1.4
9
+ - 5
10
+ version: 0.1.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Parker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-04 00:00:00 Z
18
+ date: 2012-01-08 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: kramdown
@@ -34,9 +34,25 @@ dependencies:
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: cucumber
37
+ name: term-ansicolor
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 25
45
+ segments:
46
+ - 1
47
+ - 0
48
+ - 7
49
+ version: 1.0.7
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: cucumber
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
40
56
  none: false
41
57
  requirements:
42
58
  - - ">="
@@ -46,11 +62,11 @@ dependencies:
46
62
  - 0
47
63
  version: "0"
48
64
  type: :development
49
- version_requirements: *id002
65
+ version_requirements: *id003
50
66
  - !ruby/object:Gem::Dependency
51
67
  name: rspec
52
68
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
69
+ requirement: &id004 !ruby/object:Gem::Requirement
54
70
  none: false
55
71
  requirements:
56
72
  - - ">="
@@ -60,7 +76,7 @@ dependencies:
60
76
  - 0
61
77
  version: "0"
62
78
  type: :development
63
- version_requirements: *id003
79
+ version_requirements: *id004
64
80
  description:
65
81
  email: moonmaster9000@gmail.com
66
82
  executables:
@@ -86,11 +102,18 @@ files:
86
102
  - lib/specdown/hooks.rb
87
103
  - lib/specdown/node.rb
88
104
  - lib/specdown/parser.rb
89
- - lib/specdown/runner/report.rb
105
+ - lib/specdown/reporter/color_terminal_reporter.rb
106
+ - lib/specdown/reporter/terminal_reporter.rb
107
+ - lib/specdown/reporter_factory.rb
108
+ - lib/specdown/runner/exception_facade.rb
109
+ - lib/specdown/runner/report_summary.rb
110
+ - lib/specdown/runner/reporter.rb
90
111
  - lib/specdown/runner/stats.rb
91
112
  - lib/specdown/runner.rb
92
113
  - lib/specdown/sandbox_factory.rb
93
114
  - lib/specdown/specdown.rb
115
+ - lib/specdown/templates/color_summary.erb
116
+ - lib/specdown/templates/summary.erb
94
117
  - lib/specdown/tree.rb
95
118
  - lib/specdown.rb
96
119
  - bin/specdown
@@ -99,10 +122,13 @@ files:
99
122
  - features/command.feature
100
123
  - features/config.feature
101
124
  - features/event_server.feature
125
+ - features/exception_facade.feature
102
126
  - features/fixtures/parser_example.markdown
103
127
  - features/hooks.feature
104
128
  - features/parser.feature
105
- - features/report.feature
129
+ - features/report_summary.feature
130
+ - features/reporter.feature
131
+ - features/reporter_factory.feature
106
132
  - features/runner.feature
107
133
  - features/specdown_examples/after_hooks/specdown/env.rb
108
134
  - features/specdown_examples/after_hooks/specdown/hooks.rb
@@ -117,6 +143,7 @@ files:
117
143
  - features/specdown_examples/nested_directories_test/specdown/tests/1.markdown
118
144
  - features/specdown_examples/nested_directories_test/specdown/tests/2.markdown
119
145
  - features/specdown_examples/nested_directories_test/specdown/tests/3.markdown
146
+ - features/specdown_examples/no_ruby/specdown/env.rb
120
147
  - features/specdown_examples/no_ruby/specdown/parser_example.markdown
121
148
  - features/specdown_examples/scoped_hooks/specdown/env.rb
122
149
  - features/specdown_examples/scoped_hooks/specdown/hooks.rb
@@ -129,9 +156,12 @@ files:
129
156
  - features/step_definitions/command.rb
130
157
  - features/step_definitions/config.rb
131
158
  - features/step_definitions/event_server.rb
159
+ - features/step_definitions/exception_facade.rb
132
160
  - features/step_definitions/hooks.rb
133
161
  - features/step_definitions/parser.rb
134
- - features/step_definitions/report.rb
162
+ - features/step_definitions/report_summary.rb
163
+ - features/step_definitions/reporter.rb
164
+ - features/step_definitions/reporter_factory.rb
135
165
  - features/step_definitions/runner.rb
136
166
  - features/support/env.rb
137
167
  - features/support/hooks.rb
@@ -172,10 +202,13 @@ test_files:
172
202
  - features/command.feature
173
203
  - features/config.feature
174
204
  - features/event_server.feature
205
+ - features/exception_facade.feature
175
206
  - features/fixtures/parser_example.markdown
176
207
  - features/hooks.feature
177
208
  - features/parser.feature
178
- - features/report.feature
209
+ - features/report_summary.feature
210
+ - features/reporter.feature
211
+ - features/reporter_factory.feature
179
212
  - features/runner.feature
180
213
  - features/specdown_examples/after_hooks/specdown/env.rb
181
214
  - features/specdown_examples/after_hooks/specdown/hooks.rb
@@ -190,6 +223,7 @@ test_files:
190
223
  - features/specdown_examples/nested_directories_test/specdown/tests/1.markdown
191
224
  - features/specdown_examples/nested_directories_test/specdown/tests/2.markdown
192
225
  - features/specdown_examples/nested_directories_test/specdown/tests/3.markdown
226
+ - features/specdown_examples/no_ruby/specdown/env.rb
193
227
  - features/specdown_examples/no_ruby/specdown/parser_example.markdown
194
228
  - features/specdown_examples/scoped_hooks/specdown/env.rb
195
229
  - features/specdown_examples/scoped_hooks/specdown/hooks.rb
@@ -202,9 +236,12 @@ test_files:
202
236
  - features/step_definitions/command.rb
203
237
  - features/step_definitions/config.rb
204
238
  - features/step_definitions/event_server.rb
239
+ - features/step_definitions/exception_facade.rb
205
240
  - features/step_definitions/hooks.rb
206
241
  - features/step_definitions/parser.rb
207
- - features/step_definitions/report.rb
242
+ - features/step_definitions/report_summary.rb
243
+ - features/step_definitions/reporter.rb
244
+ - features/step_definitions/reporter_factory.rb
208
245
  - features/step_definitions/runner.rb
209
246
  - features/support/env.rb
210
247
  - features/support/hooks.rb
@@ -1,46 +0,0 @@
1
- module Specdown
2
- class Report
3
- def initialize(runners)
4
- runners = [runners] unless runners.respond_to?(:map)
5
- @stats = runners.map &:stats
6
- end
7
-
8
- def generate
9
- [
10
- format_stat("markdown", markdowns),
11
- format_stat("test", tests),
12
- format_stat("failure", failures)
13
- ].join("\n") + "\n\n" + exceptions.join("\n\n")
14
- end
15
-
16
- private
17
- def format_stat(word, number)
18
- "#{number} #{number == 1 ? word : word + "s"}"
19
- end
20
-
21
- def tests
22
- @tests ||= @stats.inject(0) {|sum, stat| sum += stat.tests}
23
- end
24
-
25
- def failures
26
- @failures ||= @stats.inject(0) {|sum, stat| sum += stat.failures}
27
- end
28
-
29
- def markdowns
30
- @stats.count
31
- end
32
-
33
- def exceptions
34
- formatted_exceptions = []
35
- @stats.each do |stat|
36
- formatted_exceptions << stat.exceptions.map do |e|
37
- [
38
- (stat.runner ? "In #{stat.runner.file_name}: " : "") + "<#{e.class}> #{e}",
39
- e.backtrace
40
- ].join "\n"
41
- end
42
- end
43
- formatted_exceptions.flatten
44
- end
45
- end
46
- end