rspec-core 2.8.0.rc1 → 2.8.0.rc2

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 (73) hide show
  1. data/License.txt +24 -0
  2. data/README.md +197 -37
  3. data/features/command_line/format_option.feature +3 -3
  4. data/features/command_line/init.feature +18 -0
  5. data/features/example_groups/shared_examples.feature +1 -1
  6. data/features/hooks/around_hooks.feature +4 -4
  7. data/features/pending/pending_examples.feature +5 -5
  8. data/features/support/env.rb +8 -1
  9. data/lib/autotest/rspec2.rb +2 -6
  10. data/lib/rspec/core.rb +48 -158
  11. data/lib/rspec/core/backward_compatibility.rb +2 -0
  12. data/lib/rspec/core/command_line.rb +4 -0
  13. data/lib/rspec/core/configuration.rb +201 -106
  14. data/lib/rspec/core/configuration_options.rb +2 -1
  15. data/lib/rspec/core/deprecation.rb +2 -3
  16. data/lib/rspec/core/drb_options.rb +69 -58
  17. data/lib/rspec/core/dsl.rb +12 -0
  18. data/lib/rspec/core/example.rb +53 -18
  19. data/lib/rspec/core/example_group.rb +144 -54
  20. data/lib/rspec/core/extensions.rb +4 -4
  21. data/lib/rspec/core/extensions/instance_eval_with_args.rb +5 -0
  22. data/lib/rspec/core/extensions/kernel.rb +1 -1
  23. data/lib/rspec/core/extensions/module_eval_with_args.rb +4 -0
  24. data/lib/rspec/core/extensions/ordered.rb +7 -2
  25. data/lib/rspec/core/filter_manager.rb +69 -36
  26. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
  27. data/lib/rspec/core/formatters/html_formatter.rb +10 -4
  28. data/lib/rspec/core/hooks.rb +93 -34
  29. data/lib/rspec/core/let.rb +62 -61
  30. data/lib/rspec/core/metadata.rb +103 -80
  31. data/lib/rspec/core/metadata_hash_builder.rb +4 -0
  32. data/lib/rspec/core/option_parser.rb +42 -44
  33. data/lib/rspec/core/pending.rb +25 -3
  34. data/lib/rspec/core/project_initializer.rb +62 -0
  35. data/lib/rspec/core/rake_task.rb +7 -13
  36. data/lib/rspec/core/runner.rb +2 -2
  37. data/lib/rspec/core/shared_context.rb +1 -1
  38. data/lib/rspec/core/shared_example_group.rb +11 -5
  39. data/lib/rspec/core/subject.rb +3 -3
  40. data/lib/rspec/core/version.rb +1 -1
  41. data/lib/rspec/monkey.rb +1 -1
  42. data/lib/rspec/monkey/spork/test_framework/rspec.rb +2 -0
  43. data/spec/command_line/order_spec.rb +19 -13
  44. data/spec/rspec/core/command_line_spec.rb +1 -5
  45. data/spec/rspec/core/configuration_options_spec.rb +22 -27
  46. data/spec/rspec/core/configuration_spec.rb +32 -14
  47. data/spec/rspec/core/drb_command_line_spec.rb +20 -37
  48. data/spec/rspec/core/drb_options_spec.rb +51 -3
  49. data/spec/rspec/core/example_group_spec.rb +101 -84
  50. data/spec/rspec/core/example_spec.rb +14 -0
  51. data/spec/rspec/core/filter_manager_spec.rb +114 -33
  52. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +17 -69
  53. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +14 -4
  54. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +14 -4
  55. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +14 -4
  56. data/spec/rspec/core/formatters/html_formatter_spec.rb +1 -1
  57. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +20 -72
  58. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +24 -14
  59. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +29 -19
  60. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +29 -19
  61. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +1 -2
  62. data/spec/rspec/core/metadata_spec.rb +77 -45
  63. data/spec/rspec/core/option_parser_spec.rb +5 -0
  64. data/spec/rspec/core/pending_example_spec.rb +44 -12
  65. data/spec/rspec/core/project_initializer_spec.rb +130 -0
  66. data/spec/rspec/core/rake_task_spec.rb +1 -1
  67. data/spec/spec_helper.rb +2 -0
  68. data/spec/support/matchers.rb +2 -12
  69. metadata +18 -16
  70. data/features/command_line/configure.feature +0 -22
  71. data/lib/rspec/core/command_line_configuration.rb +0 -62
  72. data/lib/rspec/core/errors.rb +0 -13
  73. data/spec/rspec/core/command_line_configuration_spec.rb +0 -26
