asciidoctor-doctest 2.0.0.beta.4 → 2.0.0.beta.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.adoc +58 -0
- data/LICENSE +21 -0
- data/README.adoc +310 -0
- data/asciidoctor-doctest.gemspec +48 -0
- data/data/examples/asciidoc/embedded.adoc +15 -0
- data/data/examples/asciidoc/preamble.adoc +1 -2
- data/data/examples/asciidoc/section.adoc +9 -0
- data/data/examples/asciidoc/toc.adoc +21 -9
- data/lib/asciidoctor/doctest/html/converter.rb +1 -1
- data/lib/asciidoctor/doctest/io/asciidoc.rb +2 -3
- data/lib/asciidoctor/doctest/io/base.rb +1 -1
- data/lib/asciidoctor/doctest/io/xml.rb +1 -1
- data/lib/asciidoctor/doctest/test_reporter.rb +3 -3
- data/lib/asciidoctor/doctest/version.rb +1 -1
- metadata +20 -69
- data/doc/img/doctest-diag.odf +0 -0
- data/doc/img/doctest-diag.svg +0 -56
- data/doc/img/failing-test-term.gif +0 -0
- data/features/README +0 -1
- data/features/fixtures/html-slim/Rakefile +0 -9
- data/features/fixtures/html-slim/examples/asciidoc/document.adoc +0 -4
- data/features/fixtures/html-slim/examples/asciidoc/inline_quoted.adoc +0 -2
- data/features/fixtures/html-slim/examples/asciidoc/quote.adoc +0 -12
- data/features/fixtures/html-slim/examples/html/document.html +0 -7
- data/features/fixtures/html-slim/examples/html/quote.html +0 -26
- data/features/fixtures/html-slim/templates/document.html.slim +0 -13
- data/features/fixtures/html-slim/templates/embedded.html.slim +0 -3
- data/features/fixtures/html-slim/templates/inline_quoted.html.slim +0 -8
- data/features/fixtures/html-slim/templates/paragraph.html.slim +0 -1
- data/features/fixtures/html-slim/templates/quote.html.slim +0 -7
- data/features/generator_html.feature +0 -171
- data/features/step_definitions/doctest_steps.rb +0 -5
- data/features/support/env.rb +0 -24
- data/features/test_html.feature +0 -98
- data/spec/asciidoc_converter_spec.rb +0 -64
- data/spec/example_spec.rb +0 -180
- data/spec/factory_spec.rb +0 -46
- data/spec/html/converter_spec.rb +0 -137
- data/spec/html_normalizer_spec.rb +0 -70
- data/spec/io/asciidoc_spec.rb +0 -139
- data/spec/io/xml_spec.rb +0 -141
- data/spec/minitest_diffy_spec.rb +0 -59
- data/spec/no_fallback_template_converter_spec.rb +0 -38
- data/spec/shared_examples/base_examples.rb +0 -289
- data/spec/spec_helper.rb +0 -39
- data/spec/support/matchers.rb +0 -7
- data/spec/tester_spec.rb +0 -153
data/spec/minitest_diffy_spec.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'asciidoctor/doctest/minitest_diffy'
|
2
|
-
require 'corefines'
|
3
|
-
|
4
|
-
using Corefines::String::color
|
5
|
-
|
6
|
-
describe Diffy::Format do
|
7
|
-
|
8
|
-
describe '#minitest' do
|
9
|
-
|
10
|
-
subject(:output) { input.minitest }
|
11
|
-
let(:input) { [] }
|
12
|
-
|
13
|
-
# This looks odd, but Diffy is actually using Format exactly like that.
|
14
|
-
# https://github.com/samg/diffy/blob/6e1f1312/lib/diffy/diff.rb#L132
|
15
|
-
before { input.extend described_class }
|
16
|
-
|
17
|
-
it { expect(described_class).to have_method :minitest }
|
18
|
-
|
19
|
-
context 'line starting with ---, or +++' do
|
20
|
-
let(:input) { ['--- a/file.rb', '+++ b/file.rb'] }
|
21
|
-
|
22
|
-
it 'discards the line' do
|
23
|
-
expect(output.chomp).to be_empty
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'line with ""' do
|
28
|
-
let(:input) { [''] }
|
29
|
-
|
30
|
-
it 'discards this line' do
|
31
|
-
expect(output.chomp).to be_empty
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'line starting with +' do
|
36
|
-
let(:input) { ['+ <div><p>chunky bacon</p></div>'] }
|
37
|
-
|
38
|
-
it 'replaces "+" with "A", adds padding and colour' do
|
39
|
-
is_expected.to eq "\n" + 'A <div><p>chunky bacon</p></div>'.color(:red)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'line starting with -' do
|
44
|
-
let(:input) { ['- <p>chunky bacon</p>'] }
|
45
|
-
|
46
|
-
it 'replaces "-" with "E", adds padding and colour' do
|
47
|
-
is_expected.to eq "\n" + 'E <p>chunky bacon</p>'.color(:green)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'normal lines' do
|
52
|
-
let(:input) { ['Lorem ipsum dolor', ' sit amet'] }
|
53
|
-
|
54
|
-
it 'returns the lines with padding' do
|
55
|
-
is_expected.to eq "\n Lorem ipsum dolor\n sit amet"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
describe DocTest::NoFallbackTemplateConverter do
|
2
|
-
|
3
|
-
subject(:delegator) { described_class.new('html5', template_dirs: ['/tmp/html5']) }
|
4
|
-
|
5
|
-
describe '#convert' do
|
6
|
-
|
7
|
-
let(:converter) { delegator.__getobj__ }
|
8
|
-
let(:node) { double('Node', node_name: 'block_foo') }
|
9
|
-
|
10
|
-
before do
|
11
|
-
expect(converter).to receive(:handles?).with('block_foo').and_return(handles)
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'when template is not found' do
|
15
|
-
let(:handles) { false }
|
16
|
-
|
17
|
-
it 'returns a not found marker instead of converted node' do
|
18
|
-
expect(converter).to_not receive(:convert)
|
19
|
-
expect(delegator.convert node).to eq described_class::NOT_FOUND_MARKER
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'prints a warning on stderr' do
|
23
|
-
expect { delegator.convert node }.to output(/Could not find a custom template/i).to_stderr
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'when template is found' do
|
28
|
-
let(:handles) { true }
|
29
|
-
|
30
|
-
it 'delegates to the original #convert and returns result' do
|
31
|
-
expect(converter).to receive(:convert)
|
32
|
-
.with(node, 'block_foo', {}).and_return('allons-y!')
|
33
|
-
|
34
|
-
expect(delegator.convert node).to eq 'allons-y!'
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,289 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
using Corefines::Array::second
|
5
|
-
|
6
|
-
shared_examples DocTest::IO::Base do
|
7
|
-
|
8
|
-
subject(:suite) { described_class.new(file_ext: '.adoc', path: path) }
|
9
|
-
let(:path) { ['/tmp/alpha', '/tmp/beta'] }
|
10
|
-
|
11
|
-
|
12
|
-
describe '#initialize' do
|
13
|
-
|
14
|
-
subject(:init) { described_class.new(args) }
|
15
|
-
let(:args) { {} }
|
16
|
-
|
17
|
-
{'nil' => nil, 'blank' => ' '}.each do |desc, file_ext|
|
18
|
-
context "with file_ext #{desc}" do
|
19
|
-
let(:args) { {file_ext: file_ext, path: path} }
|
20
|
-
it { expect { init }.to raise_error ArgumentError }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'with path string' do
|
25
|
-
let(:args) { {file_ext: '.html', path: '/foo/bar'} }
|
26
|
-
|
27
|
-
it 'wraps string to array' do
|
28
|
-
is_expected.to have_attributes(path: ['/foo/bar'])
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
describe '#parse' do
|
35
|
-
context 'empty file' do
|
36
|
-
subject { suite.parse '', 'block_ulist' }
|
37
|
-
|
38
|
-
it { is_expected.to be_empty }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
describe '#read_examples' do
|
44
|
-
include FakeFS::SpecHelpers
|
45
|
-
|
46
|
-
subject(:result) { suite.read_examples group_name }
|
47
|
-
|
48
|
-
let(:group_name) { 'section' }
|
49
|
-
|
50
|
-
before do
|
51
|
-
path.each { |p| FileUtils.mkpath p }
|
52
|
-
create_and_write_group path.first, 'noise', '.adoc', 'foo', 'bar'
|
53
|
-
|
54
|
-
allow(suite).to receive(:parse) do |input, group_name|
|
55
|
-
path, file_name, *example_names = input.split("\n")
|
56
|
-
expect(group_name).to eq file_name.split('.').first
|
57
|
-
|
58
|
-
example_names.map do |name|
|
59
|
-
# this content is just filling to identify the example in test
|
60
|
-
create_example [group_name, name], content: "#{path}/#{file_name}:#{name}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "when the group's file is not found" do
|
66
|
-
it { is_expected.to be_empty }
|
67
|
-
end
|
68
|
-
|
69
|
-
context "when the group's file has a wrong file extension" do
|
70
|
-
before do
|
71
|
-
create_and_write_group path.first, group_name, '.html', 'level1', 'level2'
|
72
|
-
end
|
73
|
-
|
74
|
-
it { is_expected.to be_empty }
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'when single group file is found' do
|
78
|
-
let! :examples do
|
79
|
-
create_and_write_group path.second, group_name, '.adoc', 'level1', 'level2'
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'returns parsed examples' do
|
83
|
-
is_expected.to eq examples
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
context 'when multiple group files are found and contains example with same name' do
|
88
|
-
let! :examples do
|
89
|
-
first = create_and_write_group path.first, group_name, '.adoc', 'level1', 'level2'
|
90
|
-
second = create_and_write_group path.second, group_name, '.adoc', 'level2', 'level3'
|
91
|
-
[*first, second[1]]
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'returns parsed examples without duplicates (first wins)' do
|
95
|
-
is_expected.to eq examples
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
describe '#write_examples' do
|
102
|
-
include FakeFS::SpecHelpers
|
103
|
-
|
104
|
-
let :examples do
|
105
|
-
(1..2).map { |i| create_example "section:level#{i}", content: 'yada' }
|
106
|
-
end
|
107
|
-
|
108
|
-
before { path.each { |p| FileUtils.mkpath p } }
|
109
|
-
|
110
|
-
it 'writes serialized examples to file named after the group with file extension' do
|
111
|
-
expect(suite).to receive :serialize do |exmpls|
|
112
|
-
exmpls.map(&:name).join("\n")
|
113
|
-
end
|
114
|
-
suite.write_examples examples
|
115
|
-
|
116
|
-
file = File.read "#{path.first}/section.adoc"
|
117
|
-
expect(file).to eq examples.map(&:name).join("\n")
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
describe '#file_names' do
|
123
|
-
include FakeFS::SpecHelpers
|
124
|
-
|
125
|
-
subject(:result) { suite.group_names }
|
126
|
-
|
127
|
-
before { path.each { |p| FileUtils.mkpath p } }
|
128
|
-
|
129
|
-
context 'when no file is found' do
|
130
|
-
it { is_expected.to be_empty }
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'returns names of files with matching file extension only' do
|
134
|
-
%w[block_image.html block_ulist.adoc].each do |name|
|
135
|
-
File.write "#{path.first}/#{name}", 'yada'
|
136
|
-
end
|
137
|
-
is_expected.to contain_exactly 'block_ulist'
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'returns names sorted and deduplicated' do
|
141
|
-
(names = %w[z j d c k d]).each_with_index do |name, i|
|
142
|
-
File.write "#{path[i % 2]}/#{name}.adoc", 'yada'
|
143
|
-
end
|
144
|
-
|
145
|
-
is_expected.to eq names.uniq.sort
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'ignores directories and files in subdirectories' do
|
149
|
-
Dir.mkdir "#{path.first}/invalid.adoc"
|
150
|
-
File.write "#{path.first}/invalid.adoc/wat.adoc", 'yada'
|
151
|
-
|
152
|
-
is_expected.to be_empty
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
|
157
|
-
describe '#update_examples' do
|
158
|
-
|
159
|
-
let :current do
|
160
|
-
%w[gr0:ex0 gr0:ex1 gr1:ex0 gr1:ex1].map do |name|
|
161
|
-
create_example name, content: name.reverse
|
162
|
-
end
|
163
|
-
end
|
164
|
-
let :updated do
|
165
|
-
[ (create_example 'gr0:ex0', content: 'allons-y!'),
|
166
|
-
(create_example 'gr1:ex1', content: 'allons-y!') ]
|
167
|
-
end
|
168
|
-
|
169
|
-
before do
|
170
|
-
expect(suite).to receive(:read_examples).exactly(2).times do |group_name|
|
171
|
-
current.select { |e| e.group_name == group_name }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'merges current and updated examples and writes them' do
|
176
|
-
is_expected.to receive(:write_examples).with [updated[0], current[1]]
|
177
|
-
is_expected.to receive(:write_examples).with [current[2], updated[1]]
|
178
|
-
|
179
|
-
suite.update_examples updated
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
|
184
|
-
describe '#pair_with' do
|
185
|
-
|
186
|
-
subject(:result) { ours_suite.pair_with(theirs_suite).to_a }
|
187
|
-
let(:result_names) { result.map(&:first).map(&:name) }
|
188
|
-
|
189
|
-
let(:ours_suite) { described_class.new(file_ext: '.xyz') }
|
190
|
-
let(:theirs_suite) { DocTest::IO::Asciidoc.new(file_ext: '.adoc') }
|
191
|
-
|
192
|
-
def ours_exmpl(suffix, group = 0)
|
193
|
-
create_example "gr#{group}:ex#{suffix}", content: 'ours!'
|
194
|
-
end
|
195
|
-
|
196
|
-
def theirs_exmpl(suffix, group = 0)
|
197
|
-
create_example "gr#{group}:ex#{suffix}", content: 'theirs!'
|
198
|
-
end
|
199
|
-
|
200
|
-
before do
|
201
|
-
expect(ours_suite).to receive(:group_names)
|
202
|
-
.and_return(['gr0', 'gr1'])
|
203
|
-
expect(theirs_suite).to receive(:read_examples)
|
204
|
-
.with(/gr[0-1]/).exactly(:twice).and_return(*theirs)
|
205
|
-
expect(ours_suite).to receive(:read_examples)
|
206
|
-
.with(/gr[0-1]/).exactly(:twice).and_return(*ours)
|
207
|
-
end
|
208
|
-
|
209
|
-
context do
|
210
|
-
let :ours do
|
211
|
-
[ [ ours_exmpl(0, 0), ours_exmpl(1, 0) ], [ ours_exmpl(0, 1), ours_exmpl(1, 1) ] ]
|
212
|
-
end
|
213
|
-
let :theirs do
|
214
|
-
[ [ theirs_exmpl(1, 0), theirs_exmpl(0, 0) ], [ theirs_exmpl(0, 1), theirs_exmpl(1, 1) ] ]
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'returns pairs of ours/theirs examples in ours order' do
|
218
|
-
expect(result_names).to eq %w[gr0:ex0 gr0:ex1 gr1:ex0 gr1:ex1]
|
219
|
-
expect(result).to eq ours.flatten(1).zip theirs.flatten(1).sort_by(&:name)
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
context 'when some example is missing' do
|
224
|
-
let(:ours) { [(0..2).map { |i| ours_exmpl i }, []] }
|
225
|
-
let(:theirs) { [[1, 0, 2].map { |i| theirs_exmpl i }, []] }
|
226
|
-
|
227
|
-
context 'in theirs suite' do
|
228
|
-
let(:theirs) { [ [theirs_exmpl(2), theirs_exmpl(0)], [] ] }
|
229
|
-
|
230
|
-
it 'returns pairs in ours order' do
|
231
|
-
expect(result_names).to eq %w[gr0:ex0 gr0:ex1 gr0:ex2]
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'replaces the missing example with empty one with the name' do
|
235
|
-
expect(result.second.last).to eq create_example 'gr0:ex1'
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
context 'in ours suite' do
|
240
|
-
let(:ours) { [ [ours_exmpl(1), ours_exmpl(2)], [] ] }
|
241
|
-
|
242
|
-
it 'returns pairs in ours order with the missing example at the end' do
|
243
|
-
expect(result_names).to eq %w[gr0:ex1 gr0:ex2 gr0:ex0]
|
244
|
-
end
|
245
|
-
|
246
|
-
it 'replaces the missing example with empty one with the name' do
|
247
|
-
expect(result.last.first).to eq create_example 'gr0:ex0'
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
|
254
|
-
describe '#format_options' do
|
255
|
-
|
256
|
-
shared_examples :format_options do |input, output|
|
257
|
-
it "returns #{output} for #{input}" do
|
258
|
-
expect(suite.send(:format_options, input)).to eq output
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
context 'empty' do
|
263
|
-
include_examples :format_options, {}, []
|
264
|
-
end
|
265
|
-
|
266
|
-
context 'options with one value' do
|
267
|
-
include_examples :format_options, {opt1: 'val1', opt2: 'val2'}, [':opt1: val1', ':opt2: val2']
|
268
|
-
end
|
269
|
-
|
270
|
-
context 'options with multiple values' do
|
271
|
-
include_examples :format_options, {opt1: %w[val11 val12], opt2: ['val2']},
|
272
|
-
[':opt1: val11', ':opt1: val12', ':opt2: val2']
|
273
|
-
end
|
274
|
-
|
275
|
-
context 'boolean options' do
|
276
|
-
include_examples :format_options, {opt1: true, opt2: false}, [':opt1:', ':opt2: false']
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
|
281
|
-
def create_and_write_group(path, group_name, file_ext, *examples)
|
282
|
-
content = [path, group_name + file_ext, *examples].join("\n")
|
283
|
-
File.write File.join(path, group_name + file_ext), content
|
284
|
-
|
285
|
-
examples.map do |name|
|
286
|
-
create_example [group_name, name], content: "#{path}/#{group_name}#{file_ext}:#{name}"
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'corefines'
|
2
|
-
require 'rspec/collection_matchers'
|
3
|
-
require 'simplecov'
|
4
|
-
require 'asciidoctor/doctest'
|
5
|
-
require 'fakefs/spec_helpers'
|
6
|
-
|
7
|
-
Dir['./spec/{shared_examples,support}/**/*.rb'].each { |file| require file }
|
8
|
-
|
9
|
-
RSpec.configure do |config|
|
10
|
-
|
11
|
-
# rspec-expectations config
|
12
|
-
config.expect_with :rspec do |expects|
|
13
|
-
|
14
|
-
# This option disables deprecated 'should' syntax.
|
15
|
-
expects.syntax = :expect
|
16
|
-
|
17
|
-
# This option makes the +description+ and +failure_message+ of custom
|
18
|
-
# matchers include text for helper methods defined using +chain+, e.g.:
|
19
|
-
# be_bigger_than(2).and_smaller_than(4).description
|
20
|
-
# # => "be bigger than 2 and smaller than 4"
|
21
|
-
# ...rather than:
|
22
|
-
# # => "be bigger than 2"
|
23
|
-
expects.include_chain_clauses_in_custom_matcher_descriptions = true
|
24
|
-
end
|
25
|
-
|
26
|
-
# rspec-mocks config
|
27
|
-
config.mock_with :rspec do |mocks|
|
28
|
-
|
29
|
-
# Prevents you from mocking or stubbing a method that does not exist on
|
30
|
-
# a real object.
|
31
|
-
mocks.verify_partial_doubles = true
|
32
|
-
end
|
33
|
-
|
34
|
-
config.color = true
|
35
|
-
end
|
36
|
-
|
37
|
-
def create_example(*args)
|
38
|
-
DocTest::Example.new(*args)
|
39
|
-
end
|
data/spec/support/matchers.rb
DELETED
data/spec/tester_spec.rb
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
describe DocTest::Tester do
|
2
|
-
|
3
|
-
subject(:tester) { described_class.new(input_suite, output_suite, converter, reporter) }
|
4
|
-
|
5
|
-
let(:converter) { double 'converter' }
|
6
|
-
let(:input_suite) { double 'ExamplesSuite' }
|
7
|
-
let(:output_suite) { double 'ExamplesSuite' }
|
8
|
-
let(:reporter) { spy 'Reporter' }
|
9
|
-
let(:examples) { fixtures }
|
10
|
-
|
11
|
-
|
12
|
-
describe '#initialize' do
|
13
|
-
|
14
|
-
context "with default reporter" do
|
15
|
-
subject(:tester) { described_class.new(input_suite, output_suite, converter, nil) }
|
16
|
-
|
17
|
-
it { expect(tester.reporter).to be_a DocTest::TestReporter }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
describe '#run_tests' do
|
23
|
-
|
24
|
-
before do |ex|
|
25
|
-
next if ex.metadata[:skip_before]
|
26
|
-
|
27
|
-
expect(input_suite).to receive(:pair_with)
|
28
|
-
.with(output_suite).and_return(examples.values)
|
29
|
-
allow(tester).to receive(:test_example)
|
30
|
-
end
|
31
|
-
|
32
|
-
context "with default pattern" do
|
33
|
-
|
34
|
-
it "pairs the examples and tests all valid pairs" do
|
35
|
-
['ex:alpha', 'ex:beta', 'ex:nooutput'].each do |name|
|
36
|
-
expect(tester).to receive(:test_example).with(*examples[name])
|
37
|
-
end
|
38
|
-
tester.run_tests
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "with specific pattern" do
|
43
|
-
|
44
|
-
it "pairs the examples and tests those matching the pattern" do
|
45
|
-
expect(tester).to receive(:test_example).with(*examples['ex:beta'])
|
46
|
-
tester.run_tests(pattern: 'ex:b*')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it "ignores pairs with empty input example" do
|
51
|
-
expect(tester).to_not receive(:test_example).with(*examples['ex:noinput'])
|
52
|
-
tester.run_tests
|
53
|
-
end
|
54
|
-
|
55
|
-
it "calls reporter's methods in the correct order", :skip_before do
|
56
|
-
expect(reporter).to receive(:start).ordered
|
57
|
-
expect(input_suite).to receive(:pair_with).and_return([]).ordered
|
58
|
-
expect(reporter).to receive(:report).ordered
|
59
|
-
expect(reporter).to receive(:passed?).ordered
|
60
|
-
|
61
|
-
tester.run_tests
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
describe '#test_example' do
|
67
|
-
|
68
|
-
subject(:failures) { tester.test_example input_exmpl, output_exmpl }
|
69
|
-
|
70
|
-
let(:examples_pair) { examples['ex:alpha'] }
|
71
|
-
let(:input_exmpl) { examples_pair[0] }
|
72
|
-
let(:output_exmpl) { examples_pair[1] }
|
73
|
-
let(:actual) { output_exmpl.content }
|
74
|
-
let(:expected) { output_exmpl.content }
|
75
|
-
|
76
|
-
shared_examples :example do
|
77
|
-
it "calls reporter" do
|
78
|
-
expect(reporter).to receive(:record)
|
79
|
-
tester.test_example input_exmpl, output_exmpl
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
before do |ex|
|
84
|
-
next if ex.metadata[:skip_before]
|
85
|
-
|
86
|
-
expect(converter).to receive(:convert_examples)
|
87
|
-
.with(input_exmpl, output_exmpl)
|
88
|
-
.and_return([actual, expected])
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
context "when output example is empty", :skip_before do
|
93
|
-
|
94
|
-
let(:examples_pair) { examples['ex:nooutput'] }
|
95
|
-
|
96
|
-
it "skips the test" do
|
97
|
-
is_expected.to contain_exactly Minitest::Skip
|
98
|
-
end
|
99
|
-
|
100
|
-
include_examples :example
|
101
|
-
end
|
102
|
-
|
103
|
-
context "when examples are equivalent" do
|
104
|
-
|
105
|
-
it "returns no failure" do
|
106
|
-
is_expected.to be_empty
|
107
|
-
end
|
108
|
-
|
109
|
-
include_examples :example
|
110
|
-
end
|
111
|
-
|
112
|
-
context "when examples are not equivalent" do
|
113
|
-
|
114
|
-
let(:actual) { '<em>meh</em>' }
|
115
|
-
|
116
|
-
it "returns failure" do
|
117
|
-
is_expected.to include Minitest::Assertion
|
118
|
-
end
|
119
|
-
|
120
|
-
context "and input example has desc:" do
|
121
|
-
|
122
|
-
it "returns failure with message that starts with the desc" do
|
123
|
-
expect(failures.first.message).to match /^yada.*/
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
context "and both input and output examples have desc:" do
|
128
|
-
|
129
|
-
let(:examples_pair) { examples['ex:beta'] }
|
130
|
-
|
131
|
-
it "returns failure with message that starts with the output's example desc" do
|
132
|
-
expect(failures.first.message).to match /^Yoda.*/
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
include_examples :example
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
|
-
def fixtures
|
142
|
-
data = {
|
143
|
-
'ex:alpha' => [ {content: '_alpha_', desc: 'yada'}, {content: '<i>alpha</i>'} ],
|
144
|
-
'ex:beta' => [ {content: '*beta*', desc: 'yada'}, {content: '<b>beta</b>', desc: 'Yoda'} ],
|
145
|
-
'ex:noinput' => [ {}, {content: '<del>noinput</del>'} ],
|
146
|
-
'ex:nooutput' => [ {content: 'nooutput'}, {} ]
|
147
|
-
}
|
148
|
-
data = data.map { |name, tuple|
|
149
|
-
[ name, tuple.map { |opts| DocTest::Example.new(name, opts) } ]
|
150
|
-
}
|
151
|
-
Hash[data]
|
152
|
-
end
|
153
|
-
end
|