epub_tools 0.4.0 → 0.5.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -0
  3. data/.gitignore +1 -1
  4. data/.rubocop.yml +10 -17
  5. data/.tool-versions +1 -0
  6. data/CLAUDE.md +124 -0
  7. data/Gemfile +4 -4
  8. data/Gemfile.lock +44 -37
  9. data/README.md +10 -6
  10. data/Rakefile +2 -0
  11. data/bin/epub-tools +2 -0
  12. data/epub_tools.gemspec +3 -1
  13. data/lib/epub_tools/add_chapters.rb +48 -30
  14. data/lib/epub_tools/chapter_validator.rb +40 -0
  15. data/lib/epub_tools/cli/command_options_configurator.rb +115 -0
  16. data/lib/epub_tools/cli/command_registry.rb +2 -0
  17. data/lib/epub_tools/cli/option_builder.rb +5 -3
  18. data/lib/epub_tools/cli/runner.rb +59 -110
  19. data/lib/epub_tools/cli.rb +16 -29
  20. data/lib/epub_tools/compile_book.rb +48 -65
  21. data/lib/epub_tools/compile_workspace.rb +40 -0
  22. data/lib/epub_tools/epub_configuration.rb +33 -0
  23. data/lib/epub_tools/epub_file_writer.rb +57 -0
  24. data/lib/epub_tools/epub_initializer.rb +83 -162
  25. data/lib/epub_tools/epub_metadata_builder.rb +92 -0
  26. data/lib/epub_tools/loggable.rb +2 -0
  27. data/lib/epub_tools/pack_ebook.rb +28 -14
  28. data/lib/epub_tools/split_chapters.rb +42 -17
  29. data/lib/epub_tools/style_finder.rb +17 -6
  30. data/lib/epub_tools/unpack_ebook.rb +20 -10
  31. data/lib/epub_tools/version.rb +3 -1
  32. data/lib/epub_tools/xhtml_cleaner.rb +1 -0
  33. data/lib/epub_tools/xhtml_extractor.rb +20 -10
  34. data/lib/epub_tools/xhtml_generator.rb +71 -0
  35. data/lib/epub_tools.rb +2 -0
  36. data/test/add_chapters_test.rb +50 -26
  37. data/test/chapter_validator_test.rb +47 -0
  38. data/test/cli/command_registry_test.rb +2 -0
  39. data/test/cli/option_builder_test.rb +24 -14
  40. data/test/cli/runner_test.rb +15 -15
  41. data/test/cli_commands_test.rb +3 -1
  42. data/test/cli_test.rb +2 -0
  43. data/test/cli_version_test.rb +2 -0
  44. data/test/compile_book_test.rb +17 -102
  45. data/test/compile_workspace_test.rb +55 -0
  46. data/test/epub_initializer_test.rb +55 -27
  47. data/test/pack_ebook_test.rb +33 -9
  48. data/test/split_chapters_test.rb +27 -7
  49. data/test/style_finder_test.rb +2 -0
  50. data/test/test_helper.rb +2 -0
  51. data/test/unpack_ebook_test.rb +45 -20
  52. data/test/xhtml_cleaner_test.rb +2 -0
  53. data/test/xhtml_extractor_test.rb +3 -1
  54. metadata +15 -5
  55. data/.ruby-version +0 -1
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'nokogiri'
3
5
  require 'yaml'
4
6
  require_relative 'loggable'
@@ -9,6 +11,7 @@ module EpubTools
9
11
  # {SplitChapters}[rdoc-ref:EpubTools::SplitChapters].
10
12
  class StyleFinder
11
13
  include Loggable
14
+
12
15
  # Initializes the class
13
16
  # @param options [Hash] Configuration options
14
17
  # @option options [String] :file_path XHTML file to be analyzed (required)
@@ -24,18 +27,26 @@ module EpubTools
24
27
  # Runs the finder
25
28
  # @return [Hash] Data containing the extracted style classes (italics and bolds)
26
29
  def run
