rspec-given 2.4.5 → 3.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -2
  3. data/Gemfile.lock +8 -10
  4. data/README.md +50 -34
  5. data/README.old +720 -0
  6. data/Rakefile +23 -17
  7. data/TODO +13 -0
  8. data/examples/example_helper.rb +8 -1
  9. data/examples/integration/and_spec.rb +6 -11
  10. data/examples/integration/focused_line_spec.rb +2 -1
  11. data/examples/integration/given_spec.rb +19 -9
  12. data/examples/integration/invariant_spec.rb +6 -6
  13. data/examples/integration/then_spec.rb +0 -1
  14. data/examples/loader.rb +4 -0
  15. data/examples/minitest_helper.rb +38 -0
  16. data/examples/stack/stack_spec.rb +2 -3
  17. data/lib/given.rb +2 -0
  18. data/lib/rspec/given.rb +1 -19
  19. data/rakelib/bundler_fix.rb +17 -0
  20. data/rakelib/gemspec.rake +161 -0
  21. data/rakelib/metrics.rake +30 -0
  22. data/rakelib/preview.rake +14 -0
  23. data/spec/lib/{rspec/given → given}/evaluator_spec.rb +1 -1
  24. data/spec/lib/{rspec/given → given}/ext/numeric_spec.rb +2 -2
  25. data/spec/lib/{rspec/given → given}/ext/numeric_specifications.rb +0 -0
  26. data/spec/lib/{rspec/given → given}/extensions_spec.rb +2 -2
  27. data/spec/lib/given/failure_matcher_spec.rb +77 -0
  28. data/spec/lib/given/failure_spec.rb +49 -0
  29. data/spec/lib/given/file_cache_spec.rb +26 -0
  30. data/spec/lib/{rspec/given → given}/fuzzy_number_spec.rb +2 -2
  31. data/spec/lib/{rspec/given → given}/have_failed_spec.rb +5 -4
  32. data/spec/lib/{rspec/given → given}/lexical_purity_spec.rb +0 -0
  33. data/spec/lib/given/line_extractor_spec.rb +84 -0
  34. data/spec/lib/{rspec/given → given}/module_methods_spec.rb +2 -2
  35. data/spec/lib/{rspec/given → given}/natural_assertion_spec.rb +4 -36
  36. data/spec/lib/{rspec/given → given}/options_spec.rb +33 -33
  37. data/spec/spec_helper.rb +20 -0
  38. data/spec/support/faux_then.rb +2 -2
  39. data/spec/support/natural_assertion_control.rb +1 -1
  40. metadata +35 -42
  41. data/examples/integration/failing_spec.rb +0 -5
  42. data/lib/rspec/given/configure.rb +0 -20
  43. data/lib/rspec/given/core.rb +0 -9
  44. data/lib/rspec/given/evaluator.rb +0 -39
  45. data/lib/rspec/given/ext/numeric.rb +0 -32
  46. data/lib/rspec/given/extensions.rb +0 -262
  47. data/lib/rspec/given/failure.rb +0 -53
  48. data/lib/rspec/given/file_cache.rb +0 -19
  49. data/lib/rspec/given/fuzzy_number.rb +0 -70
  50. data/lib/rspec/given/fuzzy_shortcuts.rb +0 -1
  51. data/lib/rspec/given/have_failed.rb +0 -77
  52. data/lib/rspec/given/line_extractor.rb +0 -43
  53. data/lib/rspec/given/module_methods.rb +0 -70
  54. data/lib/rspec/given/monkey.rb +0 -42
  55. data/lib/rspec/given/natural_assertion.rb +0 -193
  56. data/lib/rspec/given/rspec1_given.rb +0 -11
  57. data/lib/rspec/given/version.rb +0 -10
  58. data/spec/lib/rspec/given/failure_spec.rb +0 -17
  59. data/spec/lib/rspec/given/file_cache_spec.rb +0 -28
  60. data/spec/lib/rspec/given/line_extractor_spec.rb +0 -86
