manbook 0.0.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.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +25 -0
- data/LICENSE.txt +20 -0
- data/README.md +105 -0
- data/Rakefile +46 -0
- data/TODO +2 -0
- data/VERSION +1 -0
- data/bin/manbook +89 -0
- data/bin/mktoc +157 -0
- data/lib/manbook.rb +30 -0
- data/lib/manbook/errors.rb +22 -0
- data/lib/manbook/formatter.rb +27 -0
- data/lib/manbook/html_formatter.rb +17 -0
- data/lib/manbook/log_formatter.rb +9 -0
- data/lib/manbook/parser.rb +32 -0
- data/templates/_page.html.erb +1 -0
- data/templates/about.html.erb +6 -0
- data/templates/application.html.erb +23 -0
- data/templates/index.html.erb +4 -0
- data/templates/library_books.jpg +0 -0
- data/templates/manbook.ncx.erb +28 -0
- data/templates/manbook.opf.erb +35 -0
- data/test/fixtures/bash.html +11352 -0
- data/test/fixtures/cat.html +195 -0
- data/test/fixtures/git.html +1882 -0
- data/test/fixtures/gunzip.html +595 -0
- data/test/fixtures/less.html +3554 -0
- data/test/fixtures/ls.html +818 -0
- data/test/fixtures/man.html +649 -0
- data/test/helper.rb +42 -0
- data/test/unit/test_manbook.rb +39 -0
- data/test/unit/test_mktoc.rb +215 -0
- metadata +189 -0
data/test/helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
require 'manbook'
|
19
|
+
|
20
|
+
class Test::Unit::TestCase
|
21
|
+
FIXTURES_DIR = File.join(File.dirname(__FILE__), 'fixtures')
|
22
|
+
end
|
23
|
+
|
24
|
+
module ManBookTest
|
25
|
+
class TestCase < Test::Unit::TestCase
|
26
|
+
attr_reader :output_dir
|
27
|
+
|
28
|
+
def setup
|
29
|
+
@output_dir = Dir.mktmpdir(File.join('test', 'tmp', 'unit-test'), '.')
|
30
|
+
end
|
31
|
+
|
32
|
+
def teardown
|
33
|
+
FileUtils.remove_entry_secure(@output_dir)
|
34
|
+
end
|
35
|
+
|
36
|
+
# solves the problem of non-existing test cases
|
37
|
+
# for alternatives, see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/76191
|
38
|
+
def test_output_dir
|
39
|
+
assert(File.exist?(@output_dir))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
#
|
4
|
+
# End-to-end test the manbook
|
5
|
+
#
|
6
|
+
module ManBookTest
|
7
|
+
class TestManbook < ManBookTest::TestCase
|
8
|
+
APP_SCRIPT = 'ruby bin/manbook'
|
9
|
+
|
10
|
+
def test_no_args
|
11
|
+
status = Open4::popen4(app_script){|pid, stdin, stdout, stderr|
|
12
|
+
assert_match(/ERROR: Which man page do you want to convert?/, stderr.read)
|
13
|
+
assert(stdout.read.empty?)
|
14
|
+
}
|
15
|
+
assert_not_equal(0, status.exitstatus)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_existing_page_single
|
19
|
+
status = Open4::popen4("#{app_script} ls"){|pid, stdin, stdout, stderr|
|
20
|
+
assert(stderr.read.empty?)
|
21
|
+
assert(stdout.read.empty?)
|
22
|
+
}
|
23
|
+
assert_equal(0, status.exitstatus)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_existing_page_multiple
|
27
|
+
status = Open4::popen4("#{app_script} ls bash"){|pid, stdin, stdout, stderr|
|
28
|
+
assert(stderr.read.empty?)
|
29
|
+
assert(stdout.read.empty?)
|
30
|
+
}
|
31
|
+
assert_equal(0, status.exitstatus)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def app_script
|
36
|
+
"#{APP_SCRIPT} --output #{output_dir}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
#
|
7
|
+
# End-to-end test for mktoc
|
8
|
+
#
|
9
|
+
module ManBookTest
|
10
|
+
class TestMkToc < ManBookTest::TestCase
|
11
|
+
#
|
12
|
+
# command under test
|
13
|
+
#
|
14
|
+
APP_SCRIPT = 'ruby bin/mktoc'
|
15
|
+
|
16
|
+
#
|
17
|
+
# generator identification
|
18
|
+
#
|
19
|
+
GENERATOR = "mktoc v#{ManBook::VERSION}"
|
20
|
+
|
21
|
+
#
|
22
|
+
# generated work products (in addition to HTML input files that were created externally)
|
23
|
+
#
|
24
|
+
WORKPRODUCTS = {:html => 'index.html',
|
25
|
+
:ncx => 'index.ncx',
|
26
|
+
:opf => 'index.opf',
|
27
|
+
:about => 'about.html'}
|
28
|
+
|
29
|
+
#
|
30
|
+
# which method tests what work product
|
31
|
+
#
|
32
|
+
WORK_PRODUCT_TESTS = {:html => 'test_workproduct_html',
|
33
|
+
:ncx => 'test_workproduct_ncx',
|
34
|
+
:opf => 'test_workproduct_opf',
|
35
|
+
:about => 'test_workproduct_about',
|
36
|
+
:cover => 'test_workproduct_cover'}
|
37
|
+
|
38
|
+
def setup
|
39
|
+
super
|
40
|
+
FileUtils.cp_r(File.join(FIXTURES_DIR, '.'), output_dir)
|
41
|
+
@fixtures = Dir.glob(File.join(FIXTURES_DIR, '*.html')).map{|f| File.basename(f)}
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_no_args
|
45
|
+
assert_exec("#{app_script}", false, nil, /ERROR: Directory argument missing/)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_defaults
|
49
|
+
assert_exec("#{app_script} #{output_dir}")
|
50
|
+
test_all_workproducts(ManBook::TITLE_DEFAULT, File.basename(ManBook::COVER_IMAGE_DEFAULT))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_overridden_title
|
54
|
+
title = "Foo42Bar"
|
55
|
+
assert_exec("#{app_script} #{output_dir} --title \"#{title}\"")
|
56
|
+
test_all_workproducts(title, File.basename(ManBook::COVER_IMAGE_DEFAULT))
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_no_cover_image
|
60
|
+
assert_exec("#{app_script} #{output_dir} --no-cover-image")
|
61
|
+
test_all_workproducts(ManBook::TITLE_DEFAULT, nil)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_alt_cover_image
|
65
|
+
cover_image = ManBook::COVER_IMAGE_DEFAULT
|
66
|
+
assert(File.exist?(cover_image))
|
67
|
+
assert_exec("#{app_script} #{output_dir} --cover-image #{cover_image}")
|
68
|
+
test_all_workproducts(ManBook::TITLE_DEFAULT, File.basename(cover_image))
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_alt_cover_image_not_found
|
72
|
+
cover_image = "DOES_NOT_EXIST"
|
73
|
+
assert(!File.exist?(cover_image))
|
74
|
+
assert_exec("#{app_script} #{output_dir} --cover-image #{cover_image}", false, nil, /ERROR: Could not find cover image/)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def test_all_workproducts(title, cover_image = nil)
|
79
|
+
if cover_image.nil?
|
80
|
+
workproducts = WORKPRODUCTS
|
81
|
+
else
|
82
|
+
workproducts = WORKPRODUCTS.merge({:cover => 'library_books.jpg'})
|
83
|
+
end
|
84
|
+
|
85
|
+
assert_equal(@fixtures.size + workproducts.size, Dir.glob(File.join(output_dir, '*')).size)
|
86
|
+
|
87
|
+
workproducts.each{|k,v|
|
88
|
+
vf = File.join(output_dir, v)
|
89
|
+
assert(File.exist?(vf), "Expect #{vf} to exist")
|
90
|
+
|
91
|
+
# dispatch to test that is specific to the work product
|
92
|
+
wp_test = WORK_PRODUCT_TESTS[k]
|
93
|
+
raise "No test defined for work product #{k}" if wp_test.nil?
|
94
|
+
send(wp_test, title, cover_image)
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def assert_exec(cmd, assert_status_success = true, re_stdout = nil, re_stderr = nil)
|
99
|
+
status = Open4::popen4(cmd){|pid, stdin, stdout, stderr|
|
100
|
+
if re_stdout.nil?
|
101
|
+
assert_empty(stdout.read)
|
102
|
+
else
|
103
|
+
assert_match(re_stdout, stdout.read)
|
104
|
+
end
|
105
|
+
|
106
|
+
if re_stderr.nil?
|
107
|
+
assert_empty(stderr.read)
|
108
|
+
else
|
109
|
+
assert_match(re_stderr, stderr.read)
|
110
|
+
end
|
111
|
+
}
|
112
|
+
|
113
|
+
if assert_status_success
|
114
|
+
assert_equal(0, status.exitstatus)
|
115
|
+
else
|
116
|
+
assert_not_equal(0, status.exitstatus)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def assert_empty(str, msg = nil)
|
121
|
+
assert(str.nil? || str.empty?, "Should have been empty, but was: #{str}")
|
122
|
+
end
|
123
|
+
|
124
|
+
def app_script
|
125
|
+
"#{APP_SCRIPT}"
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_workproduct_html(title, cover_image = nil)
|
129
|
+
doc = Nokogiri::HTML(File.read(File.join(output_dir, 'index.html')))
|
130
|
+
assert_workproduct(['about.html'].concat(@fixtures), doc, '/html/body/ul/li', 'a/@href')
|
131
|
+
|
132
|
+
# index.html does not use the book title, but "Table Of Contents"
|
133
|
+
assert_equal("Table Of Contents", doc.xpath('/html/head/title/text()').to_s)
|
134
|
+
assert_equal("Table Of Contents", doc.xpath('/html/body/h1[1]/text()').to_s)
|
135
|
+
|
136
|
+
assert_equal(GENERATOR, doc.xpath("/html/head/meta[@name='generator']/@content").to_s)
|
137
|
+
assert_equal("About this book", doc.xpath('/html/body/ul/li[1]/a/text()').to_s)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_workproduct_ncx(title, cover_image = nil)
|
141
|
+
doc = Nokogiri::XML(File.read(File.join(output_dir, 'index.ncx')))
|
142
|
+
|
143
|
+
fixtures = ['about.html'].concat(@fixtures)
|
144
|
+
fixtures << cover_image unless cover_image.nil?
|
145
|
+
assert_workproduct(fixtures, doc, '/xmlns:ncx/xmlns:navMap/xmlns:navPoint', 'xmlns:content/@src')
|
146
|
+
|
147
|
+
assert_equal(title, doc.xpath("/xmlns:ncx/xmlns:head/xmlns:meta[@name='dtb:title']/@content").to_s)
|
148
|
+
assert_equal(title, doc.xpath("/xmlns:ncx/xmlns:docTitle/xmlns:text/text()").to_s)
|
149
|
+
assert_equal(GENERATOR, doc.xpath("/xmlns:ncx/xmlns:head/xmlns:meta[@name='dtb:generator']/@content").to_s)
|
150
|
+
|
151
|
+
# TODO id and order
|
152
|
+
# navPoint
|
153
|
+
# @id="bash.html"
|
154
|
+
# @playOrder="0"
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_workproduct_opf(title, cover_image = nil)
|
158
|
+
doc = Nokogiri::XML(File.read(File.join(output_dir, 'index.opf')))
|
159
|
+
|
160
|
+
# the opf must include links to index.html and index.ncx
|
161
|
+
item_fixtures = ['index.html', 'index.ncx', 'about.html'].concat(@fixtures)
|
162
|
+
item_fixtures << cover_image unless cover_image.nil?
|
163
|
+
assert_workproduct(item_fixtures, doc, '//xmlns:manifest/xmlns:item', '@href')
|
164
|
+
|
165
|
+
# cross-references within the document
|
166
|
+
xref_fixtures = ['index', 'about.html'].concat(@fixtures)
|
167
|
+
xref_fixtures << 'cover-image' unless cover_image.nil?
|
168
|
+
assert_workproduct(xref_fixtures, doc, '//xmlns:spine/xmlns:itemref', '@idref')
|
169
|
+
|
170
|
+
assert_equal(title, doc.xpath('/xmlns:package/xmlns:metadata/dc:title/text()',
|
171
|
+
{'dc' => "http://purl.org/dc/elements/1.1/",
|
172
|
+
'xmlns' => 'http://www.idpf.org/2007/opf'}).to_s)
|
173
|
+
|
174
|
+
assert_equal(GENERATOR, doc.xpath('/xmlns:package/xmlns:metadata/dc:generator/text()',
|
175
|
+
{'dc' => "http://purl.org/dc/elements/1.1/",
|
176
|
+
'xmlns' => 'http://www.idpf.org/2007/opf'}).first.to_s)
|
177
|
+
|
178
|
+
# reference to cover image in meta data. The other two references were already tested above
|
179
|
+
unless cover_image.nil?
|
180
|
+
assert_equal('cover-image', doc.xpath("/xmlns:package/xmlns:metadata/xmlns:meta[@name='cover']/@content").to_s)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_workproduct_about(title, cover_image = nil)
|
185
|
+
# no further tests
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_workproduct_cover(title, cover_image = nil)
|
189
|
+
# no further tests
|
190
|
+
end
|
191
|
+
|
192
|
+
def assert_workproduct(fixtures, doc, xpath_list, xpath_href)
|
193
|
+
assert_not_nil(doc)
|
194
|
+
|
195
|
+
list = doc.xpath(xpath_list)
|
196
|
+
assert_not_nil(list)
|
197
|
+
|
198
|
+
# every fixture file should be listed
|
199
|
+
assert_equal(fixtures.size, list.size)
|
200
|
+
|
201
|
+
hrefs = list.map{|li| li.xpath(xpath_href).to_s}
|
202
|
+
assert_not_nil(hrefs)
|
203
|
+
|
204
|
+
# each work product must be linked
|
205
|
+
fixtures.each{|fixture|
|
206
|
+
assert(hrefs.include?(fixture), "Could not find '#{fixture}' in #{hrefs.inspect}")
|
207
|
+
}
|
208
|
+
|
209
|
+
# each link must point to a work product
|
210
|
+
hrefs.each{|li|
|
211
|
+
assert(fixtures.include?(li), "Could not find '#{li}' in #{fixtures.inspect}")
|
212
|
+
}
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: manbook
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Nicholas E. Rabenau
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-12-02 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
requirement: *id001
|
33
|
+
prerelease: false
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: open4
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
type: :runtime
|
46
|
+
requirement: *id002
|
47
|
+
prerelease: false
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: nokogiri
|
50
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
type: :runtime
|
60
|
+
requirement: *id003
|
61
|
+
prerelease: false
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - "="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 49
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
- 8
|
73
|
+
- 7
|
74
|
+
version: 0.8.7
|
75
|
+
type: :development
|
76
|
+
requirement: *id004
|
77
|
+
prerelease: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 23
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 0
|
89
|
+
- 0
|
90
|
+
version: 1.0.0
|
91
|
+
type: :development
|
92
|
+
requirement: *id005
|
93
|
+
prerelease: false
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: jeweler
|
96
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 7
|
102
|
+
segments:
|
103
|
+
- 1
|
104
|
+
- 6
|
105
|
+
- 4
|
106
|
+
version: 1.6.4
|
107
|
+
type: :development
|
108
|
+
requirement: *id006
|
109
|
+
prerelease: false
|
110
|
+
description: The manbook command can be used to produce an eBook from one or more man pages.
|
111
|
+
email: nerab@gmx.net
|
112
|
+
executables:
|
113
|
+
- mktoc
|
114
|
+
- manbook
|
115
|
+
extensions: []
|
116
|
+
|
117
|
+
extra_rdoc_files:
|
118
|
+
- LICENSE.txt
|
119
|
+
- README.md
|
120
|
+
- TODO
|
121
|
+
files:
|
122
|
+
- .document
|
123
|
+
- Gemfile
|
124
|
+
- Gemfile.lock
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- TODO
|
129
|
+
- VERSION
|
130
|
+
- bin/manbook
|
131
|
+
- bin/mktoc
|
132
|
+
- lib/manbook.rb
|
133
|
+
- lib/manbook/errors.rb
|
134
|
+
- lib/manbook/formatter.rb
|
135
|
+
- lib/manbook/html_formatter.rb
|
136
|
+
- lib/manbook/log_formatter.rb
|
137
|
+
- lib/manbook/parser.rb
|
138
|
+
- templates/_page.html.erb
|
139
|
+
- templates/about.html.erb
|
140
|
+
- templates/application.html.erb
|
141
|
+
- templates/index.html.erb
|
142
|
+
- templates/library_books.jpg
|
143
|
+
- templates/manbook.ncx.erb
|
144
|
+
- templates/manbook.opf.erb
|
145
|
+
- test/fixtures/bash.html
|
146
|
+
- test/fixtures/cat.html
|
147
|
+
- test/fixtures/git.html
|
148
|
+
- test/fixtures/gunzip.html
|
149
|
+
- test/fixtures/less.html
|
150
|
+
- test/fixtures/ls.html
|
151
|
+
- test/fixtures/man.html
|
152
|
+
- test/helper.rb
|
153
|
+
- test/unit/test_manbook.rb
|
154
|
+
- test/unit/test_mktoc.rb
|
155
|
+
homepage: http://github.com/nerab/manbook
|
156
|
+
licenses:
|
157
|
+
- MIT
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
hash: 3
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
version: "0"
|
172
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
hash: 3
|
178
|
+
segments:
|
179
|
+
- 0
|
180
|
+
version: "0"
|
181
|
+
requirements: []
|
182
|
+
|
183
|
+
rubyforge_project:
|
184
|
+
rubygems_version: 1.8.9
|
185
|
+
signing_key:
|
186
|
+
specification_version: 3
|
187
|
+
summary: Produces an eBook from man pages
|
188
|
+
test_files: []
|
189
|
+
|