30
+ style_blocks = extract_style_blocks
31
+ italics, bolds = extract_style_classes(style_blocks)
32
+ generate_output(italics, bolds)
33
+ end
34
+
35
+ def extract_style_blocks
27
36
  doc = Nokogiri::HTML(File.read(@file_path))
28
- style_blocks = doc.xpath('//style').map(&:text).join("\n")
37
+ doc.xpath('//style').map(&:text).join("\n")
38
+ end
29
39
 
40
+ def extract_style_classes(style_blocks)
30
41
  italics = extract_classes(style_blocks, /font-style\s*:\s*italic/)
31
- bolds = extract_classes(style_blocks, /font-weight\s*:\s*700/)
42
+ bolds = extract_classes(style_blocks, /font-weight\s*:\s*700/)
43
+ [italics, bolds]
44
+ end
32
45
 
46
+ def generate_output(italics, bolds)
33
47
  print_summary(italics, bolds) if @verbose
34
48
 
35
- data = {
36
- 'italics' => italics,
37
- 'bolds' => bolds
38
- }
49
+ data = { 'italics' => italics, 'bolds' => bolds }
39
50
  File.write(@output_path, data.to_yaml)
40
51
  data
41
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'zip'
2
4
  require 'fileutils'
3
5
  require_relative 'loggable'
@@ -6,6 +8,7 @@ module EpubTools
6
8
  # Unpacks an EPUB (.epub file) into a directory
7
9
  class UnpackEbook
8
10
  include Loggable
11
+
9
12
  # Initializes the class
10
13
  # @param options [Hash] Configuration options
11
14
  # @option options [String] :epub_file Path to the .epub file to unpack (required)
@@ -23,22 +26,29 @@ module EpubTools
23
26
  def run
24
27
  validate!
25
28
  FileUtils.mkdir_p(@output_dir)
29
+ extract_entries
30
+ log "Unpacked #{File.basename(@epub_file)} to #{@output_dir}"
31
+ @output_dir
32
+ end
33
+
34
+ private
35
+
36
+ def extract_entries
26
37
  Zip::File.open(@epub_file) do |zip|
27
38
  zip.each do |entry|
28
- dest_path = File.join(@output_dir, entry.name)
29
- if entry.directory?
30
- FileUtils.mkdir_p(dest_path)
31
- else
32
- FileUtils.mkdir_p(File.dirname(dest_path))
33
- entry.extract(dest_path) { true }
34
- end
39
+ extract_entry(entry)
35
40
  end
36
41
  end
37
- log "Unpacked #{File.basename(@epub_file)} to #{@output_dir}"
38
- @output_dir
39
42
  end
40
43
 
41
- private
44
+ def extract_entry(entry)
45
+ if entry.directory?
46
+ FileUtils.mkdir_p(File.join(@output_dir, entry.name))
47
+ else
48
+ FileUtils.mkdir_p(File.join(@output_dir, File.dirname(entry.name)))
49
+ entry.extract(destination_directory: @output_dir) { true }
50
+ end
51
+ end
42
52
 
43
53
  def default_dir
44
54
  [File.dirname(@epub_file), File.basename(@epub_file, '.epub')].join('/')
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EpubTools
2
4
  # Ruby Gem version number
3
- VERSION = '0.4.0'.freeze
5
+ VERSION = '0.5.0'
4
6
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'nokogiri'
4
5
  require 'yaml'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'zip'
2
4
  require 'fileutils'
3
5
  require_relative 'loggable'
@@ -6,6 +8,7 @@ module EpubTools
6
8
  # Extracts text .xhtml files from EPUB archives, excluding nav.xhtml
7
9
  class XHTMLExtractor
8
10
  include Loggable
11
+
9
12
  # Initializes the class
10
13
  # @param options [Hash] Configuration options
11
14
  # @option options [String] :source_dir Directory containing source .epub files (required)
@@ -39,21 +42,28 @@ module EpubTools
39
42
  epub_name = File.basename(epub_path, '.epub')
40
43
  log "Extracting from #{epub_name}.epub"
41
44
  extracted_files = []
