mint 0.7.3 → 0.8.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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +23 -14
  3. data/LICENSE +22 -0
  4. data/README.md +82 -56
  5. data/bin/mint +47 -10
  6. data/bin/mint-epub +1 -4
  7. data/config/templates/base/style.css +187 -0
  8. data/config/templates/default/css/style.css +126 -79
  9. data/config/templates/default/layout.erb +10 -0
  10. data/config/templates/default/style.css +237 -0
  11. data/config/templates/garden/layout.erb +38 -0
  12. data/config/templates/garden/style.css +303 -0
  13. data/config/templates/newspaper/layout.erb +16 -0
  14. data/config/templates/nord/layout.erb +11 -0
  15. data/config/templates/nord/style.css +339 -0
  16. data/config/templates/nord-dark/layout.erb +11 -0
  17. data/config/templates/nord-dark/style.css +339 -0
  18. data/config/templates/protocol/layout.erb +9 -0
  19. data/config/templates/protocol/style.css +25 -0
  20. data/config/templates/zen/layout.erb +11 -0
  21. data/config/templates/zen/style.css +114 -0
  22. data/lib/mint/command_line.rb +253 -111
  23. data/lib/mint/css.rb +11 -4
  24. data/lib/mint/css_template.rb +37 -0
  25. data/lib/mint/document.rb +193 -43
  26. data/lib/mint/helpers.rb +50 -10
  27. data/lib/mint/layout.rb +2 -3
  28. data/lib/mint/markdown_template.rb +47 -0
  29. data/lib/mint/mint.rb +181 -114
  30. data/lib/mint/plugin.rb +3 -3
  31. data/lib/mint/plugins/epub.rb +1 -2
  32. data/lib/mint/resource.rb +19 -9
  33. data/lib/mint/style.rb +10 -14
  34. data/lib/mint/version.rb +1 -1
  35. data/lib/mint.rb +1 -0
  36. data/man/mint.1 +135 -0
  37. data/spec/cli/README.md +99 -0
  38. data/spec/cli/argument_parsing_spec.rb +207 -0
  39. data/spec/cli/bin_integration_spec.rb +348 -0
  40. data/spec/cli/configuration_management_spec.rb +363 -0
  41. data/spec/cli/full_workflow_integration_spec.rb +527 -0
  42. data/spec/cli/publish_workflow_spec.rb +368 -0
  43. data/spec/cli/template_management_spec.rb +300 -0
  44. data/spec/css_spec.rb +1 -1
  45. data/spec/document_spec.rb +105 -68
  46. data/spec/helpers_spec.rb +42 -42
  47. data/spec/mint_spec.rb +104 -80
  48. data/spec/plugin_spec.rb +86 -88
  49. data/spec/run_cli_tests.rb +95 -0
  50. data/spec/spec_helper.rb +8 -1
  51. data/spec/style_spec.rb +18 -16
  52. data/spec/support/cli_helpers.rb +169 -0
  53. data/spec/support/fixtures/content-2.md +16 -0
  54. data/spec/support/matchers.rb +1 -1
  55. metadata +145 -167
  56. data/config/syntax.yaml +0 -71
  57. data/config/templates/base/style.sass +0 -144
  58. data/config/templates/default/layout.haml +0 -8
  59. data/config/templates/default/style.sass +0 -36
  60. data/config/templates/protocol/layout.haml +0 -7
  61. data/config/templates/protocol/style.sass +0 -20
  62. data/config/templates/zen/css/style.css +0 -145
  63. data/config/templates/zen/layout.haml +0 -7
  64. data/config/templates/zen/style.sass +0 -24
  65. data/features/config.feature +0 -21
  66. data/features/plugins/epub.feature +0 -23
  67. data/features/publish.feature +0 -73
  68. data/features/support/env.rb +0 -15
  69. data/features/templates.feature +0 -79
  70. data/spec/command_line_spec.rb +0 -87
  71. data/spec/plugins/epub_spec.rb +0 -242
