cucumber-core 4.0.0 → 5.0.0
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +7 -1
- data/README.md +1 -2
- data/lib/cucumber/core/compiler.rb +23 -21
- data/lib/cucumber/core/event_bus.rb +1 -1
- data/lib/cucumber/core/gherkin/parser.rb +4 -5
- data/lib/cucumber/core/version.rb +1 -1
- data/spec/capture_warnings.rb +74 -0
- data/spec/coverage.rb +11 -0
- data/spec/cucumber/core/compiler_spec.rb +178 -0
- data/spec/cucumber/core/event_bus_spec.rb +163 -0
- data/spec/cucumber/core/event_spec.rb +40 -0
- data/spec/cucumber/core/filter_spec.rb +101 -0
- data/spec/cucumber/core/gherkin/parser_spec.rb +95 -0
- data/spec/cucumber/core/gherkin/writer_spec.rb +333 -0
- data/spec/cucumber/core/report/summary_spec.rb +167 -0
- data/spec/cucumber/core/test/action_spec.rb +154 -0
- data/spec/cucumber/core/test/case_spec.rb +126 -0
- data/spec/cucumber/core/test/data_table_spec.rb +81 -0
- data/spec/cucumber/core/test/doc_string_spec.rb +114 -0
- data/spec/cucumber/core/test/duration_matcher.rb +20 -0
- data/spec/cucumber/core/test/empty_multiline_argument_spec.rb +28 -0
- data/spec/cucumber/core/test/filters/locations_filter_spec.rb +271 -0
- data/spec/cucumber/core/test/location_spec.rb +126 -0
- data/spec/cucumber/core/test/result_spec.rb +474 -0
- data/spec/cucumber/core/test/runner_spec.rb +318 -0
- data/spec/cucumber/core/test/step_spec.rb +87 -0
- data/spec/cucumber/core/test/timer_spec.rb +25 -0
- data/spec/cucumber/core_spec.rb +262 -0
- data/spec/report_api_spy.rb +25 -0
- metadata +83 -14
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'cucumber/core/test/location'
|
3
|
+
require 'cucumber/core/test/doc_string'
|
4
|
+
require 'unindent'
|
5
|
+
|
6
|
+
module Cucumber
|
7
|
+
module Core
|
8
|
+
module Test
|
9
|
+
describe DocString do
|
10
|
+
let(:location) { double }
|
11
|
+
let(:doc_string) { DocString.new(content, content_type, location) }
|
12
|
+
|
13
|
+
describe "#data_table?" do
|
14
|
+
let(:doc_string) { DocString.new("test", "text/plain" , location) }
|
15
|
+
|
16
|
+
it "returns false" do
|
17
|
+
expect(doc_string).not_to be_data_table
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#doc_string" do
|
22
|
+
let(:doc_string) { DocString.new("test", "text/plain" , location) }
|
23
|
+
|
24
|
+
it "returns true" do
|
25
|
+
expect(doc_string).to be_doc_string
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context '#map' do
|
30
|
+
let(:content) { 'original content' }
|
31
|
+
let(:content_type) { double }
|
32
|
+
|
33
|
+
it 'yields with the content' do
|
34
|
+
expect { |b| doc_string.map(&b) }.to yield_with_args(content)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns a new docstring with new content' do
|
38
|
+
expect( doc_string.map { 'foo' }.content ).to eq 'foo'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises an error if no block is given' do
|
42
|
+
expect { doc_string.map }.to raise_error ArgumentError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'equality' do
|
47
|
+
let(:content) { 'foo' }
|
48
|
+
let(:content_type) { 'text/plain' }
|
49
|
+
|
50
|
+
it 'is equal to another DocString with the same content and content_type' do
|
51
|
+
expect( doc_string ).to eq DocString.new(content, content_type, location)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'is not equal to another DocString with different content' do
|
55
|
+
expect( doc_string ).not_to eq DocString.new('bar', content_type, location)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'is not equal to another DocString with different content_type' do
|
59
|
+
expect( doc_string ).not_to eq DocString.new(content, 'text/html', location)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'is equal to a string with the same content' do
|
63
|
+
expect( doc_string ).to eq 'foo'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'returns false when compared with something odd' do
|
67
|
+
expect( doc_string ).not_to eq 5
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'quacking like a String' do
|
72
|
+
let(:content) { String.new('content') }
|
73
|
+
let(:content_type) { 'text/plain' }
|
74
|
+
|
75
|
+
it 'delegates #encoding to the content string' do
|
76
|
+
content.force_encoding('us-ascii')
|
77
|
+
expect( doc_string.encoding ).to eq Encoding.find('US-ASCII')
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'allows implicit conversion to a String' do
|
81
|
+
expect( 'expected content' ).to include(doc_string)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'allows explicit conversion to a String' do
|
85
|
+
expect( doc_string.to_s ).to eq 'content'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'delegates #gsub to the content string' do
|
89
|
+
expect( doc_string.gsub(/n/, '_') ).to eq 'co_te_t'
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'delegates #split to the content string' do
|
93
|
+
expect(doc_string.split('n')).to eq ['co', 'te', 't']
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "inspect" do
|
99
|
+
let(:location) { Test::Location.new("features/feature.feature", 8) }
|
100
|
+
let(:content_type) { 'text/plain' }
|
101
|
+
|
102
|
+
it "provides a useful inspect method" do
|
103
|
+
doc_string = DocString.new("some text", content_type, location)
|
104
|
+
expect(doc_string.inspect).to eq <<-END.chomp.unindent
|
105
|
+
#<Cucumber::Core::Test::DocString (features/feature.feature:8)
|
106
|
+
"""text/plain
|
107
|
+
some text
|
108
|
+
""">
|
109
|
+
END
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'cucumber/core/test/result'
|
4
|
+
require 'rspec/expectations'
|
5
|
+
|
6
|
+
module Cucumber::Core::Test
|
7
|
+
RSpec::Matchers.define :be_duration do |expected|
|
8
|
+
match do |actual|
|
9
|
+
actual.tap { |duration| @nanoseconds = duration.nanoseconds }
|
10
|
+
@nanoseconds == expected
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Matchers.define :an_unknown_duration do
|
15
|
+
match do |actual|
|
16
|
+
actual.tap { raise "#tap block was executed, not an UnknownDuration" }
|
17
|
+
expect(actual).to respond_to(:nanoseconds)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'cucumber/core/test/location'
|
3
|
+
require 'cucumber/core/test/empty_multiline_argument'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Core
|
7
|
+
module Test
|
8
|
+
describe EmptyMultilineArgument do
|
9
|
+
|
10
|
+
let(:location) { double }
|
11
|
+
let(:arg) { EmptyMultilineArgument.new }
|
12
|
+
|
13
|
+
describe "#data_table?" do
|
14
|
+
it "returns false" do
|
15
|
+
expect(arg).not_to be_data_table
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#doc_string" do
|
20
|
+
it "returns false" do
|
21
|
+
expect(arg).not_to be_doc_string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'cucumber/core/gherkin/writer'
|
4
|
+
require 'cucumber/core'
|
5
|
+
require 'cucumber/core/test/filters/locations_filter'
|
6
|
+
require 'timeout'
|
7
|
+
require 'cucumber/core/test/location'
|
8
|
+
|
9
|
+
module Cucumber::Core
|
10
|
+
describe Test::LocationsFilter do
|
11
|
+
include Cucumber::Core::Gherkin::Writer
|
12
|
+
include Cucumber::Core
|
13
|
+
|
14
|
+
let(:receiver) { SpyReceiver.new }
|
15
|
+
|
16
|
+
let(:doc) do
|
17
|
+
gherkin('features/test.feature') do
|
18
|
+
feature do
|
19
|
+
scenario 'x' do
|
20
|
+
step 'a step'
|
21
|
+
end
|
22
|
+
|
23
|
+
scenario 'y' do
|
24
|
+
step 'a step'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sorts by the given locations" do
|
31
|
+
locations = [
|
32
|
+
Test::Location.new('features/test.feature', 6),
|
33
|
+
Test::Location.new('features/test.feature', 3)
|
34
|
+
]
|
35
|
+
filter = Test::LocationsFilter.new(locations)
|
36
|
+
compile [doc], receiver, [filter]
|
37
|
+
expect(receiver.test_case_locations).to eq locations
|
38
|
+
end
|
39
|
+
|
40
|
+
it "works with wildcard locations" do
|
41
|
+
locations = [
|
42
|
+
Test::Location.new('features/test.feature')
|
43
|
+
]
|
44
|
+
filter = Test::LocationsFilter.new(locations)
|
45
|
+
compile [doc], receiver, [filter]
|
46
|
+
expect(receiver.test_case_locations).to eq [
|
47
|
+
Test::Location.new('features/test.feature', 3),
|
48
|
+
Test::Location.new('features/test.feature', 6)
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "filters out scenarios that don't match" do
|
53
|
+
locations = [
|
54
|
+
Test::Location.new('features/test.feature', 3)
|
55
|
+
]
|
56
|
+
filter = Test::LocationsFilter.new(locations)
|
57
|
+
compile [doc], receiver, [filter]
|
58
|
+
expect(receiver.test_case_locations).to eq locations
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "matching location" do
|
62
|
+
let(:file) { 'features/path/to/the.feature' }
|
63
|
+
|
64
|
+
let(:test_cases) do
|
65
|
+
receiver = double.as_null_object
|
66
|
+
result = []
|
67
|
+
allow(receiver).to receive(:test_case) { |test_case| result << test_case }
|
68
|
+
compile [doc], receiver
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
context "for a scenario" do
|
73
|
+
let(:doc) do
|
74
|
+
Gherkin::Document.new(file, <<-END)
|
75
|
+
Feature:
|
76
|
+
|
77
|
+
Scenario: one
|
78
|
+
Given one a
|
79
|
+
|
80
|
+
# comment
|
81
|
+
@tags
|
82
|
+
Scenario: two
|
83
|
+
Given two a
|
84
|
+
And two b
|
85
|
+
|
86
|
+
Scenario: three
|
87
|
+
Given three b
|
88
|
+
|
89
|
+
Scenario: with docstring
|
90
|
+
Given a docstring
|
91
|
+
"""
|
92
|
+
this is a docstring
|
93
|
+
"""
|
94
|
+
|
95
|
+
Scenario: with a table
|
96
|
+
Given a table
|
97
|
+
| a | b |
|
98
|
+
| 1 | 2 |
|
99
|
+
| 3 | 4 |
|
100
|
+
|
101
|
+
END
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_case_named(name)
|
105
|
+
test_cases.find { |c| c.name == name }
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'matches the precise location of the scenario' do
|
109
|
+
location = test_case_named('two').location
|
110
|
+
filter = Test::LocationsFilter.new([location])
|
111
|
+
compile [doc], receiver, [filter]
|
112
|
+
expect(receiver.test_case_locations).to eq [test_case_named('two').location]
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'matches multiple locations' do
|
116
|
+
good_location = Test::Location.new(file, 8)
|
117
|
+
bad_location = Test::Location.new(file, 5)
|
118
|
+
filter = Test::LocationsFilter.new([good_location, bad_location])
|
119
|
+
compile [doc], receiver, [filter]
|
120
|
+
expect(receiver.test_case_locations).to eq [test_case_named('two').location]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "doesn't match a location after the scenario line" do
|
124
|
+
location = Test::Location.new(file, 9)
|
125
|
+
filter = Test::LocationsFilter.new([location])
|
126
|
+
compile [doc], receiver, [filter]
|
127
|
+
expect(receiver.test_case_locations).to eq []
|
128
|
+
end
|
129
|
+
|
130
|
+
it "doesn't match a location before the scenario line" do
|
131
|
+
location = Test::Location.new(file, 7)
|
132
|
+
filter = Test::LocationsFilter.new([location])
|
133
|
+
compile [doc], receiver, [filter]
|
134
|
+
expect(receiver.test_case_locations).to eq []
|
135
|
+
end
|
136
|
+
|
137
|
+
context "with duplicate locations in the filter" do
|
138
|
+
it "matches each test case only once" do
|
139
|
+
location_tc_two = test_case_named('two').location
|
140
|
+
location_tc_one = test_case_named('one').location
|
141
|
+
location_last_step_tc_two = Test::Location.new(file, 10)
|
142
|
+
filter = Test::LocationsFilter.new([location_tc_two, location_tc_one, location_last_step_tc_two])
|
143
|
+
compile [doc], receiver, [filter]
|
144
|
+
expect(receiver.test_case_locations).to eq [test_case_named('two').location, location_tc_one = test_case_named('one').location]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "for a scenario outline" do
|
150
|
+
let(:doc) do
|
151
|
+
Gherkin::Document.new(file, <<-END)
|
152
|
+
Feature:
|
153
|
+
|
154
|
+
Scenario: one
|
155
|
+
Given one a
|
156
|
+
|
157
|
+
# comment on line 6
|
158
|
+
@tags-on-line-7
|
159
|
+
Scenario Outline: two <arg>
|
160
|
+
Given two a
|
161
|
+
And two <arg>
|
162
|
+
"""
|
163
|
+
docstring
|
164
|
+
"""
|
165
|
+
|
166
|
+
# comment on line 15
|
167
|
+
@tags-on-line-16
|
168
|
+
Examples: x1
|
169
|
+
| arg |
|
170
|
+
| b |
|
171
|
+
|
172
|
+
Examples: x2
|
173
|
+
| arg |
|
174
|
+
| c |
|
175
|
+
| d |
|
176
|
+
|
177
|
+
Scenario: three
|
178
|
+
Given three b
|
179
|
+
END
|
180
|
+
end
|
181
|
+
|
182
|
+
let(:test_case) do
|
183
|
+
test_cases.find { |c| c.name == "two b" }
|
184
|
+
end
|
185
|
+
|
186
|
+
it "matches row location to the test case of the row" do
|
187
|
+
locations = [
|
188
|
+
Test::Location.new(file, 19),
|
189
|
+
]
|
190
|
+
filter = Test::LocationsFilter.new(locations)
|
191
|
+
compile [doc], receiver, [filter]
|
192
|
+
expect(receiver.test_case_locations).to eq [test_case.location]
|
193
|
+
end
|
194
|
+
|
195
|
+
it "matches outline location with the all test cases of all the tables" do
|
196
|
+
locations = [
|
197
|
+
Test::Location.new(file, 8),
|
198
|
+
]
|
199
|
+
filter = Test::LocationsFilter.new(locations)
|
200
|
+
compile [doc], receiver, [filter]
|
201
|
+
expect(receiver.test_case_locations.map(&:line)).to eq [19, 23, 24]
|
202
|
+
end
|
203
|
+
|
204
|
+
it "doesn't match the location of the examples line" do
|
205
|
+
location = Test::Location.new(file, 17)
|
206
|
+
filter = Test::LocationsFilter.new([location])
|
207
|
+
compile [doc], receiver, [filter]
|
208
|
+
expect(receiver.test_case_locations).to eq []
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context "under load", slow: true do
|
214
|
+
num_features = 50
|
215
|
+
num_scenarios_per_feature = 50
|
216
|
+
|
217
|
+
let(:docs) do
|
218
|
+
(1..num_features).map do |i|
|
219
|
+
gherkin("features/test_#{i}.feature") do
|
220
|
+
feature do
|
221
|
+
(1..num_scenarios_per_feature).each do |j|
|
222
|
+
scenario "scenario #{j}" do
|
223
|
+
step 'text'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
num_locations = num_features
|
232
|
+
let(:locations) do
|
233
|
+
(1..num_locations).map do |i|
|
234
|
+
(1..num_scenarios_per_feature).map do |j|
|
235
|
+
line = 3 + (j - 1) * 3
|
236
|
+
Test::Location.new("features/test_#{i}.feature", line)
|
237
|
+
end
|
238
|
+
end.flatten
|
239
|
+
end
|
240
|
+
|
241
|
+
max_duration_ms = 10000
|
242
|
+
max_duration_ms = max_duration_ms * 2.5 if defined?(JRUBY_VERSION)
|
243
|
+
it "filters #{num_features * num_scenarios_per_feature} test cases within #{max_duration_ms}ms" do
|
244
|
+
filter = Test::LocationsFilter.new(locations)
|
245
|
+
Timeout.timeout(max_duration_ms / 1000.0) do
|
246
|
+
compile docs, receiver, [filter]
|
247
|
+
end
|
248
|
+
expect(receiver.test_cases.length).to eq num_features * num_scenarios_per_feature
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class SpyReceiver
|
255
|
+
def test_case(test_case)
|
256
|
+
test_cases << test_case
|
257
|
+
end
|
258
|
+
|
259
|
+
def done
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_case_locations
|
263
|
+
test_cases.map(&:location)
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_cases
|
267
|
+
@test_cases ||= []
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'cucumber/core/test/location'
|
3
|
+
|
4
|
+
module Cucumber::Core::Test
|
5
|
+
RSpec::Matchers.define :be_included_in do |expected|
|
6
|
+
match do |actual|
|
7
|
+
expected.include? actual
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Location do
|
12
|
+
let(:line) { 12 }
|
13
|
+
let(:file) { "foo.feature" }
|
14
|
+
|
15
|
+
describe "equality" do
|
16
|
+
it "is equal to another Location on the same line of the same file" do
|
17
|
+
one_location = Location.new(file, line)
|
18
|
+
another_location = Location.new(file, line)
|
19
|
+
expect( one_location ).to eq another_location
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is not equal to a wild card of the same file" do
|
23
|
+
expect( Location.new(file, line) ).not_to eq Location.new(file)
|
24
|
+
end
|
25
|
+
|
26
|
+
context "collections of locations" do
|
27
|
+
it "behave as expected with uniq" do
|
28
|
+
unique_collection = [Location.new(file, line), Location.new(file, line)].uniq
|
29
|
+
expect( unique_collection ).to eq [Location.new(file, line)]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "to_s" do
|
35
|
+
it "is file:line for a precise location" do
|
36
|
+
expect( Location.new("foo.feature", 12).to_s ).to eq "foo.feature:12"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "is file for a wildcard location" do
|
40
|
+
expect( Location.new("foo.feature").to_s ).to eq "foo.feature"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "is file:first_line..last_line for a ranged location" do
|
44
|
+
expect( Location.new("foo.feature", 13..19).to_s ).to eq "foo.feature:13..19"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "is file:line:line:line for an arbitrary set of lines" do
|
48
|
+
expect( Location.new("foo.feature", [1,3,5]).to_s ).to eq "foo.feature:1:3:5"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "matches" do
|
53
|
+
let(:matching) { Location.new(file, line) }
|
54
|
+
let(:same_file_other_line) { Location.new(file, double) }
|
55
|
+
let(:not_matching) { Location.new(other_file, line) }
|
56
|
+
let(:other_file) { double }
|
57
|
+
|
58
|
+
context 'a precise location' do
|
59
|
+
let(:precise) { Location.new(file, line) }
|
60
|
+
|
61
|
+
it "matches a precise location of the same file and line" do
|
62
|
+
expect( matching ).to be_match(precise)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does not match a precise location on a different line in the same file" do
|
66
|
+
expect( matching ).not_to be_match(same_file_other_line)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'a wildcard' do
|
72
|
+
let(:wildcard) { Location.new(file) }
|
73
|
+
|
74
|
+
it "matches any location with the same filename" do
|
75
|
+
expect( wildcard ).to be_match(matching)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "is matched by any location of the same file" do
|
79
|
+
expect( matching ).to be_match(wildcard)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "does not match a location in a different file" do
|
83
|
+
expect( wildcard ).not_to be_match(not_matching)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "created from source location" do
|
89
|
+
context "when the location is in the tree below pwd" do
|
90
|
+
it "create a relative path from pwd" do
|
91
|
+
expect( Location.from_source_location(Dir.pwd + "/path/file.rb", 1).file ).to eq "path/file.rb"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when the location is in an installed gem" do
|
96
|
+
it "create a relative path from the gem directory" do
|
97
|
+
expect( Location.from_source_location("/path/gems/gem-name/path/file.rb", 1).file ).to eq "gem-name/path/file.rb"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when the location is neither below pwd nor in an installed gem" do
|
102
|
+
it "use the absolute path to the file" do
|
103
|
+
expect( Location.from_source_location("/path/file.rb", 1).file ).to eq "/path/file.rb"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "created from file-colon-line" do
|
109
|
+
it "handles also Windows paths" do
|
110
|
+
expect( Location.from_file_colon_line("c:\path\file.rb:123").file ).to eq "c:\path\file.rb"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "created of caller" do
|
115
|
+
it "use the location of the caller" do
|
116
|
+
expect( Location.of_caller.to_s ).to be_included_in caller[0]
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when specifying additional caller depth"do
|
120
|
+
it "use the location of the n:th caller" do
|
121
|
+
expect( Location.of_caller(1).to_s ).to be_included_in caller[1]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|