45
+
42
46
  Zip::File.open(epub_path) do |zip_file|
43
- zip_file.each do |entry|
44
- next unless entry.name.downcase.end_with?('.xhtml')
45
- next if File.basename(entry.name).downcase == 'nav.xhtml'
46
-
47
- output_path = File.join(@target_dir, "#{epub_name}_#{File.basename(entry.name)}")
48
- FileUtils.mkdir_p(File.dirname(output_path))
49
- entry.extract(output_path) { true }
50
- log output_path
51
- extracted_files << output_path
52
- end
47
+ zip_file.each { |entry| extract_entry_if_xhtml(entry, epub_name, extracted_files) }
53
48
  end
54
49
  extracted_files
55
50
  rescue Zip::Error => e
56
51
  warn "⚠️ Failed to process #{epub_path}: #{e.message}"
57
52
  end
53
+
54
+ def extract_entry_if_xhtml(entry, epub_name, extracted_files)
55
+ return unless xhtml_entry?(entry)
56
+
57
+ renamed = "#{epub_name}_#{File.basename(entry.name)}"
58
+ output_path = File.join(@target_dir, renamed)
59
+ FileUtils.mkdir_p(File.dirname(output_path))
60
+ entry.extract(renamed, destination_directory: @target_dir) { true }
61
+ log output_path
62
+ extracted_files << output_path
63
+ end
64
+
65
+ def xhtml_entry?(entry)
66
+ entry.name.downcase.end_with?('.xhtml') && File.basename(entry.name).downcase != 'nav.xhtml'
67
+ end
58
68
  end
59
69
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EpubTools
4
+ # Generates XHTML content for EPUB files
5
+ class XhtmlGenerator
6
+ attr_accessor :cover_image_fname
7
+
8
+ def initialize(title:, author:)
9
+ @title = title
10
+ @author = author
11
+ @cover_image_fname = nil
12
+ end
13
+
14
+ # Generates title page XHTML content
15
+ def build_title_page
16
+ <<~XHTML
17
+ <?xml version="1.0" encoding="UTF-8"?>
18
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
19
+ <head>
20
+ <meta charset="UTF-8" />
21
+ <title>#{@title}</title>
22
+ <link rel="stylesheet" type="text/css" href="style.css"/>
23
+ </head>
24
+ <body>
25
+ <h1 class="title">#{@title}</h1>
26
+ <p class="author">by #{@author}</p>
27
+ </body>
28
+ </html>
29
+ XHTML
30
+ end
31
+
32
+ # Generates cover page XHTML content
33
+ def build_cover_page
34
+ <<~XHTML
35
+ <?xml version="1.0" encoding="UTF-8"?>
36
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
37
+ <head>
38
+ <meta charset="UTF-8" />
39
+ <title>Cover</title>
40
+ <link rel="stylesheet" type="text/css" href="style.css"/>
41
+ </head>
42
+ <body>
43
+ <div class="cover-image">
44
+ <img src="#{@cover_image_fname}" alt="Cover"/>
45
+ </div>
46
+ </body>
47
+ </html>
48
+ XHTML
49
+ end
50
+
51
+ # Generates navigation XHTML content
52
+ def build_nav_page
53
+ <<~XHTML
54
+ <?xml version="1.0" encoding="utf-8"?>
55
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="en">
56
+ <head>
57
+ <title>Table of Contents</title>
58
+ </head>
59
+ <body>
60
+ <nav epub:type="toc" id="toc">
61
+ <h1>Table of Contents</h1>
62
+ <ol>
63
+ <li><a href="title.xhtml">Title Page</a></li>
64
+ </ol>
65
+ </nav>
66
+ </body>
67
+ </html>
68
+ XHTML
69
+ end
70
+ end
71
+ end
data/lib/epub_tools.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'epub_tools/version'
2
4
  require_relative 'epub_tools/loggable'
3
5
  require_relative 'epub_tools/add_chapters'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
  require_relative '../lib/epub_tools/add_chapters'
3
5
  require 'nokogiri'
