opal-rspec-cj 0.4.4

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 (176) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +15 -0
  4. data/.travis.yml +13 -0
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +25 -0
  7. data/Gemfile +8 -0
  8. data/README.md +147 -0
  9. data/Rakefile +26 -0
  10. data/config.ru +10 -0
  11. data/example/Gemfile +4 -0
  12. data/example/README.md +13 -0
  13. data/example/Rakefile +8 -0
  14. data/example/opal/user.rb +11 -0
  15. data/example/spec/user_spec.rb +15 -0
  16. data/lib/opal-rspec.rb +2 -0
  17. data/lib/opal/rspec.rb +20 -0
  18. data/lib/opal/rspec/rake_task.rb +63 -0
  19. data/lib/opal/rspec/version.rb +5 -0
  20. data/opal-rspec.gemspec +21 -0
  21. data/opal/opal-rspec.rb +1 -0
  22. data/opal/opal/rspec.rb +25 -0
  23. data/opal/opal/rspec/async.rb +289 -0
  24. data/opal/opal/rspec/browser_formatter.rb +188 -0
  25. data/opal/opal/rspec/fixes.rb +116 -0
  26. data/opal/opal/rspec/requires.rb +45 -0
  27. data/opal/opal/rspec/runner.rb +69 -0
  28. data/opal/opal/rspec/sprockets_runner.rb.erb +11 -0
  29. data/opal/opal/rspec/text_formatter.rb +74 -0
  30. data/spec/async_spec.rb +38 -0
  31. data/spec/example_spec.rb +163 -0
  32. data/spec/matchers_spec.rb +201 -0
  33. data/spec/mock_spec.rb +63 -0
  34. data/spec/named_subject_spec.rb +11 -0
  35. data/spec/should_syntax_spec.rb +17 -0
  36. data/vendor/spec_runner.js +50 -0
  37. data/vendor_lib/rspec-expectations.rb +1 -0
  38. data/vendor_lib/rspec.rb +3 -0
  39. data/vendor_lib/rspec/autorun.rb +2 -0
  40. data/vendor_lib/rspec/core.rb +203 -0
  41. data/vendor_lib/rspec/core/backport_random.rb +302 -0
  42. data/vendor_lib/rspec/core/backtrace_formatter.rb +65 -0
  43. data/vendor_lib/rspec/core/command_line.rb +36 -0
  44. data/vendor_lib/rspec/core/configuration.rb +1129 -0
  45. data/vendor_lib/rspec/core/configuration_options.rb +143 -0
  46. data/vendor_lib/rspec/core/drb_command_line.rb +26 -0
  47. data/vendor_lib/rspec/core/drb_options.rb +87 -0
  48. data/vendor_lib/rspec/core/dsl.rb +26 -0
  49. data/vendor_lib/rspec/core/example.rb +312 -0
  50. data/vendor_lib/rspec/core/example_group.rb +540 -0
  51. data/vendor_lib/rspec/core/filter_manager.rb +224 -0
  52. data/vendor_lib/rspec/core/flat_map.rb +17 -0
  53. data/vendor_lib/rspec/core/formatters.rb +54 -0
  54. data/vendor_lib/rspec/core/formatters/base_formatter.rb +291 -0
  55. data/vendor_lib/rspec/core/formatters/base_text_formatter.rb +307 -0
  56. data/vendor_lib/rspec/core/formatters/deprecation_formatter.rb +193 -0
  57. data/vendor_lib/rspec/core/formatters/documentation_formatter.rb +67 -0
  58. data/vendor_lib/rspec/core/formatters/helpers.rb +82 -0
  59. data/vendor_lib/rspec/core/formatters/html_formatter.rb +155 -0
  60. data/vendor_lib/rspec/core/formatters/html_printer.rb +408 -0
  61. data/vendor_lib/rspec/core/formatters/json_formatter.rb +99 -0
  62. data/vendor_lib/rspec/core/formatters/progress_formatter.rb +32 -0
  63. data/vendor_lib/rspec/core/formatters/snippet_extractor.rb +101 -0
  64. data/vendor_lib/rspec/core/hooks.rb +535 -0
  65. data/vendor_lib/rspec/core/memoized_helpers.rb +431 -0
  66. data/vendor_lib/rspec/core/metadata.rb +313 -0
  67. data/vendor_lib/rspec/core/mocking/with_absolutely_nothing.rb +11 -0
  68. data/vendor_lib/rspec/core/mocking/with_flexmock.rb +27 -0
  69. data/vendor_lib/rspec/core/mocking/with_mocha.rb +52 -0
  70. data/vendor_lib/rspec/core/mocking/with_rr.rb +27 -0
  71. data/vendor_lib/rspec/core/mocking/with_rspec.rb +27 -0
  72. data/vendor_lib/rspec/core/option_parser.rb +234 -0
  73. data/vendor_lib/rspec/core/ordering.rb +154 -0
  74. data/vendor_lib/rspec/core/pending.rb +110 -0
  75. data/vendor_lib/rspec/core/project_initializer.rb +88 -0
  76. data/vendor_lib/rspec/core/rake_task.rb +128 -0
  77. data/vendor_lib/rspec/core/reporter.rb +132 -0
  78. data/vendor_lib/rspec/core/ruby_project.rb +44 -0
  79. data/vendor_lib/rspec/core/runner.rb +97 -0
  80. data/vendor_lib/rspec/core/shared_context.rb +53 -0
  81. data/vendor_lib/rspec/core/shared_example_group.rb +146 -0
  82. data/vendor_lib/rspec/core/shared_example_group/collection.rb +27 -0
  83. data/vendor_lib/rspec/core/version.rb +7 -0
  84. data/vendor_lib/rspec/core/warnings.rb +22 -0
  85. data/vendor_lib/rspec/core/world.rb +131 -0
  86. data/vendor_lib/rspec/expectations.rb +75 -0
  87. data/vendor_lib/rspec/expectations/differ.rb +154 -0
  88. data/vendor_lib/rspec/expectations/errors.rb +9 -0
  89. data/vendor_lib/rspec/expectations/expectation_target.rb +87 -0
  90. data/vendor_lib/rspec/expectations/extensions.rb +1 -0
  91. data/vendor_lib/rspec/expectations/extensions/object.rb +29 -0
  92. data/vendor_lib/rspec/expectations/fail_with.rb +79 -0
  93. data/vendor_lib/rspec/expectations/handler.rb +68 -0
  94. data/vendor_lib/rspec/expectations/syntax.rb +182 -0
  95. data/vendor_lib/rspec/expectations/version.rb +8 -0
  96. data/vendor_lib/rspec/matchers.rb +633 -0
  97. data/vendor_lib/rspec/matchers/built_in.rb +39 -0
  98. data/vendor_lib/rspec/matchers/built_in/base_matcher.rb +68 -0
  99. data/vendor_lib/rspec/matchers/built_in/be.rb +213 -0
  100. data/vendor_lib/rspec/matchers/built_in/be_instance_of.rb +15 -0
  101. data/vendor_lib/rspec/matchers/built_in/be_kind_of.rb +11 -0
  102. data/vendor_lib/rspec/matchers/built_in/be_within.rb +55 -0
  103. data/vendor_lib/rspec/matchers/built_in/change.rb +141 -0
  104. data/vendor_lib/rspec/matchers/built_in/cover.rb +21 -0
  105. data/vendor_lib/rspec/matchers/built_in/eq.rb +22 -0
  106. data/vendor_lib/rspec/matchers/built_in/eql.rb +23 -0
  107. data/vendor_lib/rspec/matchers/built_in/equal.rb +48 -0
  108. data/vendor_lib/rspec/matchers/built_in/exist.rb +26 -0
  109. data/vendor_lib/rspec/matchers/built_in/has.rb +48 -0
  110. data/vendor_lib/rspec/matchers/built_in/include.rb +61 -0
  111. data/vendor_lib/rspec/matchers/built_in/match.rb +17 -0
  112. data/vendor_lib/rspec/matchers/built_in/match_array.rb +51 -0
  113. data/vendor_lib/rspec/matchers/built_in/raise_error.rb +154 -0
  114. data/vendor_lib/rspec/matchers/built_in/respond_to.rb +74 -0
  115. data/vendor_lib/rspec/matchers/built_in/satisfy.rb +30 -0
  116. data/vendor_lib/rspec/matchers/built_in/start_and_end_with.rb +48 -0
  117. data/vendor_lib/rspec/matchers/built_in/throw_symbol.rb +94 -0
  118. data/vendor_lib/rspec/matchers/built_in/yield.rb +297 -0
  119. data/vendor_lib/rspec/matchers/compatibility.rb +14 -0
  120. data/vendor_lib/rspec/matchers/configuration.rb +113 -0
  121. data/vendor_lib/rspec/matchers/dsl.rb +23 -0
  122. data/vendor_lib/rspec/matchers/generated_descriptions.rb +35 -0
  123. data/vendor_lib/rspec/matchers/matcher.rb +301 -0
  124. data/vendor_lib/rspec/matchers/method_missing.rb +12 -0
  125. data/vendor_lib/rspec/matchers/operator_matcher.rb +99 -0
  126. data/vendor_lib/rspec/matchers/pretty.rb +70 -0
  127. data/vendor_lib/rspec/matchers/test_unit_integration.rb +11 -0
  128. data/vendor_lib/rspec/mocks.rb +100 -0
  129. data/vendor_lib/rspec/mocks/any_instance/chain.rb +92 -0
  130. data/vendor_lib/rspec/mocks/any_instance/expectation_chain.rb +47 -0
  131. data/vendor_lib/rspec/mocks/any_instance/message_chains.rb +75 -0
  132. data/vendor_lib/rspec/mocks/any_instance/recorder.rb +200 -0
  133. data/vendor_lib/rspec/mocks/any_instance/stub_chain.rb +45 -0
  134. data/vendor_lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
  135. data/vendor_lib/rspec/mocks/argument_list_matcher.rb +104 -0
  136. data/vendor_lib/rspec/mocks/argument_matchers.rb +264 -0
  137. data/vendor_lib/rspec/mocks/arity_calculator.rb +66 -0
  138. data/vendor_lib/rspec/mocks/configuration.rb +111 -0
  139. data/vendor_lib/rspec/mocks/error_generator.rb +203 -0
  140. data/vendor_lib/rspec/mocks/errors.rb +12 -0
  141. data/vendor_lib/rspec/mocks/example_methods.rb +201 -0
  142. data/vendor_lib/rspec/mocks/extensions/marshal.rb +17 -0
  143. data/vendor_lib/rspec/mocks/framework.rb +36 -0
  144. data/vendor_lib/rspec/mocks/instance_method_stasher.rb +112 -0
  145. data/vendor_lib/rspec/mocks/matchers/have_received.rb +99 -0
  146. data/vendor_lib/rspec/mocks/matchers/receive.rb +112 -0
  147. data/vendor_lib/rspec/mocks/matchers/receive_messages.rb +72 -0
  148. data/vendor_lib/rspec/mocks/message_expectation.rb +643 -0
  149. data/vendor_lib/rspec/mocks/method_double.rb +209 -0
  150. data/vendor_lib/rspec/mocks/method_reference.rb +95 -0
  151. data/vendor_lib/rspec/mocks/mock.rb +7 -0
  152. data/vendor_lib/rspec/mocks/mutate_const.rb +406 -0
  153. data/vendor_lib/rspec/mocks/object_reference.rb +90 -0
  154. data/vendor_lib/rspec/mocks/order_group.rb +82 -0
  155. data/vendor_lib/rspec/mocks/proxy.rb +269 -0
  156. data/vendor_lib/rspec/mocks/proxy_for_nil.rb +37 -0
  157. data/vendor_lib/rspec/mocks/space.rb +95 -0
  158. data/vendor_lib/rspec/mocks/standalone.rb +3 -0
  159. data/vendor_lib/rspec/mocks/stub_chain.rb +51 -0
  160. data/vendor_lib/rspec/mocks/syntax.rb +374 -0
  161. data/vendor_lib/rspec/mocks/targets.rb +90 -0
  162. data/vendor_lib/rspec/mocks/test_double.rb +109 -0
  163. data/vendor_lib/rspec/mocks/verifying_double.rb +77 -0
  164. data/vendor_lib/rspec/mocks/verifying_message_expecation.rb +60 -0
  165. data/vendor_lib/rspec/mocks/verifying_proxy.rb +151 -0
  166. data/vendor_lib/rspec/mocks/version.rb +7 -0
  167. data/vendor_lib/rspec/support.rb +6 -0
  168. data/vendor_lib/rspec/support/caller_filter.rb +56 -0
  169. data/vendor_lib/rspec/support/spec.rb +14 -0
  170. data/vendor_lib/rspec/support/spec/deprecation_helpers.rb +29 -0
  171. data/vendor_lib/rspec/support/spec/in_sub_process.rb +40 -0
  172. data/vendor_lib/rspec/support/spec/stderr_splitter.rb +50 -0
  173. data/vendor_lib/rspec/support/version.rb +7 -0
  174. data/vendor_lib/rspec/support/warnings.rb +41 -0
  175. data/vendor_lib/rspec/version.rb +5 -0
  176. metadata +268 -0