@@ -1,6 +1,8 @@
1
1
  module RSpec
2
2
  module Core
3
+ # @private
3
4
  module MetadataHashBuilder
5
+ # @private
4
6
  module Common
5
7
  def build_metadata_hash_from(args)
6
8
  metadata = args.last.is_a?(Hash) ? args.pop : {}
@@ -29,6 +31,7 @@ module RSpec
29
31
  end
30
32
  end
31
33
 
34
+ # @private
32
35
  module WithConfigWarning
33
36
  include Common
34
37
 
@@ -57,6 +60,7 @@ NOTICE
57
60
  end
58
61
  end
59
62
 
63
+ # @private
60
64
  module WithDeprecationWarning
61
65
  include Common
62
66
 
@@ -17,7 +17,7 @@ module RSpec::Core
17
17
  RSpec.deprecate("the --formatter option", "-f or --format")
18
18
  args[args.index("--formatter")] = "--format"
19
19
  end
20
- options = {}
20
+ options = args.delete('--tty') ? {:tty => true} : {}
21
21
  parser(options).parse!(args)
22
22
  options
23
23
  end
@@ -28,63 +28,66 @@ module RSpec::Core
28
28
  OptionParser.new do |parser|
29
29
  parser.banner = "Usage: rspec [options] [files or directories]\n\n"
30
30
 
31
- parser.on('-I DIRECTORY', 'specify $LOAD_PATH directory (may be used more than once)') do |dir|
31
+ parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dir|
32
32
  options[:libs] ||= []
33
33
  options[:libs] << dir
34
34
  end
35
35
 
36
- parser.on('-r', '--require PATH', 'Require a file') do |path|
36
+ parser.on('-r', '--require PATH', 'Require a file.') do |path|
37
37
  options[:requires] ||= []
38
38
  options[:requires] << path
39
39
  end
40
40
 
41
- parser.on('-O', '--options PATH', 'Specify the path to a custom options file') do |path|
41
+ parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path|
42
42
  options[:custom_options_file] = path
43
43
  end
44
44
 
45
- parser.on('--order TYPE', 'Run examples by the specified order type',
46
- ' [rand] randomized',
47
- ' [random] alias for rand',
45
+ parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.',
46
+ ' [default] files are ordered based on the underlying file',
47
+ ' system\'s order',
48
+ ' [rand] randomize the order of files, groups and examples',
49
+ ' [random] alias for rand',
48
50
  ' [random:SEED] e.g. --order random:123') do |o|
49
51
  options[:order] = o
50
52
  end
51
53
 
52
- parser.on('--seed SEED', "Equivalent of --order rand:SEED") do |seed|
54
+ parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed|
53
55
  options[:order] = "rand:#{seed}"
54
56
  end
55
57
 
56
- parser.on('-d', '--debugger', 'Enable debugging') do |o|
58
+ parser.on('-d', '--debugger', 'Enable debugging.') do |o|
57
59
  options[:debug] = true
58
60
  end
59
61
 
60
- parser.on('--fail-fast', 'Abort the run on first failure') do |o|
62
+ parser.on('--fail-fast', 'Abort the run on first failure.') do |o|
61
63
  options[:fail_fast] = true
62
64
  end
63
65
 
64
- parser.on('--failure-exit-code CODE', 'Override the exit code used when there are failing specs') do |o|
65
- options[:failure_exit_code] = o.to_i
66
+ parser.on('--failure-exit-code CODE', Integer, 'Override the exit code used when there are failing specs.') do |code|
67
+ options[:failure_exit_code] = code
66
68
  end
67
69
 
68
- parser.on('-X', '--[no-]drb', 'Run examples via DRb') do |o|
70
+ parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |o|
69
71
  options[:drb] = o
70
72
  end
71
73
 
72
- parser.on('--drb-port [PORT]', 'Port to connect to on the DRb server') do |o|
74
+ parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o|
73
75
  options[:drb_port] = o.to_i
74
76
  end
75
77
 
76
- parser.on('--configure COMMAND', 'Generate configuration files') do |cmd|
77
- CommandLineConfiguration.new(cmd).run
78
+ parser.on('--init', 'Initialize your project with RSpec.') do |cmd|
79
+ ProjectInitializer.new(cmd).run
78
80
  exit
79
81
  end
80
82
 
81
- parser.on("--tty", "Used internally by rspec when sending commands to other processes") do |o|
82
- options[:tty] = true
83
+ parser.on('--configure', 'Deprecated. Use --init instead.') do |cmd|
84
+ warn "--configure is deprecated with no effect. Use --init instead."
85
+ exit
83
86
  end
