asciidoctor-doctest 2.0.0.beta.4 → 2.0.0.beta.5
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.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
|