rspec-core 2.8.0.rc1 → 2.8.0.rc2

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