opal-rspec-cj 0.4.4

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