@@ -53,47 +55,69 @@ class AddChaptersTest < Minitest::Test
53
55
  end
54
56
 
55
57
  def test_run_moves_files_and_updates_opf_and_nav
56
- # Run the add chapters task
57
- result = EpubTools::AddChapters.new(chapters_dir: @chapters_dir, epub_dir: @epub_dir).run
58
+ result = EpubTools::AddChapters.new(chapters_dir: @chapters_dir, oebps_dir: @epub_dir).run
59
+
60
+ verify_return_value(result)
61
+ verify_files_moved
62
+ verify_opf_structure
63
+ verify_nav_structure
64
+ end
58
65
 
59
- # Check return value is an array of moved file basenames
66
+ private
67
+
68
+ def verify_return_value(result)
60
69
  assert_instance_of Array, result
61
70
  assert_equal 2, result.size
62
71
  assert_includes result, 'chapter_0.xhtml'
63
72
  assert_includes result, 'chapter_1.xhtml'
73
+ end
64
74
 
65
- # Original chapter files should be moved
75
+ def verify_files_moved
66
76
  assert_empty Dir.glob(File.join(@chapters_dir, '*.xhtml'))
67
77
  assert_path_exists File.join(@epub_dir, 'chapter_0.xhtml')
68
78
  assert_path_exists File.join(@epub_dir, 'chapter_1.xhtml')
79
+ end
69
80
 
70
- # package.opf should include manifest items and spine refs
71
- doc = Nokogiri::XML(File.read(@opf_file)) { |cfg| cfg.default_xml.noblanks }
72
- items = doc.xpath('//xmlns:manifest/xmlns:item')
73
- idrefs = doc.xpath('//xmlns:spine/xmlns:itemref')
74
- hrefs = items.map { |i| i['href'] }
75
- ids = items.map { |i| i['id'] }
76
- refs = idrefs.map { |ir| ir['idref'] }
77
-
78
- assert_includes hrefs, 'chapter_0.xhtml'
79
- assert_includes hrefs, 'chapter_1.xhtml'
80
- assert_includes ids, 'chap0'
81
- assert_includes ids, 'chap1'
82
- assert_includes refs, 'chap0'
83
- assert_includes refs, 'chap1'
84
-
85
- # nav.xhtml should have list entries for each chapter
86
- nav_doc = Nokogiri::XML(File.read(@nav_file))
87
- # strip namespaces for easy querying
88
- nav_doc.remove_namespaces!
89
- links = nav_doc.xpath('//nav/ol/li/a')
81
+ def verify_opf_structure
82
+ doc = parse_opf_document
83
+ opf_data = extract_opf_data(doc)
84
+
85
+ assert_includes opf_data[:hrefs], 'chapter_0.xhtml'
86
+ assert_includes opf_data[:hrefs], 'chapter_1.xhtml'
87
+ assert_includes opf_data[:ids], 'chap0'
88
+ assert_includes opf_data[:ids], 'chap1'
89
+ assert_includes opf_data[:refs], 'chap0'
90
+ assert_includes opf_data[:refs], 'chap1'
91
+ end
92
+
93
+ def verify_nav_structure
94
+ links = extract_nav_links
90
95
 
91
96
  assert_equal 2, links.size
92
- # First is Prologue (chapter_0)
93
97
  assert_equal 'chapter_0.xhtml', links[0]['href']
94
98
  assert_equal 'Prologue', links[0].text
95
- # Second is Chapter 1
96
99
  assert_equal 'chapter_1.xhtml', links[1]['href']
97
100
  assert_equal 'Chapter 1', links[1].text
98
101
  end