@@ -1,43 +0,0 @@
1
- require 'rspec/given/file_cache'
2
-
3
- module RSpec
4
- module Given
5
- class LineExtractor
6
- def initialize(file_cache=nil)
7
- @files = file_cache || FileCache.new
8
- end
9
-
10
- def line(file_name, line)
11
- lines = @files.get(file_name)
12
- extract_lines_from(lines, line-1)
13
- end
14
-
15
- def to_s
16
- "<LineExtractor>"
17
- end
18
-
19
- private
20
-
21
- def extract_lines_from(lines, line_index)
22
- result = lines[line_index]
23
- if continued?(result)
24
- level = indentation_level(result)
25
- begin
26
- line_index += 1
27
- result << lines[line_index]
28
- end while indentation_level(lines[line_index]) > level
29
- end
30
- result
31
- end
32
-
33
- def continued?(string)
34
- string =~ /(\{|do) *$/
35
- end
36
-
37
- def indentation_level(string)
38
- string =~ /^(\s*)\S/
39
- $1.nil? ? 1000000 : $1.size
40
- end
41
- end
42
- end
43
- end
@@ -1,70 +0,0 @@
1
- module RSpec
2
- module Given
3
- # Does this platform support natural assertions?
4
- RBX_IN_USE = (defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx')
5
- JRUBY_IN_USE = defined?(JRUBY_VERSION)
6
-
7
- NATURAL_ASSERTIONS_SUPPORTED = ! (JRUBY_IN_USE || RBX_IN_USE)
8
-
9
- def self.matcher_called
10
- @_matcher_called
11
- end
12
-
13
- def self.matcher_called=(value)
14
- @_matcher_called = value
15
- end
16
-
17
- def self.source_caching_disabled
18
- @_rg_source_caching_disabled
19
- end
20
-
21
- def self.source_caching_disabled=(value)
22
- @_rg_source_caching_disabled = value
23
- end
24
-
25
- # Detect the formatting requested in the given configuration object.
26
- #
27
- # If the format requires it, source caching will be enabled.
28
- def self.detect_formatters(c)
29
- format_active = c.formatters.any? { |f| f.class.name !~ /ProgressFormatter/ }
30
- RSpec::Given.source_caching_disabled = ! format_active
31
- end
32
-
33
- # Globally enable/disable natural assertions.
34
- #
35
- # There is a similar function in Extensions that works at a
36
- # describe or context scope.
37
- def self.use_natural_assertions(enabled=true)
38
- ok_to_use_natural_assertions(enabled)
39
- @natural_assertions_enabled = enabled
40
- end
41
-
42
- # TRUE if natural assertions are globally enabled?
43
- def self.natural_assertions_enabled?
44
- @natural_assertions_enabled
45
- end
46
-
47
- # Is is OK to use natural assertions on this platform.
48
- #
49
- # An error is raised if the the platform does not support natural
50
- # assertions and the flag is attempting to enable them.
51
- def self.ok_to_use_natural_assertions(enabled)
52
- if enabled && ! NATURAL_ASSERTIONS_SUPPORTED
53
- fail ArgumentError, "Natural Assertions are disabled for JRuby"
54
- end
55
- end
56
-
57
- # Fail an example with the given messages.
58
- #
59
- # This should be the only place we reference the RSpec function.
60
- # Everywhere else in rspec-given should be calling this function.
61
- def self.fail_with(*args)
62
- ::RSpec::Expectations.fail_with(*args)
63
- end
64
-
65
- # Error object used by RSpec to indicate a pending example.
66
- def self.pending_error
67
- RSpec::Core::Pending::PendingDeclaredInExample
68
- end
69
- end
70
- end
@@ -1,42 +0,0 @@
1
- require 'rspec'
2
- require 'rspec/expectations'
3
- require 'rspec/given/module_methods'
4
-
5
- # Monkey patch RSpec to detect matchers used in expectations.
6
-
7
- unless defined?(RSpec::Given::MONKEY)
8
-
9
- if defined?(RSpec::Expectations::PositiveExpectationHandler) &&
10
- defined?(RSpec::Expectations::NegativeExpectationHandler)
11
-
12
- RSpec::Given::MONKEY = true
13
-
14
- module RSpec
15
- module Expectations
16
- class PositiveExpectationHandler
17
- class << self
18
- alias _rg_rspec_original_handle_matcher handle_matcher
19
- def handle_matcher(actual, matcher, message=nil, &block)
20
- RSpec::Given.matcher_called = true
21
- _rg_rspec_original_handle_matcher(actual, matcher, message, &block)
22
- end
23
- end
24
- end
25
-
26
- class NegativeExpectationHandler
27
- class << self
28
- alias _rg_rspec_original_handle_matcher handle_matcher
29
- def handle_matcher(actual, matcher, message=nil, &block)
30
- RSpec::Given.matcher_called = true
31
- _rg_rspec_original_handle_matcher(actual, matcher, message, &block)
32
- end
33
- end
34
- end
35
- end
36
- end
37
-
38
- else
39
- RSpec::Given::MONKEY = false
40
- end
41
-
42
- end
@@ -1,193 +0,0 @@
1
- require 'rspec'
2
- require 'rspec/given/module_methods'
3
- require 'rspec/given/evaluator'
4
-
5
- if RSpec::Given::NATURAL_ASSERTIONS_SUPPORTED
6
- require 'ripper'
7
- require 'sorcerer'
8
- require 'rspec/given/monkey'
9
- end
10
-
11
- module RSpec
12
- module Given
13
-
14
- InvalidThenError = Class.new(StandardError)
15
-
16
- class NaturalAssertion
17
-
18
- def initialize(clause_type, block, example, line_extractor)
19
- @clause_type = clause_type
20
- @evaluator = Evaluator.new(example, block)
21
- @line_extractor = line_extractor
22
- set_file_and_line(block)
23
- end
24
-
25
- VOID_SEXP = [:void_stmt]
26
-
27
- def using_rspec_assertion?
28
- using_should? || using_expect?
29
- end
30
-
31
- def has_content?
32
- assertion_sexp != VOID_SEXP
33
- end
34
-
35
- def message
36
- @output = "#{@clause_type} expression failed at #{source_line}\n"
37
- @output << "Failing expression: #{source.strip}\n" if @clause_type != "Then"
38
- explain_failure
39
- display_pairs(expression_value_pairs)
40
- @output << "\n"
41
- @output
42
- end
43
-
44
- private
45
-
46
- def using_should?
47
- source =~ /\.\s*should(_not)?\b/
48
- end
49
-
50
- def using_expect?
51
- source =~ /\bexpect\s*[({].*[)}]\s*\.\s*(not_)?to\b/
52
- end
53
-
54
- BINARY_EXPLAINATIONS = {
55
- :== => "to equal",
56
- :!= => "to not equal",
57
- :< => "to be less than",
58
- :<= => "to be less or equal to",
59
- :> => "to be greater than",
60
- :>= => "to be greater or equal to",
61
- :=~ => "to match",
62
- :!~ => "to not match",
63
- }
64
-
65
- def explain_failure
66
- if assertion_sexp.first == :binary && msg = BINARY_EXPLAINATIONS[assertion_sexp[2]]
67
- @output << explain_expected("expected", assertion_sexp[1], msg, assertion_sexp[3])
68
- end
69
- end
70
-
71
- def explain_expected(expect_msg, expect_sexp, got_msg, got_sexp)
72
- width = [expect_msg.size, got_msg.size].max
73
- sprintf("%#{width}s: %s\n%#{width}s: %s\n",
74
- expect_msg, eval_sexp(expect_sexp),
75
- got_msg, eval_sexp(got_sexp))
76
- end
77
-
78
- def expression_value_pairs
79
- assertion_subexpressions.map { |exp|
80
- [exp, @evaluator.eval_string(exp)]
81
- }
82
- end
83
-
84
- def assertion_subexpressions
85
- Sorcerer.subexpressions(assertion_sexp).reverse.uniq.reverse
86
- end
87
-
88
- def assertion_sexp
89
- @assertion_sexp ||= extract_test_expression(Ripper::SexpBuilder.new(source).parse)
90
- end
91
-
92
- def source
93
- @source ||= @line_extractor.line(@code_file, @code_line)
94
- end
95
-
96
- def set_file_and_line(block)
97
- @code_file, @code_line = eval "[__FILE__, __LINE__]", block.binding
98
- @code_line = @code_line.to_i
99
- end
100
-
101
- def extract_test_expression(sexp)
102
- brace_block = extract_brace_block(sexp)
103
- extract_first_statement(brace_block)
104
- end
105
-
106
- def extract_brace_block(sexp)
107
- unless then_block?(sexp)
108
- source = Sorcerer.source(sexp)
109
- fail InvalidThenError, "Unexpected code at #{source_line}\n#{source}"
110
- end
111
- sexp[1][2][2]
112
- end
113
-
114
- def then_block?(sexp)
115
- delve(sexp,0) == :program &&
116
- delve(sexp,1,0) == :stmts_add &&
117
- delve(sexp,1,2,0) == :method_add_block &&
118
- (delve(sexp,1,2,2,0) == :brace_block || delve(sexp,1,2,2,0) == :do_block)
119
- end
120
-
121
- def extract_first_statement(block_sexp)
122
- if contains_multiple_statements?(block_sexp)
123
- source = Sorcerer.source(block_sexp)
124
- fail InvalidThenError, "Multiple statements in Then block at #{source_line}\n#{source}"
125
- end
126
- extract_statement_from_block(block_sexp)
127
- end
128
-
129
- def contains_multiple_statements?(block_sexp)
130
- !(delve(block_sexp,2,0) == :stmts_add &&
131
- delve(block_sexp,2,1,0) == :stmts_new)
132
- end
133
-
134
- def extract_statement_from_block(block_sexp)
135
- delve(block_sexp,2,2)
136
- end
137
-
138
- # Safely dive into an array with a list of indicies. Return nil
139
- # if the element doesn't exist, or if the intermediate result is
140
- # not indexable.
141
- def delve(ary, *indicies)
142
- result = ary
143
- while !indicies.empty? && result
144
- return nil unless result.respond_to?(:[])
145
- i = indicies.shift
146
- result = result[i]
147
- end
148
- result
149
- end
150
-
151
- def eval_sexp(sexp)
152
- expr_string = Sorcerer.source(sexp)
153
- @evaluator.eval_string(expr_string)
154
- end
155
-
156
- WRAP_WIDTH = 20
157
-
158
- def display_pairs(pairs)
159
- width = suggest_width(pairs) + 4
160
- pairs.each do |x, v|
161
- v = adjust_indentation(v)
162
- fmt = multi_line?(v) ?
163
- "%-#{width}s\n#{' '*width} <- %s\n" :
164
- "%-#{width}s <- %s\n"
165
- @output << sprintf(fmt, v, x)
166
- end
167
- end
168
-
169
- def adjust_indentation(string)
170
- string.to_s.gsub(/^/, ' ')
171
- end
172
-
173
- def multi_line?(string)
174
- (string.size > WRAP_WIDTH) || (string =~ /\n/)
175
- end
176
-
177
- def suggest_width(pairs)
178
- pairs.map { |x,v|
179
- max_line_length(v)
180
- }.select { |n| n < WRAP_WIDTH }.max || 10
181
- end
182
-
183
- def max_line_length(string)
184
- string.to_s.split(/\n/).map { |s| s.size }.max
185
- end
186
-
187
- def source_line
188
- "#{@code_file}:#{@code_line}"
189
- end
190
- end
191
-
192
- end
193
- end
@@ -1,11 +0,0 @@
1
- require 'rspec/given/version'
2
- require 'rspec/given/extensions'
3
-
4
- class Spec::ExampleGroup
5
- extend RSpec::Given::ClassExtensions
6
- include RSpec::Given::InstanceExtensions
7
-
8
- class << self
9
- alias Then specify
10
- end
11
- end
@@ -1,10 +0,0 @@
1
- module RSpec
2
- module Given
3
- VERSION_NUMBERS = [
4
- VERSION_MAJOR = 2,
5
- VERSION_MINOR = 4,
6
- VERSION_BUILD = 5,
7
- ]
8
- VERSION = VERSION_NUMBERS.join(".")
9
- end
10
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
- require 'rspec/given/failure'
3
-
4
- describe RSpec::Given::Failure do
5
- Given(:exception) { StandardError.new("Oops") }
6
- Given(:failure) { RSpec::Given::Failure.new(exception) }
7
-
8
- Then { lambda { failure.to_s }.should raise_error(StandardError, "Oops") }
9
- Then { lambda { failure.call }.should raise_error(StandardError, "Oops") }
10
- Then { lambda { failure.nil? }.should raise_error(StandardError, "Oops") }
11
- Then { lambda { failure == 0 }.should raise_error(StandardError, "Oops") }
12
- Then { lambda { failure != 0 }.should raise_error(StandardError, "Oops") }
13
- Then { lambda { failure =~ 0 }.should raise_error(StandardError, "Oops") }
14
- Then { lambda { ! failure }.should raise_error(StandardError, "Oops") }
15
-
16
- Then { failure.is_a?(RSpec::Given::Failure).should be_true }
17
- end
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Given
5
-
6
- DESCRIBE_LINE = __LINE__
7
- describe FileCache do
8
- Given(:file_name) { __FILE__ }
9
- Given(:cache) { FileCache.new }
10
-
11
- When(:result) { cache.get(file_name) }
12
-
13
- context "when reading the file" do
14
- Then { result[DESCRIBE_LINE].should =~ /describe FileCache do/ }
15
- Then { result.size.should == MAX_LINE }
16
- end
17
-
18
- context "when getting the same file twice" do
19
- Given { cache.should_receive(:read_lines).once.and_return(["A"]) }
20
- When(:result2) { cache.get(file_name) }
21
- Then { result.should == ["A"] }
22
- Then { result2.should == ["A"] }
23
- end
24
- end
25
- end
26
- end
27
-
28
- MAX_LINE = __LINE__
@@ -1,86 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Given
5
-
6
- describe LineExtractor do
7
-
8
- class FauxFileCache
9
- def initialize(lines)
10
- @lines = lines.split(/\n/).map { |ln| ln + "\n" }
11
- end
12
- def get(file_name)
13
- @lines
14
- end
15
- end
16
-
17
- Given(:line) { 2 }
18
- Given(:file_cache) { FauxFileCache.new(input) }
19
- Given(:extractor) { LineExtractor.new(file_cache) }
20
-
21
- When(:result) { extractor.line("FILENAME", line) }
22
-
23
- describe "reading a line" do
24
- Given(:input) {
25
- " Now is the time\n" +
26
- " for all good men\n" +
27
- " to come to the aid\n" +
28
- " of their fellowmen\n"
29
- }
30
- Given(:expected_line) { " for all good men\n" }
31
- Then { result.should == expected_line }
32
- end
33
-
34
- context "when the line doesn't exist" do
35
- Given(:input) { "" }
36
- Then { result.should be_nil }
37
- end
38
-
39
- context "when the line has leading and trailing white space" do
40
- Given(:input) {
41
- " Then { y } \n" +
42
- " Then { x }\n"
43
- }
44
- Then { result.should == " Then { x }\n" }
45
- end
46
-
47
- context "when the Then is split over several lines with {}" do
48
- Given(:input) {
49
- "describe 'foobar' do\n" +
50
- " Then {\n" +
51
- " x\n" +
52
- " }\n" +
53
- "end\n"
54
- }
55
- Then { result.should == " Then {\n x\n }\n" }
56
- end
57
-
58
- context "when the Then is has blank lines" do
59
- Given(:input) {
60
- "describe 'foobar' do\n" +
61
- " Then {\n\n" +
62
- " x\n" +
63
- " }\n" +
64
- "end\n"
65
- }
66
- Then { result.should == " Then {\n\n x\n }\n" }
67
- end
68
-
69
- context "when the Then is split over several lines with do/end" do
70
- Given(:input) {
71
- "describe 'foobar' do\n" +
72
- " Then do\n" +
73
- " x\n" +
74
- " end\n" +
75
- "end\n"
76
- }
77
- Then { result.should == " Then do\n x\n end\n" }
78
- end
79
-
80
- describe "converting to a string" do
81
- Given(:input) { "" }
82
- Then { extractor.to_s.should =~ /line *extractor/i }
83
- end
84
- end
85
- end
86
- end