mint 0.8.1 → 0.10.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.
- checksums.yaml +4 -4
- data/Gemfile +1 -26
- data/README.md +117 -37
- data/bin/mint +2 -81
- data/config/templates/base/navigation.css +136 -0
- data/config/templates/base/print.css +152 -0
- data/config/templates/{reset.css → base/reset.css} +1 -1
- data/config/templates/base/style.css +117 -137
- data/config/templates/base/utilities.css +136 -0
- data/config/templates/base/variables.css +124 -0
- data/config/templates/basic/style.css +151 -0
- data/config/templates/default/layout.erb +33 -3
- data/config/templates/default/style.css +95 -164
- data/config/templates/magazine/style.css +383 -0
- data/config/templates/nord/style.css +105 -220
- data/config/templates/nord-dark/style.css +82 -263
- data/lib/mint/commandline/parse.rb +144 -0
- data/lib/mint/commandline/publish.rb +46 -0
- data/lib/mint/commandline/run.rb +30 -0
- data/lib/mint/config.rb +162 -0
- data/lib/mint/{css.rb → css_dsl.rb} +9 -9
- data/lib/mint/css_parser.rb +45 -25
- data/lib/mint/document.rb +250 -365
- data/lib/mint/document_tree.rb +163 -0
- data/lib/mint/exceptions.rb +2 -3
- data/lib/mint/helpers.rb +23 -180
- data/lib/mint/layout.rb +26 -9
- data/lib/mint/renderers/css_renderer.rb +32 -0
- data/lib/mint/renderers/erb_renderer.rb +11 -0
- data/lib/mint/renderers/markdown_renderer.rb +45 -0
- data/lib/mint/style.rb +21 -31
- data/lib/mint/template.rb +30 -0
- data/lib/mint/version.rb +1 -1
- data/lib/mint/workspace.rb +171 -0
- data/lib/mint.rb +44 -12
- data/man/mint.1 +85 -44
- data/spec/cli/README.md +2 -2
- data/spec/cli/argument_parsing_spec.rb +89 -147
- data/spec/cli/bin_integration_spec.rb +23 -243
- data/spec/cli/full_workflow_integration_spec.rb +99 -442
- data/spec/cli/original_style_integration_spec.rb +58 -0
- data/spec/cli/publish_workflow_spec.rb +72 -70
- data/spec/commandline_path_integration_spec.rb +230 -0
- data/spec/config_file_integration_spec.rb +362 -0
- data/spec/{css_spec.rb → css_dsl_spec.rb} +7 -3
- data/spec/css_parser_spec.rb +59 -1
- data/spec/document_spec.rb +37 -242
- data/spec/flattened_path_spec.rb +150 -0
- data/spec/layout_spec.rb +42 -3
- data/spec/mint_spec.rb +22 -217
- data/spec/path_handling_spec.rb +237 -0
- data/spec/run_cli_tests.rb +1 -1
- data/spec/spec_helper.rb +3 -10
- data/spec/style_spec.rb +31 -56
- data/spec/support/cli_helpers.rb +7 -10
- data/spec/support/matchers.rb +1 -1
- data/spec/template_spec.rb +31 -0
- data/spec/workspace_spec.rb +177 -0
- metadata +75 -89
- data/bin/mint-epub +0 -20
- data/config/templates/garden/layout.erb +0 -38
- data/config/templates/garden/style.css +0 -303
- data/config/templates/nord/layout.erb +0 -11
- data/config/templates/nord-dark/layout.erb +0 -11
- data/config/templates/zen/layout.erb +0 -11
- data/config/templates/zen/style.css +0 -114
- data/lib/mint/command_line.rb +0 -360
- data/lib/mint/css_template.rb +0 -37
- data/lib/mint/markdown_template.rb +0 -47
- data/lib/mint/mint.rb +0 -313
- data/lib/mint/plugin.rb +0 -136
- data/lib/mint/plugins/epub.rb +0 -293
- data/lib/mint/resource.rb +0 -101
- data/plugins/templates/epub/layouts/container.haml +0 -5
- data/plugins/templates/epub/layouts/content.haml +0 -35
- data/plugins/templates/epub/layouts/layout.haml +0 -6
- data/plugins/templates/epub/layouts/title.haml +0 -11
- data/plugins/templates/epub/layouts/toc.haml +0 -26
- data/spec/cli/configuration_management_spec.rb +0 -363
- data/spec/cli/template_management_spec.rb +0 -300
- data/spec/helpers_spec.rb +0 -249
- data/spec/plugin_spec.rb +0 -449
- data/spec/resource_spec.rb +0 -135
data/spec/helpers_spec.rb
DELETED
@@ -1,249 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
module Mint
|
4
|
-
describe Helpers do
|
5
|
-
describe ".underscore" do
|
6
|
-
it "underscores class names per ActiveSupport conventions" do
|
7
|
-
expect(Helpers.underscore("ClassName")).to eq("class_name")
|
8
|
-
end
|
9
|
-
|
10
|
-
it "allows for camel case prefixes" do
|
11
|
-
expect(Helpers.underscore("EPub")).to eq("e_pub")
|
12
|
-
expect(Helpers.underscore("EPub", :ignore_prefix => true)).to eq("epub")
|
13
|
-
end
|
14
|
-
|
15
|
-
it "allows for namespace removal" do
|
16
|
-
expect(Helpers.underscore("Mint::EPub",
|
17
|
-
:namespaces => true)).to eq("mint/e_pub")
|
18
|
-
expect(Helpers.underscore("Mint::EPub",
|
19
|
-
:namespaces => false)).to eq("e_pub")
|
20
|
-
expect(Helpers.underscore("Mint::EPub",
|
21
|
-
:namespaces => true,
|
22
|
-
:ignore_prefix => true)).to eq("mint/epub")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe ".slugize" do
|
27
|
-
it "downcases everything" do
|
28
|
-
expect(Helpers.slugize("This could use FEWER CAPITALS")).to eq(
|
29
|
-
"this-could-use-fewer-capitals")
|
30
|
-
end
|
31
|
-
|
32
|
-
it "parses 'and'" do
|
33
|
-
expect(Helpers.slugize("You & me")).to eq("you-and-me")
|
34
|
-
end
|
35
|
-
|
36
|
-
it "parses spaces" do
|
37
|
-
expect(Helpers.slugize("You and me")).to eq("you-and-me")
|
38
|
-
end
|
39
|
-
|
40
|
-
it "removes non-word/non-digits" do
|
41
|
-
expect(Helpers.slugize("You // and :: me")).to eq("you-and-me")
|
42
|
-
end
|
43
|
-
|
44
|
-
it "condenses multiple hyphens" do
|
45
|
-
expect(Helpers.slugize("You-----and me")).to eq("you-and-me")
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe ".symbolize" do
|
50
|
-
it "converts hyphens to underscores" do
|
51
|
-
expect(Helpers.symbolize("you-and-me")).to eq(:you_and_me)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe ".pathize" do
|
56
|
-
it "converts a String to a Pathname" do
|
57
|
-
expect(Helpers.pathize("filename.md")).to eq(
|
58
|
-
Pathname.new("filename.md").expand_path)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "does not convert a Pathname" do
|
62
|
-
pathname = Pathname.new("filename.md")
|
63
|
-
expect(Helpers.pathize(pathname)).to eq(pathname.expand_path)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe ".symbolize_keys" do
|
68
|
-
it "turns all string keys in a flat map into symbols" do
|
69
|
-
flat_map = {
|
70
|
-
"key1" => "value1",
|
71
|
-
"key2" => "value2",
|
72
|
-
"key3" => "value3"
|
73
|
-
}
|
74
|
-
|
75
|
-
expected_map = {
|
76
|
-
key1: "value1",
|
77
|
-
key2: "value2",
|
78
|
-
key3: "value3"
|
79
|
-
}
|
80
|
-
|
81
|
-
expect(Helpers.symbolize_keys(flat_map)).to eq(expected_map)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "recursively turns all string keys in a nested map into symbols" do
|
85
|
-
nested_map = {
|
86
|
-
"key1" => "value1",
|
87
|
-
"key2" => "value2",
|
88
|
-
"key3" => "value3",
|
89
|
-
"key4" => {
|
90
|
-
"nested_key1" => "nested_value1",
|
91
|
-
"nested_key2" => "nested_value2"
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
expected_map = {
|
96
|
-
key1: "value1",
|
97
|
-
key2: "value2",
|
98
|
-
key3: "value3",
|
99
|
-
key4: {
|
100
|
-
nested_key1: "nested_value1",
|
101
|
-
nested_key2: "nested_value2"
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
105
|
-
expect(Helpers.symbolize_keys(nested_map)).to eq(expected_map)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "recursively downcases all keys if specified" do
|
109
|
-
capitalized_map = {
|
110
|
-
"Key1" => "value1",
|
111
|
-
"Key2" => "value2",
|
112
|
-
"Key3" => "value3",
|
113
|
-
"Key4" => {
|
114
|
-
"Nested_key1" => "nested_value1",
|
115
|
-
"Nested_key2" => "nested_value2"
|
116
|
-
}
|
117
|
-
}
|
118
|
-
|
119
|
-
expected_map = {
|
120
|
-
key1: "value1",
|
121
|
-
key2: "value2",
|
122
|
-
key3: "value3",
|
123
|
-
key4: {
|
124
|
-
nested_key1: "nested_value1",
|
125
|
-
nested_key2: "nested_value2"
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
|
-
expect(Helpers.symbolize_keys(capitalized_map, :downcase => true)).to eq(expected_map)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe ".listify" do
|
134
|
-
it "joins a list of three or more with an ampersand, without the Oxford comma" do
|
135
|
-
expect(Helpers.listify(["Alex", "Chris", "John"])).to eq(
|
136
|
-
"Alex, Chris & John")
|
137
|
-
end
|
138
|
-
|
139
|
-
it "joins a list of two with an ampersand" do
|
140
|
-
expect(Helpers.listify(["Alex", "Chris"])).to eq("Alex & Chris")
|
141
|
-
end
|
142
|
-
|
143
|
-
it "does not do anything to a list of one" do
|
144
|
-
expect(Helpers.listify(["Alex"])).to eq("Alex")
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe ".standardize" do
|
149
|
-
before do
|
150
|
-
@nonstandard = {
|
151
|
-
title: "Title",
|
152
|
-
author: "David",
|
153
|
-
editors: ["David", "Jake"],
|
154
|
-
barcode: "Unique ID"
|
155
|
-
}
|
156
|
-
|
157
|
-
@table = {
|
158
|
-
author: [:creators, :array],
|
159
|
-
editors: [:collaborators, :array],
|
160
|
-
barcode: [:uuid, :string]
|
161
|
-
}
|
162
|
-
|
163
|
-
@standard = {
|
164
|
-
title: "Title",
|
165
|
-
creators: ["David"],
|
166
|
-
collaborators: ["David", "Jake"],
|
167
|
-
uuid: "Unique ID"
|
168
|
-
}
|
169
|
-
end
|
170
|
-
|
171
|
-
it "converts all nonstandard keys to standard ones" do
|
172
|
-
expect(Helpers.standardize(@nonstandard,
|
173
|
-
:table => @table)).to eq(@standard)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe ".hashify" do
|
178
|
-
it "zips two lists of the same size into a Hash" do
|
179
|
-
expect(Helpers.hashify([:one, :two, :three], [1, 2, 3])).to eq({
|
180
|
-
one: 1,
|
181
|
-
two: 2,
|
182
|
-
three: 3
|
183
|
-
})
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe ".normalize_path" do
|
188
|
-
it "handles two files in the same directory" do
|
189
|
-
path1 = "~/file1"
|
190
|
-
path2 = "~/file2"
|
191
|
-
expect(Helpers.normalize_path(path1, path2)).to eq(
|
192
|
-
Pathname.new("../file1"))
|
193
|
-
end
|
194
|
-
|
195
|
-
it "handles two files one directory apart" do
|
196
|
-
path1 = "~/file1"
|
197
|
-
path2 = "~/subdir/file2"
|
198
|
-
expect(Helpers.normalize_path(path1, path2)).to eq(
|
199
|
-
Pathname.new("../../file1"))
|
200
|
-
end
|
201
|
-
|
202
|
-
it "handles two files linked only at the directory root" do
|
203
|
-
path1 = "/home/david/file1"
|
204
|
-
path2 = "/usr/local/src/file2"
|
205
|
-
expect(Helpers.normalize_path(path1, path2)).to eq(
|
206
|
-
Pathname.new("/home/david/file1"))
|
207
|
-
end
|
208
|
-
|
209
|
-
it "returns nil for identical files" do
|
210
|
-
path1 = "~/file1"
|
211
|
-
path2 = "~/file1"
|
212
|
-
expect(Helpers.normalize_path(path1, path2)).to eq(Pathname.new("."))
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe ".update_yaml!" do
|
217
|
-
before do
|
218
|
-
File.open "example.yaml", "w" do |file|
|
219
|
-
file << "conflicting: foo\nnon-conflicting: bar"
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
it "combines specified data with data in YAML file and updates file" do
|
224
|
-
Helpers.update_yaml! "example.yaml", "conflicting" => "baz"
|
225
|
-
expect(YAML.load_file("example.yaml")["conflicting"]).to eq("baz")
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
describe ".generate_temp_file!" do
|
230
|
-
before do
|
231
|
-
@file = Helpers.generate_temp_file! "content.md"
|
232
|
-
@path = Pathname.new @file
|
233
|
-
end
|
234
|
-
|
235
|
-
it "creates a randomly named temp file" do
|
236
|
-
expect(@path).to exist
|
237
|
-
end
|
238
|
-
|
239
|
-
it "creates a temp file with the correct name and extension" do
|
240
|
-
expect(@path.basename.to_s).to match(/content/)
|
241
|
-
expect(@path.extname).to eq(".md")
|
242
|
-
end
|
243
|
-
|
244
|
-
it "fills the temp file with the specified content" do
|
245
|
-
expect(@path.read).to match(/This is just a test/)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
data/spec/plugin_spec.rb
DELETED
@@ -1,449 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mint do
|
4
|
-
# Remove unintended side effects of creating
|
5
|
-
# new plugins in other files.
|
6
|
-
before { Mint.clear_plugins! }
|
7
|
-
after { Mint.clear_plugins! }
|
8
|
-
|
9
|
-
describe ".plugins" do
|
10
|
-
it "returns all registered plugins" do
|
11
|
-
plugin = Class.new(Mint::Plugin)
|
12
|
-
expect(Mint.plugins).to eq([plugin])
|
13
|
-
end
|
14
|
-
|
15
|
-
it "returns an empty array if there are no registered plugins" do
|
16
|
-
expect(Mint.plugins).to eq([])
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe ".register_plugin!" do
|
21
|
-
let(:plugin) { Class.new }
|
22
|
-
|
23
|
-
it "registers a plugin once" do
|
24
|
-
Mint.register_plugin! plugin
|
25
|
-
expect(Mint.plugins).to eq([plugin])
|
26
|
-
end
|
27
|
-
|
28
|
-
it "does not register a plugin more than once" do
|
29
|
-
Mint.register_plugin! plugin
|
30
|
-
expect { Mint.register_plugin! plugin }.not_to change { Mint.plugins }
|
31
|
-
expect(Mint.plugins).to eq([plugin])
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe ".activate_plugin!" do
|
36
|
-
let(:plugin) { Class.new }
|
37
|
-
|
38
|
-
it "activates a plugin once" do
|
39
|
-
Mint.activate_plugin! plugin
|
40
|
-
expect(Mint.activated_plugins).to eq [plugin]
|
41
|
-
end
|
42
|
-
|
43
|
-
it "does not register a plugin more than once" do
|
44
|
-
Mint.activate_plugin! plugin
|
45
|
-
expect { Mint.activate_plugin! plugin }.not_to change { Mint.activated_plugins }
|
46
|
-
expect(Mint.activated_plugins).to eq [plugin]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe ".clear_plugins!" do
|
51
|
-
let(:plugin) { Class.new }
|
52
|
-
|
53
|
-
it "does nothing if no plugins are registered" do
|
54
|
-
expect { Mint.clear_plugins! }.not_to raise_error
|
55
|
-
end
|
56
|
-
|
57
|
-
it "removes all registered plugins" do
|
58
|
-
Mint.register_plugin! plugin
|
59
|
-
expect { Mint.clear_plugins! }.to change { Mint.plugins.length }.by(-1)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "removes all activated plugins" do
|
63
|
-
Mint.activate_plugin! plugin
|
64
|
-
expect { Mint.clear_plugins! }.to change { Mint.activated_plugins.length }.by(-1)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe ".template_directory" do
|
69
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
70
|
-
|
71
|
-
it "gives access to a directory where template files can be stored" do
|
72
|
-
expect(plugin).to receive(:name).and_return("DocBook")
|
73
|
-
expect(Mint.template_directory(plugin)).to eq(
|
74
|
-
Mint::ROOT + "/plugins/templates/doc_book")
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
describe ".config_directory" do
|
79
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
80
|
-
|
81
|
-
it "gives access to a directory where template files can be stored" do
|
82
|
-
expect(plugin).to receive(:name).and_return("DocBook")
|
83
|
-
expect(Mint.config_directory(plugin)).to eq(
|
84
|
-
Mint::ROOT + "/plugins/config/doc_book")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe ".commandline_options_file" do
|
89
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
90
|
-
|
91
|
-
it "gives access to a directory where template files can be stored" do
|
92
|
-
expect(plugin).to receive(:name).and_return("DocBook")
|
93
|
-
expect(Mint.commandline_options_file(plugin)).to eq(
|
94
|
-
Mint::ROOT + "/plugins/config/doc_book/syntax.yml")
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
[:before_render, :after_render].each do |callback|
|
99
|
-
describe ".#{callback}" do
|
100
|
-
let(:first_plugin) { Class.new(Mint::Plugin) }
|
101
|
-
let(:second_plugin) { Class.new(Mint::Plugin) }
|
102
|
-
let(:third_plugin) { Class.new(Mint::Plugin) }
|
103
|
-
|
104
|
-
context "when plugins are specified" do
|
105
|
-
before do
|
106
|
-
expect(first_plugin).to receive(callback).ordered.and_return("first")
|
107
|
-
expect(second_plugin).to receive(callback).ordered.and_return("second")
|
108
|
-
expect(third_plugin).to receive(callback).never
|
109
|
-
end
|
110
|
-
|
111
|
-
it "reduces .#{callback} across all specified plugins in order" do
|
112
|
-
plugins = [first_plugin, second_plugin]
|
113
|
-
expect(Mint.send(callback, "text", :plugins => plugins)).to eq("second")
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
context "when plugins are activated, but no plugins are specified" do
|
118
|
-
before do
|
119
|
-
expect(first_plugin).to receive(callback).ordered.and_return("first")
|
120
|
-
expect(second_plugin).to receive(callback).ordered.and_return("second")
|
121
|
-
expect(third_plugin).to receive(callback).never
|
122
|
-
end
|
123
|
-
|
124
|
-
it "reduces .#{callback} across all activated plugins in order" do
|
125
|
-
Mint.activate_plugin! first_plugin
|
126
|
-
Mint.activate_plugin! second_plugin
|
127
|
-
expect(Mint.send(callback, "text")).to eq("second")
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context "when plugins are not specified" do
|
132
|
-
before do
|
133
|
-
expect(first_plugin).to receive(callback).never
|
134
|
-
expect(second_plugin).to receive(callback).never
|
135
|
-
expect(third_plugin).to receive(callback).never
|
136
|
-
end
|
137
|
-
|
138
|
-
it "returns the parameter text" do
|
139
|
-
expect(Mint.send(callback, "text")).to eq("text")
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe ".after_publish" do
|
146
|
-
let(:first_plugin) { Class.new(Mint::Plugin) }
|
147
|
-
let(:second_plugin) { Class.new(Mint::Plugin) }
|
148
|
-
let(:third_plugin) { Class.new(Mint::Plugin) }
|
149
|
-
|
150
|
-
context "when plugins are specified" do
|
151
|
-
before do
|
152
|
-
expect(first_plugin).to receive(:after_publish).ordered
|
153
|
-
expect(second_plugin).to receive(:after_publish).ordered
|
154
|
-
expect(third_plugin).to receive(:after_publish).never
|
155
|
-
end
|
156
|
-
|
157
|
-
it "iterates across all specified plugins in order" do
|
158
|
-
plugins = [first_plugin, second_plugin]
|
159
|
-
Mint.after_publish("fake document", :plugins => plugins)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context "when plugins are activated, but no plugins are specified" do
|
164
|
-
before do
|
165
|
-
expect(first_plugin).to receive(:after_publish).ordered
|
166
|
-
expect(second_plugin).to receive(:after_publish).ordered
|
167
|
-
expect(third_plugin).to receive(:after_publish).never
|
168
|
-
end
|
169
|
-
|
170
|
-
it "iterates across all activated plugins in order" do
|
171
|
-
Mint.activate_plugin! first_plugin
|
172
|
-
Mint.activate_plugin! second_plugin
|
173
|
-
Mint.after_publish("fake document")
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context "when plugins are not specified" do
|
178
|
-
before do
|
179
|
-
expect(first_plugin).to receive(:after_publish).never
|
180
|
-
expect(second_plugin).to receive(:after_publish).never
|
181
|
-
expect(third_plugin).to receive(:after_publish).never
|
182
|
-
end
|
183
|
-
|
184
|
-
it "does not iterate over any plugins" do
|
185
|
-
Mint.after_publish("fake document")
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# TODO: Document expected document functionality changes related to plugins
|
191
|
-
# describe Mint::Document do
|
192
|
-
# context "when plugins are registered with Mint" do
|
193
|
-
# describe "#content=" do
|
194
|
-
# it "applies each registered plugin's before_render filter"
|
195
|
-
# end
|
196
|
-
|
197
|
-
# describe "#render" do
|
198
|
-
# it "applies each registered plugin's after_render filter"
|
199
|
-
# end
|
200
|
-
|
201
|
-
# describe "#publish!" do
|
202
|
-
# it "applies each registered plugin's after_publish filter"
|
203
|
-
# end
|
204
|
-
# end
|
205
|
-
# end
|
206
|
-
|
207
|
-
describe Mint::Plugin do
|
208
|
-
# We have to instantiate these plugins in a before block,
|
209
|
-
# and not in a let block. Because lets are lazily evaluated,
|
210
|
-
# the first two tests in the "#inherited" suite will not
|
211
|
-
# pass.
|
212
|
-
before do
|
213
|
-
@first_plugin = Class.new(Mint::Plugin)
|
214
|
-
@second_plugin = Class.new(Mint::Plugin)
|
215
|
-
end
|
216
|
-
|
217
|
-
describe ".underscore" do
|
218
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
219
|
-
|
220
|
-
# it "when anonymous, returns a random identifier"
|
221
|
-
|
222
|
-
it "when named, returns its name, underscored" do
|
223
|
-
expect(plugin).to receive(:name).and_return("EPub")
|
224
|
-
expect(plugin.underscore).to eq("epub")
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
describe ".inherited" do
|
229
|
-
it "registers the subclass with Mint as a plugin" do
|
230
|
-
expect do
|
231
|
-
Class.new(Mint::Plugin)
|
232
|
-
end.to change { Mint.plugins.length }.by(1)
|
233
|
-
end
|
234
|
-
|
235
|
-
it "preserves the order of subclassing" do
|
236
|
-
expect(Mint.plugins).to eq([@first_plugin, @second_plugin])
|
237
|
-
end
|
238
|
-
|
239
|
-
it "does not change the order of a plugin when it is monkey-patched" do
|
240
|
-
expect do
|
241
|
-
@first_plugin.instance_eval do
|
242
|
-
def monkey_patch
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end.not_to change { Mint.plugins }
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
describe ".commandline_options" do
|
250
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
251
|
-
before do
|
252
|
-
plugin.instance_eval do
|
253
|
-
def commandline_options
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
# it "returns a hash of options the plugin can take, including constraints"
|
259
|
-
end
|
260
|
-
|
261
|
-
context "plugin callbacks" do
|
262
|
-
let(:plugin) { Class.new(Mint::Plugin) }
|
263
|
-
|
264
|
-
describe ".before_render" do
|
265
|
-
it "allows changes to the un-rendered content" do
|
266
|
-
plugin.instance_eval do
|
267
|
-
def before_render(text_document)
|
268
|
-
"base"
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
expect(plugin.before_render("text")).to eq("base")
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
describe ".after_render" do
|
277
|
-
it "allows changes to the rendered HTML" do
|
278
|
-
plugin.instance_eval do
|
279
|
-
def after_render(html_document)
|
280
|
-
"<!doctype html>"
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
expect(plugin.after_render("<html></html>")).to eq("<!doctype html>")
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
describe ".after_mint" do
|
289
|
-
let(:document) { Mint::Document.new "content.md" }
|
290
|
-
|
291
|
-
it "allows changes to the document extension" do
|
292
|
-
plugin.class_eval do
|
293
|
-
def self.after_publish(document)
|
294
|
-
document.name.gsub! /html$/, "htm"
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
expect do
|
299
|
-
plugin.after_publish(document)
|
300
|
-
end.to change { document.name.length }.by(-1)
|
301
|
-
end
|
302
|
-
|
303
|
-
it "allows splitting up the document into two, without garbage" do
|
304
|
-
plugin.class_eval do
|
305
|
-
def self.after_publish(document)
|
306
|
-
content = document.content
|
307
|
-
fake_splitting_point = content.length / 2
|
308
|
-
|
309
|
-
first = content[0..fake_splitting_point]
|
310
|
-
second = content[fake_splitting_point..-1]
|
311
|
-
|
312
|
-
File.open "first-half.html", "w+" do |file|
|
313
|
-
file << first
|
314
|
-
end
|
315
|
-
|
316
|
-
File.open "second-half.html", "w+" do |file|
|
317
|
-
file << second
|
318
|
-
end
|
319
|
-
|
320
|
-
File.delete document.destination_file
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
document.publish! :plugins => [plugin]
|
325
|
-
|
326
|
-
expect(File.exist?(document.destination_file)).to be_falsy
|
327
|
-
expect(File.exist?("first-half.html")).to be_truthy
|
328
|
-
expect(File.exist?("second-half.html")).to be_truthy
|
329
|
-
end
|
330
|
-
|
331
|
-
# it "allows changes to the style file" do
|
332
|
-
# pending "figure out a better strategy for style manipulation"
|
333
|
-
# document = Mint::Document.new "content.md", style: "style.css"
|
334
|
-
|
335
|
-
# plugin.instance_eval do
|
336
|
-
# def after_publish(document)
|
337
|
-
# # I'd like to take document.style_destination_file,
|
338
|
-
# # but the current Mint API doesn't allow for this
|
339
|
-
# # if we're setting the style via a concrete
|
340
|
-
# # stylesheet in our current directory
|
341
|
-
# style_source = document.style.source_file
|
342
|
-
# style = File.read style_source
|
343
|
-
# File.open style_source, "w" do |file|
|
344
|
-
# file << style.gsub(/#/, ".")
|
345
|
-
# end
|
346
|
-
# end
|
347
|
-
# end
|
348
|
-
|
349
|
-
# document.publish! :plugins => [plugin]
|
350
|
-
|
351
|
-
# File.read(document.style.source_file).should =~ /\#container/
|
352
|
-
# end
|
353
|
-
|
354
|
-
# context "when the output is in the default directory" do
|
355
|
-
# it "doesn't allow changes to the document directory" do
|
356
|
-
# pending "figuring out the best way to prevent directory manipulation"
|
357
|
-
# document = Mint::Document.new "content.md"
|
358
|
-
# plugin.instance_eval do
|
359
|
-
# def after_publish
|
360
|
-
# original = document.destination_directory
|
361
|
-
# new = File.expand_path "invalid"
|
362
|
-
# FileUtils.mv original, new
|
363
|
-
# document.destination = "invalid"
|
364
|
-
# end
|
365
|
-
|
366
|
-
# expect do
|
367
|
-
# document.publish! :plugins => [plugin]
|
368
|
-
# end.to raise_error(InvalidPluginAction)
|
369
|
-
# end
|
370
|
-
# end
|
371
|
-
# end
|
372
|
-
|
373
|
-
context "when the output is a new directory" do
|
374
|
-
it "allows changes to the document directory" do
|
375
|
-
document = Mint::Document.new "content.md", destination: "destination"
|
376
|
-
plugin.class_eval do
|
377
|
-
def self.after_publish(document)
|
378
|
-
original = document.destination_directory
|
379
|
-
new = File.expand_path "book"
|
380
|
-
FileUtils.mv original, new
|
381
|
-
document.destination = "book"
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
document.publish! :plugins => [plugin]
|
386
|
-
expect(File.exist?("destination")).to be_falsy
|
387
|
-
expect(File.exist?("book")).to be_truthy
|
388
|
-
expect(document.destination_directory).to eq(File.expand_path("book"))
|
389
|
-
end
|
390
|
-
|
391
|
-
it "allows compression of the final output" do
|
392
|
-
require "zip"
|
393
|
-
require "zip/filesystem"
|
394
|
-
|
395
|
-
document = Mint::Document.new "content.md", destination: "destination"
|
396
|
-
plugin.class_eval do
|
397
|
-
def self.after_publish(document)
|
398
|
-
Zip::OutputStream.open("book.zip") do |zos|
|
399
|
-
zos.put_next_entry("chapter-1.html")
|
400
|
-
zos.puts File.read(document.destination_file)
|
401
|
-
end
|
402
|
-
|
403
|
-
FileUtils.mv "book.zip", "book.epub"
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
document.publish! :plugins => [plugin]
|
408
|
-
|
409
|
-
expect(File.exist?("destination")).to be_truthy
|
410
|
-
expect(File.exist?("book.zip")).to be_falsy
|
411
|
-
expect(File.exist?("book.epub")).to be_truthy
|
412
|
-
|
413
|
-
directory_size =
|
414
|
-
Dir["#{document.destination_directory}/**/*"].
|
415
|
-
flatten.
|
416
|
-
map {|file| File.stat(file).size }.
|
417
|
-
reduce(&:+)
|
418
|
-
compressed_size = File.stat("book.epub").size
|
419
|
-
expect(directory_size).to be > compressed_size
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
context "when the style output is a new directory" do
|
424
|
-
it "allows changes to the style directory" do
|
425
|
-
document = Mint::Document.new "content.md", style_destination: "styles"
|
426
|
-
plugin.class_eval do
|
427
|
-
def self.after_publish(document)
|
428
|
-
original = document.style_destination_directory
|
429
|
-
new = File.expand_path "looks"
|
430
|
-
FileUtils.mv original, new
|
431
|
-
document.style_destination = "looks"
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
document.publish! :plugins => [plugin]
|
436
|
-
|
437
|
-
expect(File.exist?("styles")).to be_falsy
|
438
|
-
expect(File.exist?("looks")).to be_truthy
|
439
|
-
expect(document.style_destination_directory).to eq(File.expand_path("looks"))
|
440
|
-
end
|
441
|
-
|
442
|
-
after do
|
443
|
-
FileUtils.rm_r File.expand_path("looks")
|
444
|
-
end
|
445
|
-
end
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
end
|