@@ -0,0 +1,99 @@
1
+ # Mint CLI Test Suite
2
+
3
+ This directory contains a comprehensive test suite for the Mint command-line interface.
4
+
5
+ ## Test structure
6
+
7
+ ### Core test files
8
+
9
+ - **`argument_parsing_spec.rb`** - Tests command-line argument parsing and option handling
10
+ - **`template_management_spec.rb`** - Tests template installation, uninstallation, editing, and listing
11
+ - **`publish_workflow_spec.rb`** - Tests markdown publishing, file discovery, and output generation
12
+ - **`configuration_management_spec.rb`** - Tests configuration setting, reading, and scope management
13
+ - **`bin_integration_spec.rb`** - Tests actual `bin/mint` executable integration
14
+ - **`full_workflow_integration_spec.rb`** - End-to-end workflow tests for common user scenarios
15
+
16
+ ### Support files
17
+
18
+ - **`../support/cli_helpers.rb`** - Helper methods for CLI testing (temp directories, file creation, output capture)
19
+ - **`run_cli_tests.rb`** - Custom test runner with better output formatting
20
+
21
+ ## Running tests
22
+
23
+ ### Run all CLI tests
24
+
25
+ ```bash
26
+ # Using custom runner (recommended)
27
+ spec/run_cli_tests.rb
28
+
29
+ # Using RSpec directly
30
+ rspec spec/cli/ --format documentation
31
+ ```
32
+
33
+ ### Run specific test suites
34
+
35
+ ```bash
36
+ # Individual test suites
37
+ spec/run_cli_tests.rb argument_parsing
38
+ spec/run_cli_tests.rb template_management
39
+ spec/run_cli_tests.rb publish_workflow
40
+
41
+ # Or with RSpec
42
+ rspec spec/cli/argument_parsing_spec.rb
43
+ ```
44
+
45
+ ### Run integration tests only
46
+
47
+ ```bash
48
+ rspec spec/cli/full_workflow_integration_spec.rb
49
+ ```
50
+
51
+ ## Helper methods
52
+
53
+ The `cli_helpers.rb` provides utilities for:
54
+
55
+ ```ruby
56
+ # Temporary directories
57
+ in_temp_dir do |dir|
58
+ # Test code runs in isolated temp directory
59
+ end
60
+
61
+ # Output capture
62
+ stdout, stderr = capture_output do
63
+ Mint::CommandLine.some_method
64
+ end
65
+
66
+ # File creation
67
+ create_markdown_file("test.md", "# Content")
68
+ create_template_directory("custom", with_layout: true)
69
+
70
+ # Command execution
71
+ result = run_command("mint", "publish", "file.md")
72
+
73
+ # Content verification
74
+ verify_file_content("output.html") do |content|
75
+ expect(content).to include("expected text")
76
+ end
77
+ ```
78
+
79
+ ## Debugging failed tests
80
+
81
+ ### Common issues
82
+ 1. **Missing templates** - Tests create minimal templates; check `create_template_directory`
83
+ 2. **File paths** - All paths should be relative within temp directory
84
+ 3. **Configuration** - Use `setup_basic_config` to establish minimal config
85
+
86
+ ### Debug helpers
87
+
88
+ ```ruby
89
+ # Print current directory contents
90
+ puts Dir.glob("**/*")
91
+
92
+ # Print file contents
93
+ puts File.read("problematic.html") rescue "FILE NOT FOUND"
94
+
95
+ # Print configuration
96
+ puts YAML.load_file(".mint/config.yaml") rescue "NO CONFIG"
97
+ ```
98
+
99
+ This test suite provides comprehensive coverage of Mint's CLI functionality while being maintainable and fast to run.
@@ -0,0 +1,207 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "CLI Argument Parsing" do
4
+ describe "Mint::CommandLine.parse" do
5
+ context "with no arguments" do
6
+ it "returns default options and empty argv" do
7
+ result = Mint::CommandLine.parse([])
8
+
9
+ expect(result[:argv]).to eq([])
10
+ expect(result[:options][:root]).to eq(Dir.getwd)
11
+ expect(result[:options][:scope]).to eq(:local)
12
+ expect(result[:options][:layout_or_style_or_template]).to eq([:template, 'default'])
13
+ expect(result[:help]).to include("Usage: mint")
14
+ end
15
+ end
16
+
17
+ context "with template options" do
18
+ it "parses --template option" do
19
+ result = Mint::CommandLine.parse(["--template", "zen", "file.md"])
20
+
21
+ expect(result[:argv]).to eq(["file.md"])
22
+ expect(result[:options][:layout_or_style_or_template]).to eq([:template, "zen"])
23
+ end
24
+
25
+ it "parses --layout option" do
26
+ result = Mint::CommandLine.parse(["--layout", "custom", "file.md"])
27
+
28
+ expect(result[:argv]).to eq(["file.md"])
29
+ expect(result[:options][:layout_or_style_or_template]).to eq([:layout, "custom"])
30
+ end
31
+
32
+ it "parses --style option" do
33
+ result = Mint::CommandLine.parse(["--style", "minimal", "file.md"])
34
+
35
+ expect(result[:argv]).to eq(["file.md"])
36
+ expect(result[:options][:layout_or_style_or_template]).to eq([:style, "minimal"])
37
+ end
38
+
39
+ it "handles short flags for templates" do
40
+ result = Mint::CommandLine.parse(["-t", "pro", "file.md"])
41
+ expect(result[:options][:layout_or_style_or_template]).to eq([:template, "pro"])
42
+
43
+ result = Mint::CommandLine.parse(["--layout", "custom", "file.md"])
44
+ expect(result[:options][:layout_or_style_or_template]).to eq([:layout, "custom"])
45
+
46
+ result = Mint::CommandLine.parse(["-s", "clean", "file.md"])
47
+ expect(result[:options][:layout_or_style_or_template]).to eq([:style, "clean"])
48
+ end
49
+ end
50
+
51
+ context "with path options" do
52
+ it "parses --root option" do
53
+ result = Mint::CommandLine.parse(["--root", "/custom/path", "file.md"])
54
+
55
+ expect(result[:options][:root]).to eq("/custom/path")
56
+ end
57
+
58
+ it "parses --destination option" do
59
+ result = Mint::CommandLine.parse(["--destination", "output", "file.md"])
60
+
61
+ expect(result[:options][:destination]).to eq("output")
62
+ end
63
+
64
+ it "parses --style-destination option" do
65
+ result = Mint::CommandLine.parse(["--style-destination", "css", "file.md"])
66
+
67
+ expect(result[:options][:style_destination]).to eq("css")
68
+ end
69
+ end
70
+
71
+ context "with output options" do
72
+ it "parses --output-file option" do
73
+ result = Mint::CommandLine.parse(["--output-file", "custom.html", "file.md"])
74
+
75
+ expect(result[:options][:output_file]).to eq("custom.html")
76
+ end
77
+
78
+ it "has default output file format" do
79
+ result = Mint::CommandLine.parse(["file.md"])
80
+
81
+ expect(result[:options][:output_file]).to eq('#{basename}.#{new_extension}')
82
+ end
83
+ end
84
+
85
+ context "with scope options" do
86
+ it "parses --global scope" do
87
+ result = Mint::CommandLine.parse(["--global", "file.md"])
88
+
89
+ expect(result[:options][:scope]).to eq(:global)
90
+ end
91
+
92
+ it "parses --user scope" do
93
+ result = Mint::CommandLine.parse(["--user", "file.md"])
94
+
95
+ expect(result[:options][:scope]).to eq(:user)
96
+ end
97
+
98
+ it "parses --local scope (default)" do
99
+ result = Mint::CommandLine.parse(["--local", "file.md"])
100
+
101
+ expect(result[:options][:scope]).to eq(:local)
102
+ end
103
+
104
+ it "handles short scope flags" do
105
+ result = Mint::CommandLine.parse(["-g"])
106
+ expect(result[:options][:scope]).to eq(:global)
107
+
108
+ result = Mint::CommandLine.parse(["-u"])
109
+ expect(result[:options][:scope]).to eq(:user)
110
+
111
+ result = Mint::CommandLine.parse(["-l"])
112
+ expect(result[:options][:scope]).to eq(:local)
113
+ end
114
+ end
115
+
116
+ context "with boolean flags" do
117
+ it "parses --recursive flag" do
118
+ result = Mint::CommandLine.parse(["--recursive"])
119
+
120
+ expect(result[:options][:recursive]).to be true
121
+ end
122
+
123
+ it "handles short recursive flag" do
124
+ result = Mint::CommandLine.parse(["-r"])
125
+
126
+ expect(result[:options][:recursive]).to be true
127
+ end
128
+
129
+ it "defaults recursive to false" do
130
+ result = Mint::CommandLine.parse([])
131
+
132
+ expect(result[:options][:recursive]).to be false
133
+ end
134
+ end
135
+
136
+ context "with mixed arguments" do
137
+ it "parses complex argument combinations" do
138
+ args = [
139
+ "--template", "zen",
140
+ "--root", "/custom",
141
+ "--destination", "out",
142
+ "--recursive",
143
+ "--global",
144
+ "file1.md", "file2.md"
145
+ ]
146
+
147
+ result = Mint::CommandLine.parse(args)
148
+
149
+ expect(result[:argv]).to eq(["file1.md", "file2.md"])
150
+ expect(result[:options][:layout_or_style_or_template]).to eq([:template, "zen"])
151
+ expect(result[:options][:root]).to eq("/custom")
152
+ expect(result[:options][:destination]).to eq("out")
153
+ expect(result[:options][:recursive]).to be true
154
+ expect(result[:options][:scope]).to eq(:global)
155
+ end
156
+ end
157
+
158
+ context "argument processing utilities" do
159
+ describe ".process_output_format" do
160
+ it "processes basename substitution" do
161
+ result = Mint::CommandLine.process_output_format(
162
+ '#{basename}.html',
163
+ 'document.md'
164
+ )
165
+
166
+ expect(result).to eq('document.html')
167
+ end
168
+
169
+ it "processes original_extension substitution" do
170
+ result = Mint::CommandLine.process_output_format(
171
+ '#{basename}.#{original_extension}.bak',
172
+ 'document.md'
173
+ )
174
+
175
+ expect(result).to eq('document.md.bak')
176
+ end
177
+
178
+ it "processes new_extension substitution" do
179
+ result = Mint::CommandLine.process_output_format(
180
+ '#{basename}.#{new_extension}',
181
+ 'document.md'
182
+ )
183
+
184
+ expect(result).to eq('document.html')
185
+ end
186
+
187
+ it "processes complex format strings" do
188
+ result = Mint::CommandLine.process_output_format(
189
+ 'output/#{basename}-converted.#{new_extension}',
190
+ 'docs/readme.md'
191
+ )
192
+
193
+ expect(result).to eq('output/readme-converted.html')
194
+ end
195
+
196
+ it "handles files without extensions" do
197
+ result = Mint::CommandLine.process_output_format(
198
+ '#{basename}.#{new_extension}',
199
+ 'README'
200
+ )
201
+
202
+ expect(result).to eq('README.html')
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,348 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Bin Script Integration" do
4
+ describe "mint executable" do
5
+ let(:mint_bin) { File.expand_path("../../../bin/mint", __FILE__) }
6
+ let(:project_root) { File.expand_path("../../..", __FILE__) }
7
+
8
+ context "in isolated environment" do
9
+ around(:each) do |example|
10
+ in_temp_dir do |dir|
11
+ @test_dir = dir
12
+ # Copy bin scripts to test directory for isolation
13
+ FileUtils.cp_r("#{project_root}/bin", ".")
14
+ FileUtils.cp_r("#{project_root}/lib", ".")
15
+
16
+ # Make sure bin script is executable
17
+ FileUtils.chmod(0755, "bin/mint")
18
+ example.run
19
+ end
20
+ end
21
+
22
+ describe "basic command functionality" do
23
+ it "shows help when run with no arguments" do
24
+ result = run_command("ruby", "bin/mint")
25
+
26
+ expect(result.success?).to be true
27
+ expect(result.stdout).to include("Usage:")
28
+ end
29
+
30
+ it "shows help with --help flag" do
31
+ result = run_command("ruby", "bin/mint", "--help")
32
+
33
+ expect(result.stdout).to include("Usage: mint [command] files [options]")
34
+ expect(result.stdout).to include("--template")
35
+ expect(result.stdout).to include("--layout")
36
+ expect(result.stdout).to include("--style")
37
+ end
38
+
39
+ it "shows version information" do
40
+ # Assuming there's a --version flag or similar
41
+ # This might need adjustment based on actual implementation
42
+ result = run_command("ruby", "bin/mint", "--version")
43
+
44
+ # This test might fail if --version isn't implemented
45
+ # In that case, we could test a different way to get version info
46
+ end
47
+ end
48
+
49
+ describe "publish command" do
50
+ it "publishes markdown files via CLI" do
51
+ create_markdown_file("test.md", "# Hello from CLI")
52
+ setup_basic_config
53
+ create_template_directory("default")
54
+
55
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "test.md")
56
+
57
+ expect(result.success?).to be true
58
+ expect(File.exist?("test.html")).to be true
59
+
60
+ content = File.read("test.html")
61
+ expect(content).to include("Hello from CLI")
62
+ end
63
+
64
+ it "handles multiple files" do
65
+ create_markdown_file("doc1.md", "# Document 1")
66
+ create_markdown_file("doc2.md", "# Document 2")
67
+ setup_basic_config
68
+ create_template_directory("default")
69
+
70
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "doc1.md", "doc2.md")
71
+
72
+ expect(result.success?).to be true
73
+ expect(File.exist?("doc1.html")).to be true
74
+ expect(File.exist?("doc2.html")).to be true
75
+ end
76
+
77
+ it "respects template options" do
78
+ create_markdown_file("styled.md", "# Styled Document")
79
+ setup_basic_config
80
+ create_template_directory("default")
81
+ create_template_directory("custom")
82
+
83
+ # Write a distinctive custom template
84
+ File.write(".mint/templates/custom/layout.erb",
85
+ "<html><body class='custom-style'><%= content %></body></html>")
86
+ File.write(".mint/templates/custom/style.css",
87
+ "body { background: red; }")
88
+
89
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "--template", "custom", "styled.md")
90
+
91
+ expect(result.success?).to be true
92
+ expect(File.exist?("styled.html")).to be true
93
+
94
+ content = File.read("styled.html")
95
+ expect(content).to include("custom-style")
96
+ end
97
+
98
+ it "handles recursive publishing" do
99
+ FileUtils.mkdir_p("docs/sub")
100
+ create_markdown_file("docs/index.md", "# Index")
101
+ create_markdown_file("docs/sub/page.md", "# Sub Page")
102
+ setup_basic_config
103
+ create_template_directory("default")
104
+
105
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "--recursive", "docs")
106
+
107
+ expect(result.success?).to be true
108
+ expect(File.exist?("docs/index.html")).to be true
109
+ expect(File.exist?("docs/sub/page.html")).to be true
110
+ end
111
+
112
+ it "handles errors gracefully" do
113
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "nonexistent.md")
114
+
115
+ expect(result.success?).to be false
116
+ expect(result.stderr + result.stdout).to match(/error|Error|No such file|ENOENT/i)
117
+ end
118
+ end
119
+
120
+ describe "template management commands" do
121
+ it "lists templates" do
122
+ setup_basic_config
123
+ create_template_directory("custom1")
124
+ create_template_directory("custom2")
125
+
126
+ result = run_command("ruby", "bin/mint", "templates")
127
+
128
+ expect(result.success?).to be true
129
+ expect(result.stdout).to include("custom1")
130
+ expect(result.stdout).to include("custom2")
131
+ end
132
+
133
+ it "installs templates" do
134
+ create_template_file("my-layout.erb", :layout, "<html><%= yield %></html>")
135
+
136
+ result = run_command("ruby", "bin/mint", "install", "my-layout.erb", "mynew")
137
+
138
+ expect(result.success?).to be true
139
+ expect(File.exist?(".mint/templates/mynew/layout.erb")).to be true
140
+ end
141
+
142
+ it "uninstalls templates" do
143
+ setup_basic_config
144
+ create_template_directory("removeme")
145
+
146
+ # Verify it exists first
147
+ expect(File.exist?(".mint/templates/removeme")).to be true
148
+
149
+ result = run_command("ruby", "bin/mint", "uninstall", "removeme")
150
+
151
+ expect(result.success?).to be true
152
+ expect(File.exist?(".mint/templates/removeme")).to be false
153
+ end
154
+
155
+ it "edits templates" do
156
+ setup_basic_config
157
+ create_template_directory("editable", with_layout: true)
158
+
159
+ # Mock the editor to avoid opening a real editor
160
+ result = run_command(
161
+ {"EDITOR" => "echo 'edited'"},
162
+ "ruby", "bin/mint", "edit-layout", "editable"
163
+ )
164
+
165
+ expect(result.success?).to be true
166
+ end
167
+ end
168
+
169
+ describe "configuration commands" do
170
+ it "displays current configuration" do
171
+ setup_basic_config
172
+
173
+ result = run_command("ruby", "bin/mint", "config")
174
+
175
+ expect(result.success?).to be true
176
+ expect(result.stdout).to include("layout")
177
+ expect(result.stdout).to include("default")
178
+ end
179
+
180
+ it "sets configuration values" do
181
+ result = run_command("ruby", "bin/mint", "set", "layout", "custom-layout")
182
+
183
+ expect(result.success?).to be true
184
+ expect(File.exist?(".mint/config.yaml")).to be true
185
+
186
+ config = YAML.load_file(".mint/config.yaml")
187
+ expect(config["layout"]).to eq("custom-layout")
188
+ end
189
+
190
+ it "handles scope flags for configuration" do
191
+ result = run_command("ruby", "bin/mint", "set", "--local", "style", "local-style")
192
+
193
+ expect(result.success?).to be true
194
+
195
+ config = YAML.load_file(".mint/config.yaml")
196
+ expect(config["style"]).to eq("local-style")
197
+ end
198
+ end
199
+
200
+ describe "plugin commands" do
201
+ it "handles epub plugin" do
202
+ create_markdown_file("book.md", "# My Book\n\nContent here.")
203
+
204
+ # This might fail if epub dependencies aren't available
205
+ result = run_command("ruby", "bin/mint-epub", "publish", "book.md")
206
+
207
+ # We expect this to either work or fail gracefully
208
+ # The specific behavior depends on whether epub dependencies are installed
209
+ expect([true, false]).to include(result.success?)
210
+ end
211
+ end
212
+
213
+ describe "error handling and edge cases" do
214
+ it "handles unknown commands gracefully" do
215
+ result = run_command("ruby", "bin/mint", "unknown-command")
216
+
217
+ expect(result.success?).to be false
218
+ expect(result.stderr + result.stdout).to match(/error|Usage/)
219
+ end
220
+
221
+ it "handles malformed arguments" do
222
+ result = run_command("ruby", "bin/mint", "publish", "--invalid-flag")
223
+
224
+ expect(result.success?).to be false
225
+ end
226
+
227
+ it "provides helpful error messages" do
228
+ result = run_command("ruby", "bin/mint", "edit", "nonexistent-template")
229
+
230
+ expect(result.success?).to be false
231
+ # Should provide a helpful error about the missing template
232
+ end
233
+
234
+ it "handles permission errors" do
235
+ create_markdown_file("test.md", "# Test")
236
+
237
+ # Try to publish to a location we can't write to
238
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "--destination", "/root", "test.md")
239
+
240
+ expect(result.success?).to be false
241
+ end
242
+ end
243
+
244
+ describe "environment handling" do
245
+ it "respects EDITOR environment variable" do
246
+ setup_basic_config
247
+ create_template_directory("test", with_layout: true)
248
+
249
+ result = run_command(
250
+ {"EDITOR" => "echo 'custom-editor'"},
251
+ "ruby", "bin/mint", "edit-layout", "test"
252
+ )
253
+
254
+ expect(result.success?).to be true
255
+ end
256
+
257
+ it "works with different working directories" do
258
+ FileUtils.mkdir_p("subdir")
259
+ Dir.chdir("subdir") do
260
+ create_markdown_file("doc.md", "# From Subdir")
261
+
262
+ result = run_command("ruby", "../bin/mint", "publish", "doc.md")
263
+
264
+ # This might require the default template to exist
265
+ # The exact behavior depends on how Mint handles paths
266
+ end
267
+ end
268
+
269
+ it "handles Ruby load path correctly" do
270
+ # The bin script should be able to find the lib directory
271
+ result = run_command("ruby", "bin/mint", "--help")
272
+
273
+ expect(result.success?).to be true
274
+ # Should not have load errors
275
+ expect(result.stderr).not_to include("LoadError")
276
+ expect(result.stderr).not_to include("cannot load such file")
277
+ end
278
+ end
279
+
280
+ describe "output formatting and verbosity" do
281
+ it "produces clean output for normal operations" do
282
+ create_markdown_file("test.md", "# Test")
283
+ setup_basic_config
284
+ create_template_directory("default")
285
+
286
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "test.md")
287
+
288
+ expect(result.success?).to be true
289
+ # Output should be minimal for successful operations
290
+ expect(result.stdout.length).to be < 100
291
+ end
292
+
293
+ it "provides detailed output in verbose mode" do
294
+ create_markdown_file("test.md", "# Test")
295
+ setup_basic_config
296
+ create_template_directory("default")
297
+
298
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "--verbose", "test.md")
299
+
300
+ # Verbose mode should provide more information
301
+ # This test depends on whether --verbose is implemented
302
+ end
303
+
304
+ it "formats template listings nicely" do
305
+ setup_basic_config
306
+ create_template_directory("template-one")
307
+ create_template_directory("template-two")
308
+
309
+ result = run_command("ruby", "bin/mint", "templates")
310
+
311
+ expect(result.success?).to be true
312
+
313
+ # Should be formatted nicely, one per line
314
+ lines = result.stdout.split("\n").reject(&:empty?)
315
+ expect(lines.length).to be >= 2
316
+ end
317
+ end
318
+
319
+ describe "integration with system tools" do
320
+ it "can be used in shell pipelines" do
321
+ create_markdown_file("input.md", "# Pipeline Test")
322
+ setup_basic_config
323
+ create_template_directory("default")
324
+
325
+ # Test that it works with shell redirection
326
+ result = run_command("bash", "-c", "MINT_NO_PIPE=1 ruby bin/mint publish input.md 2>&1")
327
+
328
+ expect(result.success?).to be true
329
+ expect(File.exist?("input.html")).to be true
330
+ end
331
+
332
+ it "exits with appropriate status codes" do
333
+ # Success case
334
+ create_markdown_file("success.md", "# Success")
335
+ setup_basic_config
336
+ create_template_directory("default")
337
+
338
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "success.md")
339
+ expect(result.exit_code).to eq(0)
340
+
341
+ # Failure case
342
+ result = run_command({"MINT_NO_PIPE" => "1"}, "ruby", "bin/mint", "publish", "nonexistent.md")
343
+ expect(result.exit_code).not_to eq(0)
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end