84
87
 
85
- parser.separator("\n **** Output formatting ****\n\n")
88
+ parser.separator("\n **** Output ****\n\n")
86
89
 
87
- parser.on('-f', '--format FORMATTER', 'Choose a formatter',
90
+ parser.on('-f', '--format FORMATTER', 'Choose a formatter.',
88
91
  ' [p]rogress (default - dots)',
89
92
  ' [d]ocumentation (group and example names)',
90
93
  ' [h]tml',
@@ -96,28 +99,28 @@ module RSpec::Core
96
99
 
97
100
  parser.on('-o', '--out FILE',
98
101
  'Write output to a file instead of STDOUT. This option applies',
99
- 'to the previously specified --format, or the default format if',
100
- 'no format is specified.'
102
+ ' to the previously specified --format, or the default format',
103
+ ' if no format is specified.'
101
104
  ) do |o|
102
105
  options[:formatters] ||= [['progress']]
103
106
  options[:formatters].last << o
104
107
  end
105
108
 
106
- parser.on('-b', '--backtrace', 'Enable full backtrace') do |o|
109
+ parser.on('-b', '--backtrace', 'Enable full backtrace.') do |o|
107
110
  options[:full_backtrace] = true
108
111
  end
109
112
 
110
- parser.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output') do |o|
113
+ parser.on('-c', '--[no-]color', '--[no-]colour', 'Enable color in the output.') do |o|
111
114
  options[:color] = o
112
115
  end
113
116
 
114
- parser.on('-p', '--profile', 'Enable profiling of examples with output of the top 10 slowest examples') do |o|
117
+ parser.on('-p', '--profile', 'Enable profiling of examples and list 10 slowest examples.') do |o|
115
118
  options[:profile_examples] = o
116
119
  end
117
120
 
118
121
  parser.separator <<-FILTERING
119
122
 
120
- **** Filtering and tags ****
123
+ **** Filtering/tags ****
121
124
 
122
125
  In addition to the following options for selecting specific files, groups,
123
126
  or examples, you can select a single example by appending the line number to
@@ -127,7 +130,7 @@ module RSpec::Core
127
130
 
128
131
  FILTERING
129
132
 
130
- parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb")') do |o|
133
+ parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o|
131
134
  options[:pattern] = o
132
135
  end
133
136
 
@@ -135,38 +138,33 @@ FILTERING
135
138
  options[:full_description] = Regexp.compile(Regexp.escape(o))
136
139
  end
137
140
 
138
- parser.on('-l', '--line_number LINE', 'Specify line number of an example or group (may be specified multiple times)') do |o|
141
+ parser.on('-l', '--line_number LINE', 'Specify line number of an example or group (may be',
142
+ ' used more than once).') do |o|
139
143
  (options[:line_numbers] ||= []) << o
140
144
  end
141
145
 
142
146
  parser.on('-t', '--tag TAG[:VALUE]',
143
- 'Run examples with the specified tag, or exclude',
144
- 'examples by ading ~ before the tag (e.g. ~slow)',
145
- '(TAG is always converted to a symbol)') do |tag|
147
+ 'Run examples with the specified tag, or exclude examples',
148
+ 'by adding ~ before the tag.',
149
+ ' - e.g. ~slow',
150
+ ' - TAG is always converted to a symbol') do |tag|
146
151
  filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter
147
152
 
148
153
  name,value = tag.gsub(/^(~@|~|@)/, '').split(':')
149
154
  name = name.to_sym
150
155
 
151
156
  options[filter_type] ||= {}
152
- options[filter_type][name] = case value
153
- when /^(true|false|nil)$/
154
- eval(value)
155
- when nil
156
- true
157
- else
158
- value
159
- end
160
- end
161
-
162
- parser.on('--default_path PATH', 'Set the default path where RSpec looks for examples.',
163
- 'Can be a path to a file or a directory') do |path|
157
+ options[filter_type][name] = value.nil? ? true : eval(value) rescue value
158
+ end
159
+
160
+ parser.on('--default_path PATH', 'Set the default path where RSpec looks for examples (can',
161
+ ' be a path to a file or a directory).') do |path|
164
162
  options[:default_path] = path
165
163
  end
166
164
 
167
165
  parser.separator("\n **** Utility ****\n\n")
168
166
 
169
- parser.on('-v', '--version', 'Show version') do
167
+ parser.on('-v', '--version', 'Display the version.') do
170
168
  puts RSpec::Core::Version::STRING
171
169
  exit
172
170
  end
@@ -3,7 +3,20 @@ module RSpec
3
3
  module Pending
4
4
  class PendingDeclaredInExample < StandardError; end
5
5
 
6
- DEFAULT_MESSAGE = 'No reason given'
6
+ # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit
7
+ # will report unmet RSpec expectations as failures rather than errors.
8
+ begin
9
+ class PendingExampleFixedError < Test::Unit::AssertionFailedError; end
10
+ rescue
11
+ class PendingExampleFixedError < StandardError; end
12
+ end
13
+
14
+ class PendingExampleFixedError
15
+ def pending_fixed?; true; end
16
+ end
17
+
18
+ NO_REASON_GIVEN = 'No reason given'
19
+ NOT_YET_IMPLEMENTED = 'Not yet implemented'
7
20
 
8
21
  # @overload pending()
9
22
  # @overload pending(message)
@@ -46,11 +59,20 @@ module RSpec
46
59
  # end
47
60
  # end
48
61
  # end
62
+ #
63
+ # @note `before(:each)` hooks are eval'd when you use the `pending`
64
+ # method within an example. If you want to declare an example `pending`
65
+ # and bypass the `before` hooks as well, you can pass `:pending => true`
66
+ # to the `it` method:
67
+ #
68
+ # it "does something", :pending => true do
69
+ # # ...
70
+ # end
49
71
  def pending(*args)
50
72
  return self.class.before(:each) { pending(*args) } unless example
51
73
 
52
74
  options = args.last.is_a?(Hash) ? args.pop : {}
53
- message = args.first || DEFAULT_MESSAGE
75
+ message = args.first || NO_REASON_GIVEN
54
76
 
55
77
  if options[:unless] || (options.has_key?(:if) && !options[:if])
56
78
  return block_given? ? yield : nil
@@ -70,7 +92,7 @@ module RSpec
70
92
  ensure
71
93
  teardown_mocks_for_rspec
72
94
  end
73
- raise RSpec::Core::PendingExampleFixedError.new if result
95
+ raise PendingExampleFixedError.new if result
74
96
  end
75
97
  raise PendingDeclaredInExample.new(message)
76
98
  end
@@ -0,0 +1,62 @@
1
+ module RSpec
2
+ module Core
3
+ class ProjectInitializer
4
+ def initialize(arg=nil)
5
+ @arg = arg
6
+ end
7
+
8
+ def run
9
+ warn "The --configure option no longer needs any arguments, so #{@arg} was ignored." if @arg
10
+ create_spec_helper_file
11
+ create_dot_rspec_file
12
+ delete_if_confirmed("autotest/discover.rb", <<-MESSAGE)
13
+ RSpec registers its own discover.rb with Autotest, so autotest/discover.rb is
14
+ no longer needed.
15
+ MESSAGE
16
+
17
+ delete_if_confirmed("lib/tasks/rspec.rake", <<-MESSAGE)
18
+ If the file in lib/tasks/rspec.rake is the one generated by rspec-rails-1x,
19
+ you can get rid of it, as it is no longer needed with rspec-2.
20
+ MESSAGE
21
+ end
22
+
23
+ def create_dot_rspec_file
24
+ if File.exist?('.rspec')
25
+ report_exists('.rspec')
26
+ else
27
+ report_creating('.rspec')
28
+ FileUtils.touch('.rspec')
29
+ end
30
+ end
31
+
32
+ def create_spec_helper_file
33
+ if File.exist?('spec/spec_helper.rb')
34
+ report_exists("spec/spec_helper.rb")
35
+ else
36
+ report_creating("spec/spec_helper.rb")
37
+ FileUtils.mkdir('spec') unless File.exist?('spec') && File.directory?('spec')
38
+ FileUtils.touch('spec/spec_helper.rb')
39
+ end
40
+ end
41
+
42
+ def delete_if_confirmed(path, message)
43
+ if File.exist?(path)
44
+ puts
45
+ puts message
46
+ puts
47
+ puts " delete #{path}? [y/n]"
48
+ FileUtils.rm_rf(path) if gets =~ /y/i
49
+ end
50
+ end
51
+
52
+ def report_exists(file)
53
+ puts " exist #{file}"
54
+ end
55
+
56
+ def report_creating(file)
57
+ puts " create #{file}"
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -134,7 +134,7 @@ module RSpec
134
134
  rescue
135
135
  puts failure_message if failure_message
136
136
  end
137
- raise("ruby #{spec_command} failed") if fail_on_error unless success
137
+ raise("#{spec_command} failed") if fail_on_error unless success
138
138
  end
139
139
  end
140
140
  end
@@ -156,18 +156,12 @@ module RSpec
156
156
  cmd_parts << RUBY
157
157
  cmd_parts << ruby_opts
158
158
  cmd_parts << "-w" if @warning
159
- cmd_parts << "-S"
160
- cmd_parts << runner
161
- if rcov
162
- cmd_parts << ["-Ispec:lib", rcov_opts]
163
- else
164
- cmd_parts << rspec_opts
165
- end
159
+ cmd_parts << "-S" << runner
160
+ cmd_parts << "-Ispec:lib" << rcov_opts if rcov
166
161
  cmd_parts << files_to_run
167
- if rcov && rspec_opts
168
- cmd_parts << ["--", rspec_opts]
169
- end
170
- cmd_parts.flatten.compact.reject(&blank).join(" ")
162
+ cmd_parts << "--" if rcov && rspec_opts
163
+ cmd_parts << rspec_opts
164
+ cmd_parts.flatten.reject(&blank).join(" ")
171
165
  end
172
166
  end
173
167
 
@@ -178,7 +172,7 @@ module RSpec
178
172
  end
179
173
 
180
174
  def blank
181
- lambda {|s| s == ""}
175
+ lambda {|s| s.nil? || s == ""}
182
176
  end
183
177
  end
184
178
  end
@@ -46,12 +46,12 @@ module RSpec
46
46
  # want files like spec_helper.rb to be reloaded, be sure to load `load`
47
47
  # instead of `require`.
48
48
  #
49
- # ==== Parameters
49
+ # #### Parameters
50
50
  # * +args+ - an array of command-line-supported arguments
51
51
  # * +err+ - error stream (Default: $stderr)
52
52
  # * +out+ - output stream (Default: $stdout)
53
53
  #
54
- # ==== Returns
54
+ # #### Returns
55
55
  # * +Fixnum+ - exit status code (0/1)
56
56
  def self.run(args, err=$stderr, out=$stdout)
57
57
  trap_interrupt
@@ -20,7 +20,7 @@ module RSpec
20
20
  # end
21
21
  module SharedContext
22
22
  include Hooks
23
- include Let::ClassMethods
23
+ include Let::ExampleGroupMethods
24
24
 
25
25
  def included(group)
26
26
  [:before, :after].each do |type|
@@ -2,7 +2,14 @@ module RSpec
2
2
  module Core
3
3
  module SharedExampleGroup
4
4
 
5
- def shared_context(*args, &block)
5
+ # @overload shared_examples(name, &block)
6
+ # @overload shared_examples(name, tags, &block)
7
+ #
8
+ # Creates and stores (but does not evaluate) the block.
9
+ #
10
+ # @see ExampleGroup.include_examples
11
+ # @see ExampleGroup.include_context
12
+ def shared_examples(*args, &block)
6
13
  if [String, Symbol, Module].any? {|cls| cls === args.first }
7
14
  object = args.shift
8
15
  ensure_shared_example_group_name_not_taken(object)
@@ -18,9 +25,9 @@ module RSpec
18
25
  end
19
26
  end
20
27
 
21
- alias :shared_examples :shared_context
22
- alias :share_examples_for :shared_context
23
- alias :shared_examples_for :shared_context
28
+ alias_method :shared_context, :shared_examples
29
+ alias_method :share_examples_for, :shared_examples
30
+ alias_method :shared_examples_for, :shared_examples
24
31
 
25
32
  def share_as(name, &block)
26
33
  if Object.const_defined?(name)
@@ -46,7 +53,6 @@ module RSpec
46
53
  RSpec.world.shared_example_groups[shared_const] = block
47
54
  end
48
55
 
49
-
50
56
  private
51
57
 
52
58
  def raise_name_error
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module Subject
4
- module InstanceMethods
4
+ module ExampleMethods
5
5
 
6
6
  # Returns the subject defined by the example group. The subject block is
7
7
  # only executed once per example, the result of which is cached and
@@ -69,7 +69,7 @@ module RSpec
69
69
  end
70
70
  end
71
71
 
72
- module ClassMethods
72
+ module ExampleGroupMethods
73
73
  # Creates a nested example group named by the submitted +attribute+,
74
74
  # and then generates an example using the submitted block.
75
75
  #
@@ -165,7 +165,7 @@ module RSpec
165
165
  end
166
166
 
167
167
  def implicit_subject
168
- described = describes || description
168
+ described = described_class || description
169
169
  Class === described ? proc { described.new } : proc { described }
170
170
  end
171
171
  end