@@ -0,0 +1,67 @@
1
+ require 'rspec/core/formatters/base_text_formatter'
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ class DocumentationFormatter < BaseTextFormatter
7
+ def initialize(output)
8
+ super(output)
9
+ @group_level = 0
10
+ end
11
+
12
+ def example_group_started(example_group)
13
+ super(example_group)
14
+
15
+ output.puts if @group_level == 0
16
+ output.puts "#{current_indentation}#{example_group.description.strip}"
17
+
18
+ @group_level += 1
19
+ end
20
+
21
+ def example_group_finished(example_group)
22
+ @group_level -= 1
23
+ end
24
+
25
+ def example_passed(example)
26
+ super(example)
27
+ output.puts passed_output(example)
28
+ end
29
+
30
+ def example_pending(example)
31
+ super(example)
32
+ output.puts pending_output(example, example.execution_result[:pending_message])
33
+ end
34
+
35
+ def example_failed(example)
36
+ super(example)
37
+ output.puts failure_output(example, example.execution_result[:exception])
38
+ end
39
+
40
+ def failure_output(example, exception)
41
+ failure_color("#{current_indentation}#{example.description.strip} (FAILED - #{next_failure_index})")
42
+ end
43
+
44
+ def next_failure_index
45
+ @next_failure_index ||= 0
46
+ @next_failure_index += 1
47
+ end
48
+
49
+ def passed_output(example)
50
+ success_color("#{current_indentation}#{example.description.strip}")
51
+ end
52
+
53
+ def pending_output(example, message)
54
+ pending_color("#{current_indentation}#{example.description.strip} (PENDING: #{message})")
55
+ end
56
+
57
+ def current_indentation
58
+ ' ' * @group_level
59
+ end
60
+
61
+ def example_group_chain
62
+ example_group.parent_groups.reverse
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,82 @@
1
+ module RSpec
2
+ module Core
3
+ module Formatters
4
+ module Helpers
5
+ SUB_SECOND_PRECISION = 5
6
+ DEFAULT_PRECISION = 2
7
+
8
+ # @api private
9
+ #
10
+ # Formats seconds into a human-readable string.
11
+ #
12
+ # @param [Float, Fixnum] duration in seconds
13
+ # @return [String] human-readable time
14
+ #
15
+ # @example
16
+ # format_duration(1) #=> "1 minute 1 second"
17
+ # format_duration(135.14) #=> "2 minutes 15.14 seconds"
18
+ def format_duration(duration)
19
+ precision = case
20
+ when duration < 1; SUB_SECOND_PRECISION
21
+ when duration < 120; DEFAULT_PRECISION
22
+ when duration < 300; 1
23
+ else 0
24
+ end
25
+
26
+ if duration > 60
27
+ minutes = (duration.to_i / 60).to_i
28
+ seconds = duration - minutes * 60
29
+
30
+ "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds, precision), 'second')}"
31
+ else
32
+ pluralize(format_seconds(duration, precision), 'second')
33
+ end
34
+ end
35
+
36
+ # @api private
37
+ #
38
+ # Formats seconds to have 5 digits of precision with trailing zeros removed if the number
39
+ # is less than 1 or with 2 digits of precision if the number is greater than zero.
40
+ #
41
+ # @param [Float] float
42
+ # @return [String] formatted float
43
+ #
44
+ # @example
45
+ # format_seconds(0.000006) #=> "0.00001"
46
+ # format_seconds(0.020000) #=> "0.02"
47
+ # format_seconds(1.00000000001) #=> "1"
48
+ #
49
+ # The precision used is set in {Helpers::SUB_SECOND_PRECISION} and {Helpers::DEFAULT_PRECISION}.
50
+ #
51
+ # @see #strip_trailing_zeroes
52
+ def format_seconds(float, precision = nil)
53
+ precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION
54
+ formatted = sprintf("%.#{precision}f", float)
55
+ strip_trailing_zeroes(formatted)
56
+ end
57
+
58
+ # @api private
59
+ #
60
+ # Remove trailing zeros from a string.
61
+ #
62
+ # @param [String] string string with trailing zeros
63
+ # @return [String] string with trailing zeros removed
64
+ def strip_trailing_zeroes(string)
65
+ stripped = string.sub(/[^1-9]+$/, '')
66
+ stripped.empty? ? "0" : stripped
67
+ end
68
+
69
+ # @api private
70
+ #
71
+ # Pluralize a word based on a count.
72
+ #
73
+ # @param [Fixnum] count number of objects
74
+ # @param [String] string word to be pluralized
75
+ # @return [String] pluralized word
76
+ def pluralize(count, string)
77
+ "#{count} #{string}#{'s' unless count.to_f == 1}"
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,155 @@
1
+ require 'rspec/core/formatters/base_text_formatter'
2
+ require 'rspec/core/formatters/html_printer'
3
+
4
+ module RSpec
5
+ module Core
6
+ module Formatters
7
+ class HtmlFormatter < BaseTextFormatter
8
+
9
+ def initialize(output)
10
+ super(output)
11
+ @example_group_number = 0
12
+ @example_number = 0
13
+ @header_red = nil
14
+ @printer = HtmlPrinter.new(output)
15
+ end
16
+
17
+ private
18
+ def method_missing(m, *a, &b)
19
+ # no-op
20
+ end
21
+
22
+ public
23
+ def message(message)
24
+ end
25
+
26
+ # The number of the currently running example_group
27
+ def example_group_number
28
+ @example_group_number
29
+ end
30
+
31
+ # The number of the currently running example (a global counter)
32
+ def example_number
33
+ @example_number
34
+ end
35
+
36
+ def start(example_count)
37
+ super(example_count)
38
+ @printer.print_html_start
39
+ @printer.flush
40
+ end
41
+
42
+ def example_group_started(example_group)
43
+ super(example_group)
44
+ @example_group_red = false
45
+ @example_group_number += 1
46
+
47
+ unless example_group_number == 1
48
+ @printer.print_example_group_end
49
+ end
50
+ @printer.print_example_group_start( example_group_number, example_group.description, example_group.parent_groups.size )
51
+ @printer.flush
52
+ end
53
+
54
+ def start_dump
55
+ @printer.print_example_group_end
56
+ @printer.flush
57
+ end
58
+
59
+ def example_started(example)
60
+ super(example)
61
+ @example_number += 1
62
+ end
63
+
64
+ def example_passed(example)
65
+ @printer.move_progress(percent_done)
66
+ @printer.print_example_passed( example.description, example.execution_result[:run_time] )
67
+ @printer.flush
68
+ end
69
+
70
+ def example_failed(example)
71
+ super(example)
72
+
73
+ unless @header_red
74
+ @header_red = true
75
+ @printer.make_header_red
76
+ end
77
+
78
+ unless @example_group_red
79
+ @example_group_red = true
80
+ @printer.make_example_group_header_red(example_group_number)
81
+ end
82
+
83
+ @printer.move_progress(percent_done)
84
+
85
+ exception = example.metadata[:execution_result][:exception]
86
+ exception_details = if exception
87
+ {
88
+ :message => exception.message,
89
+ :backtrace => format_backtrace(exception.backtrace, example).join("\n")
90
+ }
91
+ else
92
+ false
93
+ end
94
+ extra = extra_failure_content(exception)
95
+
96
+ @printer.print_example_failed(
97
+ example.execution_result[:pending_fixed],
98
+ example.description,
99
+ example.execution_result[:run_time],
100
+ @failed_examples.size,
101
+ exception_details,
102
+ (extra == "") ? false : extra,
103
+ true
104
+ )
105
+ @printer.flush
106
+ end
107
+
108
+ def example_pending(example)
109
+
110
+ @printer.make_header_yellow unless @header_red
111
+ @printer.make_example_group_header_yellow(example_group_number) unless @example_group_red
112
+ @printer.move_progress(percent_done)
113
+ @printer.print_example_pending( example.description, example.metadata[:execution_result][:pending_message] )
114
+ @printer.flush
115
+ end
116
+
117
+ # Override this method if you wish to output extra HTML for a failed spec. For example, you
118
+ # could output links to images or other files produced during the specs.
119
+ #
120
+ def extra_failure_content(exception)
121
+ require 'rspec/core/formatters/snippet_extractor'
122
+ backtrace = exception.backtrace.map {|line| configuration.backtrace_formatter.backtrace_line(line)}
123
+ backtrace.compact!
124
+ @snippet_extractor ||= SnippetExtractor.new
125
+ " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
126
+ end
127
+
128
+ def percent_done
129
+ result = 100.0
130
+ if @example_count > 0
131
+ result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f
132
+ end
133
+ result
134
+ end
135
+
136
+ def dump_failures
137
+ end
138
+
139
+ def dump_pending
140
+ end
141
+
142
+ def dump_summary(duration, example_count, failure_count, pending_count)
143
+ @printer.print_summary(
144
+ dry_run?,
145
+ duration,
146
+ example_count,
147
+ failure_count,
148
+ pending_count
149
+ )
150
+ @printer.flush
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,408 @@
1
+ require 'erb'
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ class HtmlPrinter
7
+ include ERB::Util # for the #h method
8
+ def initialize(output)
9
+ @output = output
10
+ end
11
+
12
+ def print_html_start
13
+ @output.puts HTML_HEADER
14
+ @output.puts REPORT_HEADER
15
+ end
16
+
17
+ def print_example_group_end
18
+ @output.puts " </dl>"
19
+ @output.puts "</div>"
20
+ end
21
+
22
+ def print_example_group_start( group_id, description, number_of_parents )
23
+ @output.puts "<div id=\"div_group_#{group_id}\" class=\"example_group passed\">"
24
+ @output.puts " <dl #{indentation_style(number_of_parents)}>"
25
+ @output.puts " <dt id=\"example_group_#{group_id}\" class=\"passed\">#{h(description)}</dt>"
26
+ end
27
+
28
+ def print_example_passed( description, run_time )
29
+ formatted_run_time = sprintf("%.5f", run_time)
30
+ @output.puts " <dd class=\"example passed\"><span class=\"passed_spec_name\">#{h(description)}</span><span class='duration'>#{formatted_run_time}s</span></dd>"
31
+ end
32
+
33
+ def print_example_failed( pending_fixed, description, run_time, failure_id, exception, extra_content, escape_backtrace = false )
34
+ formatted_run_time = sprintf("%.5f", run_time)
35
+
36
+ @output.puts " <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
37
+ @output.puts " <span class=\"failed_spec_name\">#{h(description)}</span>"
38
+ @output.puts " <span class=\"duration\">#{formatted_run_time}s</span>"
39
+ @output.puts " <div class=\"failure\" id=\"failure_#{failure_id}\">"
40
+ if exception
41
+ @output.puts " <div class=\"message\"><pre>#{h(exception[:message])}</pre></div>"
42
+ if escape_backtrace
43
+ @output.puts " <div class=\"backtrace\"><pre>#{h exception[:backtrace]}</pre></div>"
44
+ else
45
+ @output.puts " <div class=\"backtrace\"><pre>#{exception[:backtrace]}</pre></div>"
46
+ end
47
+ end
48
+ @output.puts extra_content if extra_content
49
+ @output.puts " </div>"
50
+ @output.puts " </dd>"
51
+ end
52
+
53
+ def print_example_pending( description, pending_message )
54
+ @output.puts " <dd class=\"example not_implemented\"><span class=\"not_implemented_spec_name\">#{h(description)} (PENDING: #{h(pending_message)})</span></dd>"
55
+ end
56
+
57
+ def print_summary( was_dry_run, duration, example_count, failure_count, pending_count )
58
+ # TODO - kill dry_run?
59
+ if was_dry_run
60
+ totals = "This was a dry-run"
61
+ else
62
+ totals = "#{example_count} example#{'s' unless example_count == 1}, "
63
+ totals << "#{failure_count} failure#{'s' unless failure_count == 1}"
64
+ totals << ", #{pending_count} pending" if pending_count > 0
65
+ end
66
+
67
+ formatted_duration = sprintf("%.5f", duration)
68
+
69
+ @output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{formatted_duration} seconds</strong>\";</script>"
70
+ @output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
71
+ @output.puts "</div>"
72
+ @output.puts "</div>"
73
+ @output.puts "</body>"
74
+ @output.puts "</html>"
75
+ end
76
+
77
+ def flush
78
+ @output.flush
79
+ end
80
+
81
+ def move_progress( percent_done )
82
+ @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
83
+ @output.flush
84
+ end
85
+
86
+ def make_header_red
87
+ @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>"
88
+ end
89
+
90
+ def make_header_yellow
91
+ @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>"
92
+ end
93
+
94
+ def make_example_group_header_red(group_id)
95
+ @output.puts " <script type=\"text/javascript\">makeRed('div_group_#{group_id}');</script>"
96
+ @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{group_id}');</script>"
97
+ end
98
+
99
+ def make_example_group_header_yellow(group_id)
100
+ @output.puts " <script type=\"text/javascript\">makeYellow('div_group_#{group_id}');</script>"
101
+ @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{group_id}');</script>"
102
+ end
103
+
104
+
105
+ private
106
+
107
+ def indentation_style( number_of_parents )
108
+ "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\""
109
+ end
110
+
111
+
112
+ REPORT_HEADER = <<-EOF
113
+ <div class="rspec-report">
114
+
115
+ <div id="rspec-header">
116
+ <div id="label">
117
+ <h1>RSpec Code Examples</h1>
118
+ </div>
119
+
120
+ <div id="display-filters">
121
+ <input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="1" /> <label for="passed_checkbox">Passed</label>
122
+ <input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="2" /> <label for="failed_checkbox">Failed</label>
123
+ <input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="3" /> <label for="pending_checkbox">Pending</label>
124
+ </div>
125
+
126
+ <div id="summary">
127
+ <p id="totals">&#160;</p>
128
+ <p id="duration">&#160;</p>
129
+ </div>
130
+ </div>
131
+
132
+
133
+ <div class="results">
134
+ EOF
135
+
136
+ GLOBAL_SCRIPTS = <<-EOF
137
+
138
+ function addClass(element_id, classname) {
139
+ document.getElementById(element_id).className += (" " + classname);
140
+ }
141
+
142
+ function removeClass(element_id, classname) {
143
+ var elem = document.getElementById(element_id);
144
+ var classlist = elem.className.replace(classname,'');
145
+ elem.className = classlist;
146
+ }
147
+
148
+ function moveProgressBar(percentDone) {
149
+ document.getElementById("rspec-header").style.width = percentDone +"%";
150
+ }
151
+
152
+ function makeRed(element_id) {
153
+ removeClass(element_id, 'passed');
154
+ removeClass(element_id, 'not_implemented');
155
+ addClass(element_id,'failed');
156
+ }
157
+
158
+ function makeYellow(element_id) {
159
+ var elem = document.getElementById(element_id);
160
+ if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed
161
+ if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
162
+ removeClass(element_id, 'passed');
163
+ addClass(element_id,'not_implemented');
164
+ }
165
+ }
166
+ }
167
+
168
+ function apply_filters() {
169
+ var passed_filter = document.getElementById('passed_checkbox').checked;
170
+ var failed_filter = document.getElementById('failed_checkbox').checked;
171
+ var pending_filter = document.getElementById('pending_checkbox').checked;
172
+
173
+ assign_display_style("example passed", passed_filter);
174
+ assign_display_style("example failed", failed_filter);
175
+ assign_display_style("example not_implemented", pending_filter);
176
+
177
+ assign_display_style_for_group("example_group passed", passed_filter);
178
+ assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
179
+ assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
180
+ }
181
+
182
+ function get_display_style(display_flag) {
183
+ var style_mode = 'none';
184
+ if (display_flag == true) {
185
+ style_mode = 'block';
186
+ }
187
+ return style_mode;
188
+ }
189
+
190
+ function assign_display_style(classname, display_flag) {
191
+ var style_mode = get_display_style(display_flag);
192
+ var elems = document.getElementsByClassName(classname)
193
+ for (var i=0; i<elems.length;i++) {
194
+ elems[i].style.display = style_mode;
195
+ }
196
+ }
197
+
198
+ function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
199
+ var display_style_mode = get_display_style(display_flag);
200
+ var subgroup_style_mode = get_display_style(subgroup_flag);
201
+ var elems = document.getElementsByClassName(classname)
202
+ for (var i=0; i<elems.length;i++) {
203
+ var style_mode = display_style_mode;
204
+ if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
205
+ elems[i].style.display = subgroup_style_mode;
206
+ } else {
207
+ elems[i].style.display = display_style_mode;
208
+ }
209
+ }
210
+ }
211
+ EOF
212
+
213
+ GLOBAL_STYLES = <<-EOF
214
+ #rspec-header {
215
+ background: #65C400; color: #fff; height: 4em;
216
+ }
217
+
218
+ .rspec-report h1 {
219
+ margin: 0px 10px 0px 10px;
220
+ padding: 10px;
221
+ font-family: "Lucida Grande", Helvetica, sans-serif;
222
+ font-size: 1.8em;
223
+ position: absolute;
224
+ }
225
+
226
+ #label {
227
+ float:left;
228
+ }
229
+
230
+ #display-filters {
231
+ float:left;
232
+ padding: 28px 0 0 40%;
233
+ font-family: "Lucida Grande", Helvetica, sans-serif;
234
+ }
235
+
236
+ #summary {
237
+ float:right;
238
+ padding: 5px 10px;
239
+ font-family: "Lucida Grande", Helvetica, sans-serif;
240
+ text-align: right;
241
+ }
242
+
243
+ #summary p {
244
+ margin: 0 0 0 2px;
245
+ }
246
+
247
+ #summary #totals {
248
+ font-size: 1.2em;
249
+ }
250
+
251
+ .example_group {
252
+ margin: 0 10px 5px;
253
+ background: #fff;
254
+ }
255
+
256
+ dl {
257
+ margin: 0; padding: 0 0 5px;
258
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
259
+ }
260
+
261
+ dt {
262
+ padding: 3px;
263
+ background: #65C400;
264
+ color: #fff;
265
+ font-weight: bold;
266
+ }
267
+
268
+ dd {
269
+ margin: 5px 0 5px 5px;
270
+ padding: 3px 3px 3px 18px;
271
+ }
272
+
273
+ dd .duration {
274
+ padding-left: 5px;
275
+ text-align: right;
276
+ right: 0px;
277
+ float:right;
278
+ }
279
+
280
+ dd.example.passed {
281
+ border-left: 5px solid #65C400;
282
+ border-bottom: 1px solid #65C400;
283
+ background: #DBFFB4; color: #3D7700;
284
+ }
285
+
286
+ dd.example.not_implemented {
287
+ border-left: 5px solid #FAF834;
288
+ border-bottom: 1px solid #FAF834;
289
+ background: #FCFB98; color: #131313;
290
+ }
291
+
292
+ dd.example.pending_fixed {
293
+ border-left: 5px solid #0000C2;
294
+ border-bottom: 1px solid #0000C2;
295
+ color: #0000C2; background: #D3FBFF;
296
+ }
297
+
298
+ dd.example.failed {
299
+ border-left: 5px solid #C20000;
300
+ border-bottom: 1px solid #C20000;
301
+ color: #C20000; background: #FFFBD3;
302
+ }
303
+
304
+
305
+ dt.not_implemented {
306
+ color: #000000; background: #FAF834;
307
+ }
308
+
309
+ dt.pending_fixed {
310
+ color: #FFFFFF; background: #C40D0D;
311
+ }
312
+
313
+ dt.failed {
314
+ color: #FFFFFF; background: #C40D0D;
315
+ }
316
+
317
+
318
+ #rspec-header.not_implemented {
319
+ color: #000000; background: #FAF834;
320
+ }
321
+
322
+ #rspec-header.pending_fixed {
323
+ color: #FFFFFF; background: #C40D0D;
324
+ }
325
+
326
+ #rspec-header.failed {
327
+ color: #FFFFFF; background: #C40D0D;
328
+ }
329
+
330
+
331
+ .backtrace {
332
+ color: #000;
333
+ font-size: 12px;
334
+ }
335
+
336
+ a {
337
+ color: #BE5C00;
338
+ }
339
+
340
+ /* Ruby code, style similar to vibrant ink */
341
+ .ruby {
342
+ font-size: 12px;
343
+ font-family: monospace;
344
+ color: white;
345
+ background-color: black;
346
+ padding: 0.1em 0 0.2em 0;
347
+ }
348
+
349
+ .ruby .keyword { color: #FF6600; }
350
+ .ruby .constant { color: #339999; }
351
+ .ruby .attribute { color: white; }
352
+ .ruby .global { color: white; }
353
+ .ruby .module { color: white; }
354
+ .ruby .class { color: white; }
355
+ .ruby .string { color: #66FF00; }
356
+ .ruby .ident { color: white; }
357
+ .ruby .method { color: #FFCC00; }
358
+ .ruby .number { color: white; }
359
+ .ruby .char { color: white; }
360
+ .ruby .comment { color: #9933CC; }
361
+ .ruby .symbol { color: white; }
362
+ .ruby .regex { color: #44B4CC; }
363
+ .ruby .punct { color: white; }
364
+ .ruby .escape { color: white; }
365
+ .ruby .interp { color: white; }
366
+ .ruby .expr { color: white; }
367
+
368
+ .ruby .offending { background-color: gray; }
369
+ .ruby .linenum {
370
+ width: 75px;
371
+ padding: 0.1em 1em 0.2em 0;
372
+ color: #000000;
373
+ background-color: #FFFBD3;
374
+ }
375
+ EOF
376
+
377
+ HTML_HEADER = <<-EOF
378
+ <!DOCTYPE html>
379
+ <html lang='en'>
380
+ <head>
381
+ <title>RSpec results</title>
382
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
383
+ <meta http-equiv="Expires" content="-1" />
384
+ <meta http-equiv="Pragma" content="no-cache" />
385
+ <style type="text/css">
386
+ body {
387
+ margin: 0;
388
+ padding: 0;
389
+ background: #fff;
390
+ font-size: 80%;
391
+ }
392
+ </style>
393
+ <script type="text/javascript">
394
+ // <![CDATA[
395
+ #{GLOBAL_SCRIPTS}
396
+ // ]]>
397
+ </script>
398
+ <style type="text/css">
399
+ #{GLOBAL_STYLES}
400
+ </style>
401
+ </head>
402
+ <body>
403
+ EOF
404
+
405
+ end
406
+ end
407
+ end
408
+ end