asciidoctor-doctest 1.5.2.0 → 2.0.0.beta.1
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 +4 -4
- data/LICENSE +1 -1
- data/README.adoc +48 -68
- data/features/fixtures/html-slim/Rakefile +5 -11
- data/features/generator_html.feature +6 -6
- data/features/test_html.feature +70 -28
- data/lib/asciidoctor/doctest.rb +11 -14
- data/lib/asciidoctor/doctest/asciidoc_converter.rb +85 -0
- data/lib/asciidoctor/doctest/{base_example.rb → example.rb} +6 -27
- data/lib/asciidoctor/doctest/factory.rb +36 -0
- data/lib/asciidoctor/doctest/generator.rb +30 -23
- data/lib/asciidoctor/doctest/html/converter.rb +64 -0
- data/lib/asciidoctor/doctest/{html/normalizer.rb → html_normalizer.rb} +4 -4
- data/lib/asciidoctor/doctest/io.rb +14 -0
- data/lib/asciidoctor/doctest/{asciidoc/examples_suite.rb → io/asciidoc.rb} +4 -8
- data/lib/asciidoctor/doctest/{base_examples_suite.rb → io/base.rb} +28 -46
- data/lib/asciidoctor/doctest/io/xml.rb +69 -0
- data/lib/asciidoctor/doctest/no_fallback_template_converter.rb +42 -0
- data/lib/asciidoctor/doctest/rake_tasks.rb +229 -0
- data/lib/asciidoctor/doctest/test_reporter.rb +110 -0
- data/lib/asciidoctor/doctest/tester.rb +134 -0
- data/lib/asciidoctor/doctest/version.rb +1 -1
- data/spec/asciidoc_converter_spec.rb +64 -0
- data/spec/{base_example_spec.rb → example_spec.rb} +4 -5
- data/spec/factory_spec.rb +46 -0
- data/spec/html/converter_spec.rb +95 -0
- data/spec/{html/normalizer_spec.rb → html_normalizer_spec.rb} +1 -1
- data/spec/{asciidoc/examples_suite_spec.rb → io/asciidoc_spec.rb} +3 -8
- data/spec/{html/examples_suite_spec.rb → io/xml_spec.rb} +3 -106
- data/spec/no_fallback_template_converter_spec.rb +38 -0
- data/spec/shared_examples/{base_examples_suite.rb → base_examples.rb} +25 -28
- data/spec/spec_helper.rb +4 -0
- data/spec/tester_spec.rb +153 -0
- metadata +52 -59
- data/features/fixtures/html-slim/test/html_test.rb +0 -6
- data/features/fixtures/html-slim/test/test_helper.rb +0 -5
- data/lib/asciidoctor/doctest/asciidoc_renderer.rb +0 -111
- data/lib/asciidoctor/doctest/generator_task.rb +0 -115
- data/lib/asciidoctor/doctest/html/example.rb +0 -21
- data/lib/asciidoctor/doctest/html/examples_suite.rb +0 -118
- data/lib/asciidoctor/doctest/test.rb +0 -125
- data/spec/asciidoc_renderer_spec.rb +0 -103
- data/spec/test_spec.rb +0 -164
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'asciidoctor/doctest/minitest_diffy'
|
2
|
+
require 'asciidoctor/doctest/test_reporter'
|
3
|
+
require 'corefines'
|
4
|
+
require 'minitest'
|
5
|
+
|
6
|
+
using Corefines::Object::presence
|
7
|
+
|
8
|
+
module Asciidoctor
|
9
|
+
module DocTest
|
10
|
+
class Tester
|
11
|
+
|
12
|
+
##
|
13
|
+
# @return [Minitest::Reporter] an instance of minitest's +Reporter+
|
14
|
+
# to report test results.
|
15
|
+
attr_reader :reporter
|
16
|
+
|
17
|
+
##
|
18
|
+
# @param input_suite [IO::Base] an instance of {IO::Base} subclass to
|
19
|
+
# read the reference input examples from.
|
20
|
+
#
|
21
|
+
# @param output_suite [IO::Base] an instance of {IO::Base} subclass to
|
22
|
+
# read the output examples from (i.e. an expected output).
|
23
|
+
#
|
24
|
+
# @param converter [#call] a callable that accepts a string content of
|
25
|
+
# an input example and a hash with options for the converter, and
|
26
|
+
# returns the converted content.
|
27
|
+
#
|
28
|
+
# @param reporter [Minitest::Reporter, nil] an instance of minitest's
|
29
|
+
# +Reporter+ to report test results. When omitted or +nil+, then
|
30
|
+
# {TestReporter} is used.
|
31
|
+
#
|
32
|
+
def initialize(input_suite, output_suite, converter, reporter = nil)
|
33
|
+
@input_suite = input_suite
|
34
|
+
@output_suite = output_suite
|
35
|
+
@converter = converter
|
36
|
+
@reporter = reporter || TestReporter.new
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Runs tests for all the input/output examples which name matches
|
41
|
+
# the _pattern_. When some output example is missing, it's reported as
|
42
|
+
# a skipped test.
|
43
|
+
#
|
44
|
+
# @param pattern [String] glob-like pattern to select examples to test
|
45
|
+
# (see {Example#name_match?}).
|
46
|
+
#
|
47
|
+
def run_tests(pattern: '*:*')
|
48
|
+
@reporter.start
|
49
|
+
|
50
|
+
@input_suite.pair_with(@output_suite).each do |input, output|
|
51
|
+
next if input.empty? || !input.name_match?(pattern)
|
52
|
+
test_example input, output
|
53
|
+
end
|
54
|
+
|
55
|
+
@reporter.report
|
56
|
+
@reporter.passed?
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Tests if the given reference input is matching the expected output
|
61
|
+
# after conversion through the tested backend.
|
62
|
+
#
|
63
|
+
# @param input_exmpl [Example] the reference input example.
|
64
|
+
# @param output_exmpl [Example] the expected output example.
|
65
|
+
#
|
66
|
+
def test_example(input_exmpl, output_exmpl)
|
67
|
+
test_with_minitest input_exmpl.name do |test|
|
68
|
+
if output_exmpl.empty?
|
69
|
+
test.skip 'No expected output found'
|
70
|
+
else
|
71
|
+
actual, expected = @converter.convert_examples(input_exmpl, output_exmpl)
|
72
|
+
msg = output_exmpl.desc.presence || input_exmpl.desc
|
73
|
+
|
74
|
+
test.assert_equal expected, actual, msg
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
##
|
82
|
+
# Runs the given block with Minitest as a single test.
|
83
|
+
#
|
84
|
+
# @param [String, Symbol] test name.
|
85
|
+
# @yield [Minitest::Test] Gives the test context to the block.
|
86
|
+
#
|
87
|
+
def test_with_minitest(name, &block)
|
88
|
+
MinitestSingleTest.test! @reporter, name, name, block
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# @private
|
93
|
+
class MinitestSingleTest < Minitest::Test
|
94
|
+
include MinitestDiffy
|
95
|
+
|
96
|
+
# @note Overrides method from +Minitest::Test+.
|
97
|
+
attr_reader :location
|
98
|
+
|
99
|
+
def self.test!(reporter, name, location, callable)
|
100
|
+
new(reporter, name, location, callable).failures
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def initialize(reporter, name, location, callable)
|
106
|
+
super name
|
107
|
+
@reporter = reporter
|
108
|
+
@location = location
|
109
|
+
@callable = callable
|
110
|
+
run
|
111
|
+
@reporter.record(self)
|
112
|
+
end
|
113
|
+
|
114
|
+
# @note Overrides method from +Minitest::Test+.
|
115
|
+
def run
|
116
|
+
with_info_handler do
|
117
|
+
time_it do
|
118
|
+
capture_exceptions do
|
119
|
+
@callable.call(self)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
self # per contract
|
125
|
+
end
|
126
|
+
|
127
|
+
# @note Overrides method from +Minitest::Assertions+.
|
128
|
+
def mu_pp(example)
|
129
|
+
example.to_s
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
describe DocTest::AsciidocConverter do
|
4
|
+
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
it { is_expected.to have_method :convert, :call }
|
8
|
+
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
|
12
|
+
context 'with defaults' do
|
13
|
+
subject { described_class.new.opts }
|
14
|
+
it { is_expected.to include safe: :safe }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with backend_name' do
|
18
|
+
subject { described_class.new(backend_name: 'html5').opts }
|
19
|
+
it { is_expected.to include backend: 'html5' }
|
20
|
+
|
21
|
+
context 'empty string' do
|
22
|
+
subject { described_class.new(backend_name: '').opts }
|
23
|
+
it { is_expected.to_not include :backend }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with template_dirs' do
|
28
|
+
include FakeFS::SpecHelpers
|
29
|
+
|
30
|
+
subject { described_class.new(template_dirs: template_dirs).opts }
|
31
|
+
let(:template_dirs) { ['/tmp/html5'] }
|
32
|
+
|
33
|
+
before { FileUtils.mkpath template_dirs[0] }
|
34
|
+
|
35
|
+
context 'that exists' do
|
36
|
+
it do
|
37
|
+
is_expected.to include(
|
38
|
+
template_dirs: template_dirs,
|
39
|
+
converter: DocTest::NoFallbackTemplateConverter
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'and templates_fallback is true' do
|
44
|
+
subject { described_class.new(template_dirs: template_dirs, templates_fallback: true).opts }
|
45
|
+
it { is_expected.to include template_dirs: template_dirs }
|
46
|
+
it { is_expected.to_not include :converter }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'and custom converter' do
|
50
|
+
subject { described_class.new(template_dirs: template_dirs, converter: converter).opts }
|
51
|
+
let(:converter) { Asciidoctor::Converter::TemplateConverter }
|
52
|
+
|
53
|
+
it { is_expected.to include template_dirs: template_dirs, converter: converter }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "that doesn't exist" do
|
58
|
+
let(:template_dirs) { ['/tmp/html5', '/tmp/revealjs'] }
|
59
|
+
|
60
|
+
it { expect { subject }.to raise_error ArgumentError }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
|
-
describe DocTest::
|
1
|
+
describe DocTest::Example do
|
2
2
|
|
3
3
|
subject(:o) { described_class.new ['foo', 'bar'] }
|
4
4
|
|
5
5
|
it do
|
6
|
-
is_expected.to respond_to :group_name, :local_name, :desc, :opts, :content
|
7
|
-
:content_normalized, :content_pretty
|
6
|
+
is_expected.to respond_to :group_name, :local_name, :desc, :opts, :content
|
8
7
|
end
|
9
8
|
|
10
9
|
describe '#name' do
|
@@ -156,8 +155,8 @@ describe DocTest::BaseExample do
|
|
156
155
|
expect(first).to_not eq second
|
157
156
|
end
|
158
157
|
|
159
|
-
it 'returns false for instances with different
|
160
|
-
expect(second).to receive(:
|
158
|
+
it 'returns false for instances with different content' do
|
159
|
+
expect(second).to receive(:content).and_return('ALLONS-Y!')
|
161
160
|
expect(first).to_not eq second
|
162
161
|
end
|
163
162
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
describe DocTest::Factory do
|
4
|
+
|
5
|
+
subject(:factory) { Module.new { extend DocTest::Factory } }
|
6
|
+
|
7
|
+
let(:default_opts) { {} }
|
8
|
+
|
9
|
+
before do
|
10
|
+
factory.register(:foo, OpenStruct, default_opts)
|
11
|
+
factory.register(:bar, String, 'illegal')
|
12
|
+
factory.register(:baz, Integer)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.create' do
|
16
|
+
it "returns instance of registered class" do
|
17
|
+
expect( factory.create(:foo) ).to eq OpenStruct.new
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with opts" do
|
21
|
+
it "initializes class with opts" do
|
22
|
+
expect( factory.create(:foo, a: 42) ).to eq OpenStruct.new(a: 42)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when class with default_opts" do
|
26
|
+
let(:default_opts) { {a: 1, b: 2} }
|
27
|
+
|
28
|
+
it "initializes class with opts merged with default_opts" do
|
29
|
+
expect( factory.create(:foo, b: 6) ).to eq OpenStruct.new(a: 1, b: 6)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when class with default_opts" do
|
35
|
+
let(:default_opts) { {a: 1, b: 2} }
|
36
|
+
|
37
|
+
it "initializes class with default_opts" do
|
38
|
+
expect( factory.create(:foo) ).to eq OpenStruct.new(default_opts)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with unregistered name" do
|
43
|
+
it { expect { factory.create(:unknown) }.to raise_error(ArgumentError) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module DocTest
|
4
|
+
describe HTML::Converter do
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegator :converter, :convert_examples
|
8
|
+
|
9
|
+
subject(:converter) { described_class.new }
|
10
|
+
|
11
|
+
describe '#convert_examples' do
|
12
|
+
|
13
|
+
let(:input) { Example.new 's:dummy', content: '*chunky* bacon' }
|
14
|
+
let(:output) { Example.new 's:dummy', content: '<b>chunky</b> bacon', opts: opts }
|
15
|
+
let(:opts) { {dummy: 'value'} }
|
16
|
+
let(:converter_opts) { {header_footer: false} }
|
17
|
+
|
18
|
+
subject(:result) { convert_examples input, output }
|
19
|
+
|
20
|
+
let :rendered do
|
21
|
+
<<-EOF
|
22
|
+
<section>
|
23
|
+
<h1>Title</h1>
|
24
|
+
<div>
|
25
|
+
<p><b>Chunky</b> bacon</p>
|
26
|
+
</div>
|
27
|
+
<code>meh</code>
|
28
|
+
</section>
|
29
|
+
<div>
|
30
|
+
<p>why?</p>
|
31
|
+
</div>
|
32
|
+
EOF
|
33
|
+
end
|
34
|
+
|
35
|
+
before do
|
36
|
+
expect(converter).to receive(:convert)
|
37
|
+
.with(input.content, converter_opts).and_return(rendered)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns array of converted input content and output content'
|
41
|
+
|
42
|
+
context 'with :exclude option' do
|
43
|
+
let(:opts) { {exclude: ['.//p', './/code']} }
|
44
|
+
|
45
|
+
it 'returns content without HTML (sub)elements specified by XPath' do
|
46
|
+
expect(result.first.gsub(/\s*/, '')).to eq \
|
47
|
+
'<section><h1>Title</h1><div></div></section><div></div>'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with :include option' do
|
52
|
+
let(:opts) { {include: ['.//p']} }
|
53
|
+
|
54
|
+
it 'returns content with only HTML (sub)elements specified by XPath' do
|
55
|
+
expect(result.first.gsub(/\s*/, '')).to eq '<p><b>Chunky</b>bacon</p><p>why?</p>'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with :header_footer option' do
|
60
|
+
let(:opts) { {header_footer: true} }
|
61
|
+
let(:converter_opts) { {header_footer: true} }
|
62
|
+
|
63
|
+
it 'renders content with :header_footer => true' do
|
64
|
+
convert_examples input, output
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with example named /^document.*/' do
|
69
|
+
let(:input) { Example.new 'document:dummy', content: '*chunky* bacon' }
|
70
|
+
let(:converter_opts) { {header_footer: true} }
|
71
|
+
|
72
|
+
it 'renders content with :header_footer => true' do
|
73
|
+
convert_examples input, output
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with example named /inline_.*/' do
|
78
|
+
let(:input) { Example.new 'inline_quoted:dummy', content: '*chunky* bacon' }
|
79
|
+
let(:rendered) { '<p><b>chunky</b> bacon</p>' }
|
80
|
+
|
81
|
+
it 'returns content without top-level <p> tags' do
|
82
|
+
expect(result.first).to eq '<b>chunky</b> bacon'
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with :include option' do
|
86
|
+
let(:opts) { {include: ['.//b']} }
|
87
|
+
|
88
|
+
it 'preferes the include option' do
|
89
|
+
expect(result.first).to eq '<b>chunky</b>'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -1,15 +1,10 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
1
|
using Corefines::String::unindent
|
4
2
|
|
5
|
-
describe DocTest::Asciidoc
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
it_should_behave_like DocTest::BaseExamplesSuite
|
3
|
+
describe DocTest::IO::Asciidoc do
|
9
4
|
|
10
|
-
|
5
|
+
it_should_behave_like DocTest::IO::Base
|
11
6
|
|
12
|
-
subject(:suite) { described_class.new }
|
7
|
+
subject(:suite) { described_class.new(file_ext: '.adoc') }
|
13
8
|
|
14
9
|
|
15
10
|
describe '#initialize' do
|
@@ -1,15 +1,10 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
1
|
using Corefines::String::unindent
|
4
2
|
|
5
|
-
describe DocTest::
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
it_should_behave_like DocTest::BaseExamplesSuite
|
3
|
+
describe DocTest::IO::XML do
|
9
4
|
|
10
|
-
|
5
|
+
it_should_behave_like DocTest::IO::Base
|
11
6
|
|
12
|
-
subject(:suite) { described_class.new }
|
7
|
+
subject(:suite) { described_class.new(file_ext: '.html') }
|
13
8
|
|
14
9
|
|
15
10
|
describe '#initialize' do
|
@@ -143,102 +138,4 @@ describe DocTest::HTML::ExamplesSuite do
|
|
143
138
|
end
|
144
139
|
end
|
145
140
|
end
|
146
|
-
|
147
|
-
|
148
|
-
describe '#convert_example' do
|
149
|
-
|
150
|
-
let(:input) { create_example 's:dummy', content: '*chunky* bacon' }
|
151
|
-
let(:opts) { {dummy: 'value'} }
|
152
|
-
let(:renderer) { double 'AsciidocRenderer' }
|
153
|
-
let(:converter_opts) { {header_footer: false} }
|
154
|
-
|
155
|
-
subject(:result) { suite.convert_example input, opts, renderer }
|
156
|
-
|
157
|
-
let :rendered do
|
158
|
-
<<-EOF
|
159
|
-
<section>
|
160
|
-
<h1>Title</h1>
|
161
|
-
<div>
|
162
|
-
<p><b>Chunky</b> bacon</p>
|
163
|
-
</div>
|
164
|
-
<code>meh</code>
|
165
|
-
</section>
|
166
|
-
<div>
|
167
|
-
<p>why?</p>
|
168
|
-
</div>
|
169
|
-
EOF
|
170
|
-
end
|
171
|
-
|
172
|
-
before do
|
173
|
-
expect(renderer).to receive(:convert)
|
174
|
-
.with(input.content, converter_opts).and_return(rendered)
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'returns instance of HTML::Example' do
|
178
|
-
is_expected.to be_instance_of DocTest::HTML::Example
|
179
|
-
end
|
180
|
-
|
181
|
-
it 'returns Example with the same name as input_example' do
|
182
|
-
expect(result.name).to eq input.name
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'returns Example with the given opts' do
|
186
|
-
expect(result.opts).to eq opts
|
187
|
-
end
|
188
|
-
|
189
|
-
context 'with :exclude option' do
|
190
|
-
let(:opts) { {exclude: ['.//p', './/code']} }
|
191
|
-
|
192
|
-
it 'returns content without HTML (sub)elements specified by XPath' do
|
193
|
-
expect(result.content.gsub(/\s*/, '')).to eq \
|
194
|
-
'<section><h1>Title</h1><div></div></section><div></div>'
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
context 'with :include option' do
|
199
|
-
let(:opts) { {include: ['.//p']} }
|
200
|
-
|
201
|
-
it 'returns content with only HTML (sub)elements specified by XPath' do
|
202
|
-
expect(result.content.gsub(/\s*/, '')).to eq '<p><b>Chunky</b>bacon</p><p>why?</p>'
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
context 'with :header_footer option' do
|
207
|
-
let(:opts) { {header_footer: true} }
|
208
|
-
|
209
|
-
it 'renders content with :header_footer => true' do
|
210
|
-
suite.convert_example input, {}, renderer
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
context 'with example named /^document.*/' do
|
215
|
-
let(:input) { create_example 'document:dummy', content: '*chunky* bacon' }
|
216
|
-
let(:converter_opts) { {header_footer: true} }
|
217
|
-
|
218
|
-
it 'renders content with :header_footer => true' do
|
219
|
-
suite.convert_example input, {}, renderer
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
context 'with example named /inline_.*/' do
|
224
|
-
let(:input) { create_example 'inline_quoted:dummy', content: '*chunky* bacon' }
|
225
|
-
let(:rendered) { '<p><b>chunky</b> bacon</p>' }
|
226
|
-
|
227
|
-
it 'returns content without top-level <p> tags' do
|
228
|
-
expect(result.content).to eq '<b>chunky</b> bacon'
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'does not add implicit include into returned example' do
|
232
|
-
expect(result.opts).to_not include :include
|
233
|
-
end
|
234
|
-
|
235
|
-
context 'with :include option' do
|
236
|
-
let(:opts) { {include: ['.//b']} }
|
237
|
-
|
238
|
-
it 'preferes the include option' do
|
239
|
-
expect(result.content).to eq '<b>chunky</b>'
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
141
|
end
|