102
+
103
+ def parse_opf_document
104
+ Nokogiri::XML(File.read(@opf_file)) { |cfg| cfg.default_xml.noblanks }
105
+ end
106
+
107
+ def extract_opf_data(doc)
108
+ items = doc.xpath('//xmlns:manifest/xmlns:item')
109
+ idrefs = doc.xpath('//xmlns:spine/xmlns:itemref')
110
+
111
+ {
112
+ hrefs: items.map { |i| i['href'] },
113
+ ids: items.map { |i| i['id'] },
114
+ refs: idrefs.map { |ir| ir['idref'] }
115
+ }
116
+ end
117
+
118
+ def extract_nav_links
119
+ nav_doc = Nokogiri::XML(File.read(@nav_file))
120
+ nav_doc.remove_namespaces!
121
+ nav_doc.xpath('//nav/ol/li/a')
122
+ end
99
123
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'test_helper'
4
+ require_relative '../lib/epub_tools/chapter_validator'
5
+
6
+ class ChapterValidatorTest < Minitest::Test
7
+ def setup
8
+ @tmp = Dir.mktmpdir
9
+ @validator = EpubTools::ChapterValidator.new(chapters_dir: @tmp)
10
+ end
11
+
12
+ def teardown
13
+ FileUtils.rm_rf(@tmp)
14
+ end
15
+
16
+ def test_validates_complete_sequence
17
+ create_chapter_files([1, 2, 3, 4, 5])
18
+
19
+ assert_silent { @validator.validate }
20
+ end
21
+
22
+ def test_raises_on_missing_chapters
23
+ create_chapter_files([1, 2, 4, 5]) # Missing 3
24
+
25
+ error = assert_raises(RuntimeError) { @validator.validate }
26
+ assert_match(/Missing chapter numbers: 3/, error.message)
27
+ end
28
+
29
+ def test_raises_on_no_chapters
30
+ error = assert_raises(RuntimeError) { @validator.validate }
31
+ assert_match(/No chapter files found/, error.message)
32
+ end
33
+
34
+ def test_handles_non_sequential_start
35
+ create_chapter_files([5, 6, 7, 8])
36
+
37
+ assert_silent { @validator.validate }
38
+ end
39
+
40
+ private
41
+
42
+ def create_chapter_files(numbers)
43
+ numbers.each do |num|
44
+ File.write(File.join(@tmp, "chapter_#{num}.xhtml"), '<html></html>')
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../test_helper'
2
4
  require_relative '../../lib/epub_tools'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../test_helper'
2
4
  require_relative '../../lib/epub_tools'
3
5
  require 'stringio'
@@ -41,17 +43,13 @@ class OptionBuilderTest < Minitest::Test
41
43
  def test_with_input_file
42
44
  @builder.with_input_file('Test input')
43
45
 
44
- assert_includes @builder.parser.to_s, '-i, --input-file FILE'
45
- assert_includes @builder.parser.to_s, 'Test input (required)'
46
+ verify_parser_option_format('-i, --input-file FILE', 'Test input (required)')
46
47
 
47
- # Test with required=false
48
48
  builder2 = EpubTools::CLI::OptionBuilder.new
49
- builder2.with_input_file('Test input', false)
49
+ builder2.with_input_file('Test input', required: false)
50
50
 
51
- assert_includes builder2.parser.to_s, 'Test input'
52
- refute_includes builder2.parser.to_s, 'Test input (required)'
51
+ verify_optional_parser_format(builder2, 'Test input')
53
52
 
54
- # Test with actual parsing
55
53
  @builder.parse(['-i', 'file.txt'])
56
54
 
57
55
  assert_equal 'file.txt', @builder.options[:input_file]
@@ -69,20 +67,16 @@ class OptionBuilderTest < Minitest::Test
69
67
  end
70
68
 
71
69
  def test_with_output_dir
72
- # Test with default value
73
70
  @builder.with_output_dir('Test output dir', 'default/path')
74
71
 
75
- assert_includes @builder.parser.to_s, '-o, --output-dir DIR'
76
- assert_includes @builder.parser.to_s, 'Test output dir (default: default/path)'
72
+ verify_parser_option_format('-o, --output-dir DIR', 'Test output dir (default: default/path)')
73
+
77
74
  assert_equal 'default/path', @builder.options[:output_dir]
78
75
 
79
- # Test without default
80
76
  builder2 = EpubTools::CLI::OptionBuilder.new
81
77
  builder2.with_output_dir('Test output dir')
