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,143 @@
1
+ require 'erb'
2
+ require 'shellwords'
3
+
4
+ module RSpec
5
+ module Core
6
+ # @private
7
+ class ConfigurationOptions
8
+ attr_reader :options
9
+
10
+ def initialize(args)
11
+ @args = args.map {|a|
12
+ a.sub("default_path", "default-path").sub("line_number", "line-number")
13
+ }
14
+ end
15
+
16
+ def configure(config)
17
+ config.filter_manager = filter_manager
18
+
19
+ config.libs = options[:libs] || []
20
+ config.setup_load_path_and_require(options[:requires] || [])
21
+
22
+ process_options_into config
23
+ load_formatters_into config
24
+ end
25
+
26
+ def parse_options
27
+ @options = (file_options << command_line_options << env_options).
28
+ each {|opts|
29
+ filter_manager.include opts.delete(:inclusion_filter) if opts.has_key?(:inclusion_filter)
30
+ filter_manager.exclude opts.delete(:exclusion_filter) if opts.has_key?(:exclusion_filter)
31
+ }.
32
+ inject {|h, opts|
33
+ h.merge(opts) {|k, oldval, newval|
34
+ [:libs, :requires].include?(k) ? oldval + newval : newval
35
+ }
36
+ }
37
+ end
38
+
39
+ def drb_argv
40
+ DrbOptions.new(options, filter_manager).options
41
+ end
42
+
43
+ def filter_manager
44
+ @filter_manager ||= RSpec::configuration.filter_manager
45
+ end
46
+
47
+ private
48
+
49
+ UNFORCED_OPTIONS = [
50
+ :requires, :profile, :drb, :libs, :files_or_directories_to_run,
51
+ :line_numbers, :full_description, :full_backtrace, :tty
52
+ ].to_set
53
+
54
+ UNPROCESSABLE_OPTIONS = [:libs, :formatters, :requires].to_set
55
+
56
+ def force?(key)
57
+ !UNFORCED_OPTIONS.include?(key)
58
+ end
59
+
60
+ def order(keys, *ordered)
61
+ ordered.reverse.each do |key|
62
+ keys.unshift(key) if keys.delete(key)
63
+ end
64
+ keys
65
+ end
66
+
67
+ def process_options_into(config)
68
+ opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k }
69
+
70
+ order(opts.keys, :default_path, :pattern).each do |key|
71
+ force?(key) ? config.force(key => opts[key]) : config.send("#{key}=", opts[key])
72
+ end
73
+ end
74
+
75
+ def load_formatters_into(config)
76
+ options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters]
77
+ end
78
+
79
+ def file_options
80
+ custom_options_file ? [custom_options] : [global_options, project_options, local_options]
81
+ end
82
+
83
+ def env_options
84
+ ENV["SPEC_OPTS"] ? Parser.parse!(Shellwords.split(ENV["SPEC_OPTS"])) : {}
85
+ end
86
+
87
+ def command_line_options
88
+ @command_line_options ||= Parser.parse!(@args).merge :files_or_directories_to_run => @args
89
+ end
90
+
91
+ def custom_options
92
+ options_from(custom_options_file)
93
+ end
94
+
95
+ def local_options
96
+ @local_options ||= options_from(local_options_file)
97
+ end
98
+
99
+ def project_options
100
+ @project_options ||= options_from(project_options_file)
101
+ end
102
+
103
+ def global_options
104
+ @global_options ||= options_from(global_options_file)
105
+ end
106
+
107
+ def options_from(path)
108
+ Parser.parse(args_from_options_file(path))
109
+ end
110
+
111
+ def args_from_options_file(path)
112
+ return [] unless path && File.exist?(path)
113
+ config_string = options_file_as_erb_string(path)
114
+ FlatMap.flat_map(config_string.split(/\n+/), &:shellsplit)
115
+ end
116
+
117
+ def options_file_as_erb_string(path)
118
+ ERB.new(File.read(path), nil, '-').result(binding)
119
+ end
120
+
121
+ def custom_options_file
122
+ command_line_options[:custom_options_file]
123
+ end
124
+
125
+ def project_options_file
126
+ ".rspec"
127
+ end
128
+
129
+ def local_options_file
130
+ ".rspec-local"
131
+ end
132
+
133
+ def global_options_file
134
+ begin
135
+ File.join(File.expand_path("~"), ".rspec")
136
+ rescue ArgumentError
137
+ RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
138
+ nil
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,26 @@
1
+ require 'drb/drb'
2
+ require 'rspec/core/drb_options'
3
+
4
+ module RSpec
5
+ module Core
6
+ class DRbCommandLine
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ def drb_port
12
+ @options.options[:drb_port] || ENV['RSPEC_DRB'] || 8989
13
+ end
14
+
15
+ def run(err, out)
16
+ begin
17
+ DRb.start_service("druby://localhost:0")
18
+ rescue SocketError, Errno::EADDRNOTAVAIL
19
+ DRb.start_service("druby://:0")
20
+ end
21
+ spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}")
22
+ spec_server.run(@options.drb_argv, err, out)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,87 @@
1
+ # Builds command line arguments to pass to the rspec command over DRb
2
+
3
+ module RSpec::Core
4
+ # @private
5
+ class DrbOptions
6
+ def initialize(submitted_options, filter_manager)
7
+ @submitted_options = submitted_options
8
+ @filter_manager = filter_manager
9
+ end
10
+
11
+ def options
12
+ argv = []
13
+ argv << "--color" if @submitted_options[:color]
14
+ argv << "--profile" if @submitted_options[:profile_examples]
15
+ argv << "--backtrace" if @submitted_options[:full_backtrace]
16
+ argv << "--tty" if @submitted_options[:tty]
17
+ argv << "--fail-fast" if @submitted_options[:fail_fast]
18
+ argv << "--options" << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file]
19
+ argv << "--order" << @submitted_options[:order] if @submitted_options[:order]
20
+
21
+ add_failure_exit_code(argv)
22
+ add_full_description(argv)
23
+ add_line_numbers(argv)
24
+ add_filter(argv, :inclusion, @filter_manager.inclusions)
25
+ add_filter(argv, :exclusion, @filter_manager.exclusions)
26
+ add_formatters(argv)
27
+ add_libs(argv)
28
+ add_requires(argv)
29
+
30
+ argv + @submitted_options[:files_or_directories_to_run]
31
+ end
32
+
33
+ def add_failure_exit_code(argv)
34
+ if @submitted_options[:failure_exit_code]
35
+ argv << "--failure-exit-code" << @submitted_options[:failure_exit_code].to_s
36
+ end
37
+ end
38
+
39
+ def add_full_description(argv)
40
+ if @submitted_options[:full_description]
41
+ # The argument to --example is regexp-escaped before being stuffed
42
+ # into a regexp when received for the first time (see OptionParser).
43
+ # Hence, merely grabbing the source of this regexp will retain the
44
+ # backslashes, so we must remove them.
45
+ @submitted_options[:full_description].each do |description|
46
+ argv << "--example" << description.source.delete('\\')
47
+ end
48
+ end
49
+ end
50
+
51
+ def add_line_numbers(argv)
52
+ if @submitted_options[:line_numbers]
53
+ argv.push(*@submitted_options[:line_numbers].inject([]){|a,l| a << "--line_number" << l})
54
+ end
55
+ end
56
+
57
+ CONDITIONAL_FILTERS = [:if, :unless]
58
+
59
+ def add_filter(argv, name, hash)
60
+ hash.each_pair do |k, v|
61
+ next if CONDITIONAL_FILTERS.include?(k)
62
+ tag = name == :inclusion ? k.to_s : "~#{k}"
63
+ tag << ":#{v}" if v.is_a?(String)
64
+ argv << "--tag" << tag
65
+ end unless hash.empty?
66
+ end
67
+
68
+ def add_formatters(argv)
69
+ @submitted_options[:formatters].each do |pair|
70
+ argv << "--format" << pair[0]
71
+ argv << "--out" << pair[1] if pair[1]
72
+ end if @submitted_options[:formatters]
73
+ end
74
+
75
+ def add_libs(argv)
76
+ @submitted_options[:libs].each do |path|
77
+ argv << "-I" << path
78
+ end if @submitted_options[:libs]
79
+ end
80
+
81
+ def add_requires(argv)
82
+ @submitted_options[:requires].each do |path|
83
+ argv << "--require" << path
84
+ end if @submitted_options[:requires]
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,26 @@
1
+ module RSpec
2
+ module Core
3
+ # Adds the `describe` method to the top-level namespace.
4
+ module DSL
5
+ # Generates a subclass of {ExampleGroup}
6
+ #
7
+ # ## Examples:
8
+ #
9
+ # describe "something" do
10
+ # it "does something" do
11
+ # # example code goes here
12
+ # end
13
+ # end
14
+ #
15
+ # @see ExampleGroup
16
+ # @see ExampleGroup.describe
17
+ def describe(*args, &example_group_block)
18
+ RSpec::Core::ExampleGroup.describe(*args, &example_group_block).register
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ extend RSpec::Core::DSL
25
+ Module.send(:include, RSpec::Core::DSL)
26
+
@@ -0,0 +1,312 @@
1
+ module RSpec
2
+ module Core
3
+ # Wrapper for an instance of a subclass of {ExampleGroup}. An instance of
4
+ # `Example` is returned by the {ExampleGroup#example example} method
5
+ # exposed to examples, {Hooks#before before} and {Hooks#after after} hooks,
6
+ # and yielded to {Hooks#around around} hooks.
7
+ #
8
+ # Useful for configuring logging and/or taking some action based
9
+ # on the state of an example's metadata.
10
+ #
11
+ # @example
12
+ #
13
+ # RSpec.configure do |config|
14
+ # config.before do
15
+ # log example.description
16
+ # end
17
+ #
18
+ # config.after do
19
+ # log example.description
20
+ # end
21
+ #
22
+ # config.around do |ex|
23
+ # log example.description
24
+ # ex.run
25
+ # end
26
+ # end
27
+ #
28
+ # shared_examples "auditable" do
29
+ # it "does something" do
30
+ # log "#{example.full_description}: #{auditable.inspect}"
31
+ # auditable.should do_something
32
+ # end
33
+ # end
34
+ #
35
+ # @see ExampleGroup
36
+ class Example
37
+ # @private
38
+ #
39
+ # Used to define methods that delegate to this example's metadata
40
+ def self.delegate_to_metadata(*keys)
41
+ keys.each { |key| define_method(key) { @metadata[key] } }
42
+ end
43
+
44
+ delegate_to_metadata :full_description, :execution_result, :file_path, :pending, :location
45
+
46
+ # Returns the string submitted to `example` or its aliases (e.g.
47
+ # `specify`, `it`, etc). If no string is submitted (e.g. `it { should
48
+ # do_something }`) it returns the message generated by the matcher if
49
+ # there is one, otherwise returns a message including the location of the
50
+ # example.
51
+ def description
52
+ description = metadata[:description].to_s.empty? ? "example at #{location}" : metadata[:description]
53
+ RSpec.configuration.format_docstrings_block.call(description)
54
+ end
55
+
56
+ # @attr_reader
57
+ #
58
+ # Returns the first exception raised in the context of running this
59
+ # example (nil if no exception is raised)
60
+ attr_reader :exception
61
+
62
+ # @attr_reader
63
+ #
64
+ # Returns the metadata object associated with this example.
65
+ attr_reader :metadata
66
+
67
+ # @attr_reader
68
+ # @private
69
+ #
70
+ # Returns the example_group_instance that provides the context for
71
+ # running this example.
72
+ attr_reader :example_group_instance
73
+
74
+ # Creates a new instance of Example.
75
+ # @param example_group_class the subclass of ExampleGroup in which this Example is declared
76
+ # @param description the String passed to the `it` method (or alias)
77
+ # @param metadata additional args passed to `it` to be used as metadata
78
+ # @param example_block the block of code that represents the example
79
+ def initialize(example_group_class, description, metadata, example_block=nil)
80
+ @example_group_class, @options, @example_block = example_group_class, metadata, example_block
81
+ @metadata = @example_group_class.metadata.for_example(description, metadata)
82
+ @example_group_instance = @exception = nil
83
+ @pending_declared_in_example = false
84
+ end
85
+
86
+ # @deprecated access options via metadata instead
87
+ def options
88
+ @options
89
+ end
90
+
91
+ # Returns the example group class that provides the context for running
92
+ # this example.
93
+ def example_group
94
+ @example_group_class
95
+ end
96
+
97
+ alias_method :pending?, :pending
98
+
99
+ # @api private
100
+ # instance_evals the block passed to the constructor in the context of
101
+ # the instance of {ExampleGroup}.
102
+ # @param example_group_instance the instance of an ExampleGroup subclass
103
+ def run(example_group_instance, reporter)
104
+ @example_group_instance = example_group_instance
105
+ RSpec.current_example = self
106
+
107
+ start(reporter)
108
+
109
+ begin
110
+ unless pending || RSpec.configuration.dry_run?
111
+ with_around_each_hooks do
112
+ begin
113
+ run_before_each
114
+ @example_group_instance.instance_exec(self, &@example_block)
115
+ rescue Pending::PendingDeclaredInExample => e
116
+ @pending_declared_in_example = e.message
117
+ rescue Exception => e
118
+ set_exception(e)
119
+ ensure
120
+ run_after_each
121
+ end
122
+ end
123
+ end
124
+ rescue Exception => e
125
+ set_exception(e)
126
+ ensure
127
+ @example_group_instance.instance_variables.each do |ivar|
128
+ @example_group_instance.instance_variable_set(ivar, nil)
129
+ end
130
+ @example_group_instance = nil
131
+
132
+ begin
133
+ assign_generated_description
134
+ rescue Exception => e
135
+ set_exception(e, "while assigning the example description")
136
+ end
137
+ end
138
+
139
+ finish(reporter)
140
+ ensure
141
+ RSpec.current_example = nil
142
+ end
143
+
144
+ # Wraps a `Proc` and exposes a `run` method for use in {Hooks#around
145
+ # around} hooks.
146
+ #
147
+ # @note Procsy, itself, is not a public API, but we're documenting it
148
+ # here to document how to interact with the object yielded to an
149
+ # `around` hook.
150
+ #
151
+ # @example
152
+ #
153
+ # RSpec.configure do |c|
154
+ # c.around do |ex| # Procsy which wraps the example
155
+ # if ex.metadata[:key] == :some_value && some_global_condition
156
+ # raise "some message"
157
+ # end
158
+ # ex.run # run delegates to ex.call
159
+ # end
160
+ # end
161
+ class Procsy
162
+ # The `metadata` of the {Example} instance.
163
+ attr_reader :metadata
164
+
165
+ Proc.public_instance_methods(false).each do |name|
166
+ define_method(name) { |*a, &b| @proc.__send__(name, *a, &b) }
167
+ end
168
+ alias run call
169
+
170
+ def initialize(metadata, &block)
171
+ @metadata = metadata
172
+ @proc = block
173
+ end
174
+
175
+ # @api private
176
+ def wrap(&block)
177
+ self.class.new(metadata, &block)
178
+ end
179
+ end
180
+
181
+ # @private
182
+ def any_apply?(filters)
183
+ metadata.any_apply?(filters)
184
+ end
185
+
186
+ # @private
187
+ def all_apply?(filters)
188
+ @metadata.all_apply?(filters) || @example_group_class.all_apply?(filters)
189
+ end
190
+
191
+ # @private
192
+ def around_each_hooks
193
+ @around_each_hooks ||= example_group.around_each_hooks_for(self)
194
+ end
195
+
196
+ # @private
197
+ #
198
+ # Used internally to set an exception in an after hook, which
199
+ # captures the exception but doesn't raise it.
200
+ def set_exception(exception, context=nil)
201
+ if @exception && context != :dont_print
202
+ # An error has already been set; we don't want to override it,
203
+ # but we also don't want silence the error, so let's print it.
204
+ msg = <<-EOS
205
+
206
+ An error occurred #{context}
207
+ #{exception.class}: #{exception.message}
208
+ occurred at #{exception.backtrace.first}
209
+
210
+ EOS
211
+ RSpec.configuration.reporter.message(msg)
212
+ end
213
+
214
+ @exception ||= exception
215
+ end
216
+
217
+ # @private
218
+ #
219
+ # Used internally to set an exception and fail without actually executing
220
+ # the example when an exception is raised in before(:all).
221
+ def fail_with_exception(reporter, exception)
222
+ start(reporter)
223
+ set_exception(exception)
224
+ finish(reporter)
225
+ end
226
+
227
+ # @private
228
+ def instance_exec_with_rescue(context = nil, &block)
229
+ @example_group_instance.instance_exec_with_rescue(self, context, &block)
230
+ end
231
+
232
+ # @private
233
+ def instance_exec(*args, &block)
234
+ @example_group_instance.instance_exec(*args, &block)
235
+ end
236
+
237
+ private
238
+
239
+ def with_around_each_hooks(&block)
240
+ if around_each_hooks.empty?
241
+ yield
242
+ else
243
+ @example_group_class.run_around_each_hooks(self, Procsy.new(metadata, &block))
244
+ end
245
+ rescue Exception => e
246
+ set_exception(e, "in an around(:each) hook")
247
+ end
248
+
249
+ def start(reporter)
250
+ reporter.example_started(self)
251
+ record :started_at => RSpec::Core::Time.now
252
+ end
253
+
254
+ def finish(reporter)
255
+ if @exception
256
+ record_finished 'failed', :exception => @exception
257
+ reporter.example_failed self
258
+ false
259
+ elsif @pending_declared_in_example
260
+ record_finished 'pending', :pending_message => @pending_declared_in_example
261
+ reporter.example_pending self
262
+ true
263
+ elsif pending
264
+ record_finished 'pending', :pending_message => String === pending ? pending : Pending::NO_REASON_GIVEN
265
+ reporter.example_pending self
266
+ true
267
+ else
268
+ record_finished 'passed'
269
+ reporter.example_passed self
270
+ true
271
+ end
272
+ end
273
+
274
+ def record_finished(status, results={})
275
+ finished_at = RSpec::Core::Time.now
276
+ record results.merge(:status => status, :finished_at => finished_at, :run_time => (finished_at - execution_result[:started_at]).to_f)
277
+ end
278
+
279
+ def run_before_each
280
+ @example_group_instance.setup_mocks_for_rspec
281
+ @example_group_class.run_before_each_hooks(self)
282
+ end
283
+
284
+ def run_after_each
285
+ @example_group_class.run_after_each_hooks(self)
286
+ verify_mocks
287
+ rescue Exception => e
288
+ set_exception(e, "in an after(:each) hook")
289
+ ensure
290
+ @example_group_instance.teardown_mocks_for_rspec
291
+ end
292
+
293
+ def verify_mocks
294
+ @example_group_instance.verify_mocks_for_rspec
295
+ rescue Exception => e
296
+ set_exception(e, :dont_print)
297
+ end
298
+
299
+ def assign_generated_description
300
+ return unless RSpec.configuration.expecting_with_rspec?
301
+ if metadata[:description_args].empty? and !pending?
302
+ metadata[:description_args] << RSpec::Matchers.generated_description
303
+ end
304
+ RSpec::Matchers.clear_generated_description
305
+ end
306
+
307
+ def record(results={})
308
+ execution_result.update(results)
309
+ end
310
+ end
311
+ end
312
+ end