Permalink
Browse files

Merge branch 'master' into retry-failures

* master: (24 commits)
  fix copy/paste oversight
  Don't process filters when the metadata doesn't even have the key.
  Changelog for #564
  Fix autotest when RSpec executable path contains spaces
  it was rescue false, not rescue nil
  Changelog for #556
  don't rescue from calling proc filters
  dev: need to include dev rspec in case dependent gems depend on rspec
  ci: it's gem, not rubygems
  ci: it's before_install (RTFM)
  ci: one more try ...
  ci: before_script doesn't run before bundling, so no way to run against ree for now
  ci: update rubygems if < 1.8 (needed for ZenTest in ree)
  simplify spec for #reset
  Spec for RSpec::Core::World#reset
  Changelog for prev commit
  doc formatter strips whitespace from group and example descriptions
  changelog
  Pluralization support for runtime duration output (minute).
  Added spec for patched case
  ...
  • Loading branch information...
2 parents 640a018 + b06bc35 commit 1ce51ea803cad5b905d166cecc89d8813980a228 @oggy committed Feb 7, 2012
View
@@ -1,3 +1,5 @@
+before_install:
+ - if [[ `gem -v` != 1.8.* ]]; then gem update --system; fi
script: "bin/rake --trace 2>&1"
bundler_args: "--binstubs"
rvm:
View
@@ -1,10 +1,18 @@
### dev
+Enhancements
+
+* Support for "X minutes X seconds" spec run duration in formatter. (uzzz)
+* Strip whitespace from group and example names in doc formatter.
+
Bug fixes
* Restore `--full_backtrace` option
* Ensure that values passed to `config.filter_run` are respected when running
over DRb (using spork).
+* Ensure shared example groups are reset after a run (as example groups are).
+* Remove `rescue false` from calls to filters represented as Procs
+* Ensure described_class gets the closest constant (pyromaniac)
### 2.8.0 / 2012-01-04
View
@@ -3,7 +3,7 @@ source "http://rubygems.org"
gemspec
### rspec libs
-%w[rspec-core rspec-expectations rspec-mocks].each do |lib|
+%w[rspec rspec-core rspec-expectations rspec-mocks].each do |lib|
library_path = File.expand_path("../../#{lib}", __FILE__)
if File.exist?(library_path)
gem lib, :path => library_path
@@ -9,7 +9,7 @@ Feature: mock with flexmock
config.mock_framework = :flexmock
end
- describe "mocking with RSpec" do
+ describe "mocking with Flexmock" do
it "passes when it should" do
receiver = flexmock('receiver')
receiver.should_receive(:message).once
@@ -27,7 +27,7 @@ Feature: mock with flexmock
config.mock_framework = :flexmock
end
- describe "mocking with RSpec" do
+ describe "mocking with Flexmock" do
it "fails when it should" do
receiver = flexmock('receiver')
receiver.should_receive(:message).once
@@ -11,8 +11,8 @@
end
Then /^the example(?:s)? should(?: all)? pass$/ do
- Then %q{the output should contain "0 failures"}
- Then %q{the exit status should be 0}
+ step %q{the output should contain "0 failures"}
+ step %q{the exit status should be 0}
end
Then /^the file "([^"]*)" should contain:$/ do |file, partial_content|
@@ -47,7 +47,7 @@ def consolidate_failures(failed)
# Overrides Autotest's implementation to generate the rspec command to run
def make_test_cmd(files_to_test)
files_to_test.empty? ? '' :
- "#{prefix}#{ruby}#{suffix} -S #{RSPEC_EXECUTABLE} --tty #{normalize(files_to_test).keys.flatten.map { |f| "'#{f}'"}.join(' ')}"
+ "#{prefix}#{ruby}#{suffix} -S '#{RSPEC_EXECUTABLE}' --tty #{normalize(files_to_test).keys.flatten.map { |f| "'#{f}'"}.join(' ')}"
end
# Generates a map of filenames to Arrays for Autotest
@@ -546,10 +546,26 @@ def alias_it_should_behave_like_to(new_name, report_label = '')
# or config files (e.g. `.rspec`).
#
# @example
- # filter_run_including :x => 'y'
+ # # given this declaration
+ # describe "something", :foo => 'bar' do
+ # # ...
+ # end
+ #
+ # # any of the following will include that group
+ # config.filter_run_including :foo => 'bar'
+ # config.filter_run_including :foo => /^ba/
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
+ #
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
+ #
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
+ # # and the metadata itself e.g.
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
#
# # with treat_symbols_as_metadata_keys_with_true_values = true
- # filter_run_including :foo # results in {:foo => true}
+ # filter_run_including :foo # same as filter_run_including :foo => true
def filter_run_including(*args)
filter_manager.include_with_low_priority build_metadata_hash_from(args)
end
@@ -588,10 +604,26 @@ def inclusion_filter
# or config files (e.g. `.rspec`).
#
# @example
- # filter_run_excluding :x => 'y'
+ # # given this declaration
+ # describe "something", :foo => 'bar' do
+ # # ...
+ # end
+ #
+ # # any of the following will exclude that group
+ # config.filter_run_excluding :foo => 'bar'
+ # config.filter_run_excluding :foo => /^ba/
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
+ #
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+ #
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
+ # # and the metadata itself e.g.
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
#
# # with treat_symbols_as_metadata_keys_with_true_values = true
- # filter_run_excluding :foo # results in {:foo => true}
+ # filter_run_excluding :foo # same as filter_run_excluding :foo => true
def filter_run_excluding(*args)
filter_manager.exclude_with_low_priority build_metadata_hash_from(args)
end
@@ -67,7 +67,7 @@ module Core
# @see Configuration#filter_run_excluding
class FilterManager
DEFAULT_EXCLUSIONS = {
- :if => lambda { |value, metadata| metadata.has_key?(:if) && !value },
+ :if => lambda { |value| !value },
:unless => lambda { |value| value }
}
@@ -35,7 +35,7 @@ def dump_summary(duration, example_count, failure_count, pending_count)
super(duration, example_count, failure_count, pending_count)
# Don't print out profiled info if there are failures, it just clutters the output
dump_profile if profile_examples? && failure_count == 0
- output.puts "\nFinished in #{format_seconds(duration)} seconds\n"
+ output.puts "\nFinished in #{format_duration(duration)}\n"
output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
dump_commands_to_rerun_failed_examples
end
@@ -142,10 +142,6 @@ def long_padding
private
- def pluralize(count, string)
- "#{count} #{string}#{'s' unless count == 1}"
- end
-
def format_caller(caller_info)
backtrace_line(caller_info.to_s.split(':in `block').first)
end
@@ -3,9 +3,7 @@
module RSpec
module Core
module Formatters
-
class DocumentationFormatter < BaseTextFormatter
-
def initialize(output)
super(output)
@group_level = 0
@@ -15,7 +13,7 @@ def example_group_started(example_group)
super(example_group)
output.puts if @group_level == 0
- output.puts "#{current_indentation}#{example_group.description}"
+ output.puts "#{current_indentation}#{example_group.description.strip}"
@group_level += 1
end
@@ -40,7 +38,7 @@ def example_failed(example)
end
def failure_output(example, exception)
- red("#{current_indentation}#{example.description} (FAILED - #{next_failure_index})")
+ red("#{current_indentation}#{example.description.strip} (FAILED - #{next_failure_index})")
end
def next_failure_index
@@ -49,11 +47,11 @@ def next_failure_index
end
def passed_output(example)
- green("#{current_indentation}#{example.description}")
+ green("#{current_indentation}#{example.description.strip}")
end
def pending_output(example, message)
- yellow("#{current_indentation}#{example.description} (PENDING: #{message})")
+ yellow("#{current_indentation}#{example.description.strip} (PENDING: #{message})")
end
def current_indentation
@@ -63,9 +61,7 @@ def current_indentation
def example_group_chain
example_group.ancestors.reverse
end
-
end
-
end
end
end
@@ -6,6 +6,17 @@ module Helpers
SUB_SECOND_PRECISION = 5
DEFAULT_PRECISION = 2
+ def format_duration(duration)
+ if duration > 60
+ minutes = duration.to_i / 60
+ seconds = duration - minutes * 60
+
+ "#{pluralize(minutes, 'minute')} #{format_seconds(seconds)} seconds"
+ else
+ "#{format_seconds(duration)} seconds"
+ end
+ end
+
def format_seconds(float)
precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION
formatted = sprintf("%.#{precision}f", float)
@@ -17,6 +28,10 @@ def strip_trailing_zeroes(string)
stripped.empty? ? "0" : stripped
end
+ def pluralize(count, string)
+ "#{count} #{string}#{'s' unless count == 1}"
+ end
+
end
end
@@ -102,8 +102,8 @@ module GroupMetadataHash
def described_class
container_stack.each do |g|
- return g[:describes] if g.has_key?(:describes)
return g[:described_class] if g.has_key?(:described_class)
+ return g[:describes] if g.has_key?(:describes)
end
container_stack.reverse.each do |g|
@@ -174,20 +174,15 @@ def filter_applies?(key, value, metadata=self)
return metadata.location_filter_applies?(value) if key == :locations
return metadata.filters_apply?(key, value) if Hash === value
+ return false unless metadata.has_key?(key)
+
case value
when Regexp
metadata[key] =~ value
when Proc
- if value.arity == 2
- # Pass the metadata hash to allow the proc to check if it even has the key.
- # This is necessary for the implicit :if exclusion filter:
- # { } # => run the example
- # { :if => nil } # => exclude the example
- # The value of metadata[:if] is the same in these two cases but
- # they need to be treated differently.
- value.call(metadata[key], metadata) rescue false
- else
- value.call(metadata[key]) rescue false
+ case value.arity
+ when 1 then value.call(metadata[key])
+ when 2 then value.call(metadata[key], metadata)
end
when Array
value.include?(metadata[key].to_s)
@@ -4,12 +4,13 @@ class World
include RSpec::Core::Hooks
- attr_reader :example_groups, :filtered_examples, :wants_to_quit
- attr_writer :wants_to_quit
+ attr_reader :example_groups, :shared_example_groups, :filtered_examples
+ attr_accessor :wants_to_quit
def initialize(configuration=RSpec.configuration)
@configuration = configuration
@example_groups = [].extend(Extensions::Ordered)
+ @shared_example_groups = {}
@filtered_examples = Hash.new { |hash,group|
hash[group] = begin
examples = group.examples.dup
@@ -22,6 +23,7 @@ def initialize(configuration=RSpec.configuration)
def reset
example_groups.clear
+ shared_example_groups.clear
end
def filter_manager
@@ -45,12 +47,10 @@ def configure_group(group)
@configuration.configure_group(group)
end
- def shared_example_groups
- @shared_example_groups ||= {}
- end
-
def example_count
- example_groups.collect {|g| g.descendants}.flatten.inject(0) { |sum, g| sum += g.filtered_examples.size }
+ example_groups.collect {|g| g.descendants}.flatten.inject(0) do |sum, g|
+ sum += g.filtered_examples.size
+ end
end
def preceding_declaration_line(filter_line)
@@ -30,7 +30,7 @@
it "makes the appropriate test command" do
actual_command = rspec_autotest.make_test_cmd(@files_to_test)
- expected_command = /#{ruby_cmd}.*#{spec_cmd} (.*)/
+ expected_command = /#{ruby_cmd}.*'#{spec_cmd}' (.*)/
actual_command.should match(expected_command)
@@ -751,20 +751,16 @@ def metadata_hash(*args)
end
describe "the default :if filter" do
- it "does not exclude a spec with no :if metadata" do
- config.exclusion_filter[:if].call(nil, {}).should be_false
+ it "does not exclude a spec with { :if => true } metadata" do
+ config.exclusion_filter[:if].call(true).should be_false
end
- it "does not exclude a spec with { :if => true } metadata" do
- config.exclusion_filter[:if].call(true, {:if => true}).should be_false
+ it "excludes a spec with { :if => false } metadata" do
+ config.exclusion_filter[:if].call(false).should be_true
end
- it "excludes a spec with { :if => false } metadata" do
- config.exclusion_filter[:if].call(false, {:if => false}).should be_true
- end
-
- it "excludes a spec with { :if => nil } metadata" do
- config.exclusion_filter[:if].call(false, {:if => nil}).should be_true
+ it "excludes a spec with { :if => nil } metadata" do
+ config.exclusion_filter[:if].call(nil).should be_true
end
end
@@ -293,6 +293,22 @@ def metadata_hash(*args)
group.run.should be_true
end
end
+
+ context "and metadata redefinition after `described_class` call" do
+ it "is the redefined level constant" do
+ group = ExampleGroup.describe(String) do
+ described_class
+ metadata[:example_group][:described_class] = Object
+ describe :symbol do
+ example "described_class is Object" do
+ described_class.should eq(Object)
+ end
+ end
+ end
+
+ group.run.should be_true
+ end
+ end
end
context "in a nested group" do
Oops, something went wrong.

0 comments on commit 1ce51ea

Please sign in to comment.