78
+ verify_required_parser_format(builder2, 'Test output dir (required)')
82
79
 
83
- assert_includes builder2.parser.to_s, 'Test output dir (required)'
84
-
85
- # Test actual parsing
86
80
  @builder.parse(['-o', 'new/path'])
87
81
 
88
82
  assert_equal 'new/path', @builder.options[:output_dir]
@@ -170,4 +164,20 @@ class OptionBuilderTest < Minitest::Test
170
164
 
171
165
  assert_equal @builder, result
172
166
  end
167
+
168
+ private
169
+
170
+ def verify_parser_option_format(option_format, description)
171
+ assert_includes @builder.parser.to_s, option_format
172
+ assert_includes @builder.parser.to_s, description
173
+ end
174
+
175
+ def verify_optional_parser_format(builder, description)
176
+ assert_includes builder.parser.to_s, description
177
+ refute_includes builder.parser.to_s, "#{description} (required)"
178
+ end
179
+
180
+ def verify_required_parser_format(builder, description)
181
+ assert_includes builder.parser.to_s, description
182
+ end
173
183
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../test_helper'
2
4
  require_relative '../../lib/epub_tools'
3
5
  require 'stringio'
@@ -33,15 +35,18 @@ class RunnerTest < Minitest::Test
33
35
  end
34
36
 
35
37
  def test_handle_command
36
- assert_output(/Usage: test-program test-cmd/) do
37
- assert_raises(SystemExit) { @runner.handle_command('test-cmd', ['-h']) }
38
+ @runner.registry.register('add', TestCommand)
39
+
40
+ assert_output(/Usage: test-program add/) do
41
+ assert_raises(SystemExit) { @runner.handle_command('add', ['-h']) }
38
42
  end
39
43
  end
40
44
 
41
45
  def test_handle_command_with_required_args
42
46
  runner = EpubTools::CLI::Runner.new('test-program')
43
- runner.registry.register('test-cmd', TestCommand)
44
- assert_output("Called!\n") { assert runner.handle_command('test-cmd') }
47
+ runner.registry.register('add', TestCommand)
48
+
49
+ assert_output("Called!\n") { assert runner.handle_command('add') }
45
50
  end
46
51
 
47
52
  def test_handle_nonexistent_command
@@ -69,18 +74,13 @@ class RunnerTest < Minitest::Test
69
74
  end
70
75
 
71
76
  def test_configure_command_options
72
- # This is testing a private method, which is generally not recommended,
73
- # but it's useful to ensure all command configurations work
77
+ # Test command configuration through public interface
78
+ @runner.registry.register('add', TestCommand)
74
79
 
75
- # Use send to access private method
76
- builder = EpubTools::CLI::OptionBuilder.new
77
-
78
- # Test each command configuration - we'll just check one example
79
- @runner.send(:configure_command_options, 'add', builder)
80
-
81
- # Check add command options were added
82
- assert_includes builder.parser.to_s, '--chapters-dir DIR'
83
- assert_includes builder.parser.to_s, '--epub-oebps-dir DIR'
80
+ # Should show help without errors
81
+ assert_output(/Usage: test-program add/) do
82
+ assert_raises(SystemExit) { @runner.handle_command('add', ['-h']) }
83
+ end
84
84
  end
85
85
 
86
86
  def test_run_with_unknown_command
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
  require 'fileutils'
3
5
  require 'tempfile'
@@ -79,7 +81,7 @@ class CLICommandsTest < Minitest::Test
79
81
 
80
82
  assert_match(/Usage: epub-tools add \[options\]/, output)
81
83
  assert_includes output, '--chapters-dir DIR'
82
- assert_includes output, '--epub-oebps-dir DIR'
84
+ assert_includes output, '--oebps-dir DIR'
83
85
  end
84
86
 
85
87
  def test_pack_command
data/test/cli_test.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
  require_relative 'cli/command_registry_test'
3
5
  require_relative 'cli/option_builder_test'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
  require_relative '../lib/epub_tools/version'
3
5
  require 'open3'