rspec-given 2.4.5 → 3.0.0.beta.2

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 (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