impression 0.11 → 0.12
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/CHANGELOG.md +4 -0
- data/Gemfile +0 -5
- data/Gemfile.lock +7 -7
- data/README.md +78 -8
- data/impression.gemspec +2 -2
- data/lib/impression/app.rb +271 -3
- data/lib/impression/file_tree.rb +4 -2
- data/lib/impression/rack_app.rb +27 -0
- data/lib/impression/version.rb +1 -1
- data/lib/impression.rb +23 -11
- data/test/{jamstack → app}/_layouts/article.rb +0 -0
- data/test/{jamstack → app}/_layouts/default.rb +0 -0
- data/test/{jamstack → app}/articles/2008-06-14-manu.md +0 -0
- data/test/{jamstack → app}/articles/2009-06-12-noatche.md +0 -0
- data/test/{jamstack → app}/articles/a.md +0 -0
- data/test/{jamstack → app}/assets/js/a.js +0 -0
- data/test/{jamstack → app}/bar.html +0 -0
- data/test/{jamstack → app}/baz/index.md +0 -0
- data/test/{jamstack → app}/foo.rb +0 -0
- data/test/{jamstack → app}/foobar.rb +0 -0
- data/test/{jamstack → app}/index.md +0 -0
- data/test/{jamstack → app}/resources/greeter.rb +0 -0
- data/test/{jamstack → app}/resources/recurse.rb +1 -1
- data/test/test_app.rb +349 -6
- data/test/test_file_tree.rb +18 -0
- data/test/test_impression.rb +3 -3
- data/test/test_rack_app.rb +48 -0
- metadata +21 -21
- data/lib/impression/jamstack.rb +0 -276
- data/test/test_jamstack.rb +0 -350
data/lib/impression/jamstack.rb
DELETED
@@ -1,276 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'fileutils'
|
4
|
-
require 'date'
|
5
|
-
require 'yaml'
|
6
|
-
require 'modulation'
|
7
|
-
require 'papercraft'
|
8
|
-
|
9
|
-
require_relative './resource'
|
10
|
-
require_relative './file_tree'
|
11
|
-
|
12
|
-
module Impression
|
13
|
-
|
14
|
-
# `Jamstack` implements a resource that maps to a Jamstack app directory.
|
15
|
-
class Jamstack < FileTree
|
16
|
-
def initialize(**props)
|
17
|
-
super
|
18
|
-
@layouts = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
# Returns a list of pages found in the given directory (relative to the base
|
22
|
-
# directory). Each entry containins the absolute file path, the pretty URL,
|
23
|
-
# the possible date parsed from the file name, and any other front matter
|
24
|
-
# attributes (for .md files). This method will detect only pages with the
|
25
|
-
# extensions .html, .md, .rb. The returned entries are sorted by file path.
|
26
|
-
#
|
27
|
-
# @param dir [String] relative directory
|
28
|
-
# @return [Array<Hash>] array of page entries
|
29
|
-
def page_list(dir)
|
30
|
-
base = File.join(@directory, dir)
|
31
|
-
Dir.glob('*.{html,md}', base: base)
|
32
|
-
.map { |fn| get_path_info(File.join(dir, fn)) }# page_entry(fn, dir) }
|
33
|
-
.sort_by { |i| i[:path] }
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
DATE_REGEXP = /(\d{4}\-\d{2}\-\d{2})/.freeze
|
39
|
-
FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m.freeze
|
40
|
-
MD_EXT_REGEXP = /\.md$/.freeze
|
41
|
-
PAGE_EXT_REGEXP = /^(.+)\.(md|html|rb)$/.freeze
|
42
|
-
INDEX_PAGE_REGEXP = /^(.+)?\/index$/.freeze
|
43
|
-
|
44
|
-
YAML_OPTS = {
|
45
|
-
permitted_classes: [Date],
|
46
|
-
symbolize_names: true
|
47
|
-
}.freeze
|
48
|
-
|
49
|
-
# Returns the path info for the given file path.
|
50
|
-
#
|
51
|
-
# @param path [String] file path
|
52
|
-
# @return [Hash] path info
|
53
|
-
def file_info(path)
|
54
|
-
info = super
|
55
|
-
case info[:ext]
|
56
|
-
when '.md'
|
57
|
-
atts, content = parse_markdown_file(path)
|
58
|
-
info = info.merge(atts)
|
59
|
-
info[:html_content] = Papercraft.markdown(content)
|
60
|
-
info[:kind] = :markdown
|
61
|
-
when '.rb'
|
62
|
-
info[:module] = import(path)
|
63
|
-
info[:kind] = :module
|
64
|
-
end
|
65
|
-
if (m = path.match(DATE_REGEXP))
|
66
|
-
info[:date] ||= Date.parse(m[1])
|
67
|
-
end
|
68
|
-
|
69
|
-
info
|
70
|
-
end
|
71
|
-
|
72
|
-
# Returns the pretty URL for the given relative path. For pages, the
|
73
|
-
# extension is removed. For index pages, the index suffix is removed.
|
74
|
-
#
|
75
|
-
# @param relative_path [String] relative path
|
76
|
-
# @return [String] pretty URL
|
77
|
-
def pretty_url(relative_path)
|
78
|
-
if (m = relative_path.match(PAGE_EXT_REGEXP))
|
79
|
-
relative_path = m[1]
|
80
|
-
end
|
81
|
-
if (m = relative_path.match(INDEX_PAGE_REGEXP))
|
82
|
-
relative_path = m[1] || '/'
|
83
|
-
end
|
84
|
-
relative_path == '/' ? absolute_path : File.join(absolute_path, relative_path)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Renders a response according to the given path info.
|
88
|
-
#
|
89
|
-
# @param req [Qeweney::Request] request
|
90
|
-
# @param path_info [Hash] path info
|
91
|
-
# @return [void]
|
92
|
-
def render_from_path_info(req, path_info)
|
93
|
-
case (kind = path_info[:kind])
|
94
|
-
when :not_found
|
95
|
-
mod_path_info = up_tree_resource_module_path_info(req, path_info)
|
96
|
-
if mod_path_info
|
97
|
-
render_module(req, mod_path_info)
|
98
|
-
else
|
99
|
-
req.respond(nil, ':status' => Qeweney::Status::NOT_FOUND)
|
100
|
-
end
|
101
|
-
when :module
|
102
|
-
render_module(req, path_info)
|
103
|
-
when :markdown
|
104
|
-
render_markdown_file(req, path_info)
|
105
|
-
when :file
|
106
|
-
render_file(req, path_info)
|
107
|
-
else
|
108
|
-
raise "Invalid path info kind #{kind.inspect}"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Returns the path info for an up-tree resource module, or false if not
|
113
|
-
# found. the :up_tree_resource_module_path_info KV can be either:
|
114
|
-
# - nil (default): up tree module search has not been performed.
|
115
|
-
# - false: no up tree module was found.
|
116
|
-
# - module path info: up tree module info (subsequent requests will be
|
117
|
-
# directly routed to the module).
|
118
|
-
#
|
119
|
-
# @param req [Qeweney::Request] request
|
120
|
-
# @param path_info [Hash] path info
|
121
|
-
# @return [Hash, false] up-tree resource module path info
|
122
|
-
def up_tree_resource_module_path_info(req, path_info)
|
123
|
-
if path_info[:up_tree_resource_module_path_info].nil?
|
124
|
-
if (mod_path_info = find_up_tree_resource_module(req, path_info))
|
125
|
-
path_info[:up_tree_resource_module_path_info] = mod_path_info
|
126
|
-
return mod_path_info;
|
127
|
-
else
|
128
|
-
path_info[:up_tree_resource_module_path_info] = false
|
129
|
-
return false
|
130
|
-
end
|
131
|
-
end
|
132
|
-
path_info[:up_tree_resource_module_path_info]
|
133
|
-
end
|
134
|
-
|
135
|
-
# Performs a recursive search for an up-tree resource module from the given
|
136
|
-
# path info. If a resource module is found up the tree, its path_info is
|
137
|
-
# returned, otherwise returns nil.
|
138
|
-
#
|
139
|
-
# @param req [Qeweney::Request] request
|
140
|
-
# @param path_info [Hash] path info
|
141
|
-
# @return [Hash, nil] up-tree resource module path info
|
142
|
-
def find_up_tree_resource_module(req, path_info)
|
143
|
-
relative_path = req.resource_relative_path
|
144
|
-
|
145
|
-
while relative_path != path
|
146
|
-
up_tree_path = File.expand_path('..', relative_path)
|
147
|
-
up_tree_path_info = get_path_info(up_tree_path)
|
148
|
-
|
149
|
-
case up_tree_path_info[:kind]
|
150
|
-
when :not_found
|
151
|
-
relative_path = up_tree_path
|
152
|
-
next
|
153
|
-
when :module
|
154
|
-
return up_tree_path_info
|
155
|
-
else
|
156
|
-
return nil
|
157
|
-
end
|
158
|
-
end
|
159
|
-
nil
|
160
|
-
end
|
161
|
-
|
162
|
-
# Renders a file response for the given request and the given path info,
|
163
|
-
# according to the file type.
|
164
|
-
#
|
165
|
-
# @param req [Qeweney::Request] request
|
166
|
-
# @param path_info [Hash] path info
|
167
|
-
# @return [void]
|
168
|
-
# def render_file(req, path_info)
|
169
|
-
# case path_info[:kind]
|
170
|
-
# else
|
171
|
-
# req.serve_file(path_info[:path])
|
172
|
-
# end
|
173
|
-
# end
|
174
|
-
|
175
|
-
# Renders a module. If the module is a Resource, it is mounted, and then the
|
176
|
-
# request is rerouted from the new resource and rendered. If the module is a
|
177
|
-
# Proc or a Papercraft::Template, it is rendered as such. Otherwise, an
|
178
|
-
# error is raised.
|
179
|
-
#
|
180
|
-
# @param req [Qeweney::Request] request
|
181
|
-
# @param path_info [Hash] path info
|
182
|
-
# @return [void]
|
183
|
-
def render_module(req, path_info)
|
184
|
-
# p render_module: path_info
|
185
|
-
case (mod = path_info[:module])
|
186
|
-
when Module
|
187
|
-
resource = mod.resource
|
188
|
-
resource.remount(self, path_info[:url])
|
189
|
-
# p path_info_url: path_info[:url], relative_path: req.resource_relative_path
|
190
|
-
relative_url = path_info[:url].gsub(/^#{path}/, '')
|
191
|
-
# p relative_url: relative_url
|
192
|
-
req.recalc_resource_relative_path(relative_url)
|
193
|
-
# p resource_relative_path: req.resource_relative_path
|
194
|
-
resource.route(req).call(req)
|
195
|
-
when Impression::Resource
|
196
|
-
mod.remount(self, path_info[:url])
|
197
|
-
req.recalc_resource_relative_path(path_info[:url])
|
198
|
-
mod.route(req).call(req)
|
199
|
-
when Proc, Papercraft::Template
|
200
|
-
render_papercraft_module(req, mod)
|
201
|
-
else
|
202
|
-
raise "Unsupported module type #{mod.class}"
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# Renders a Papercraft module.
|
207
|
-
#
|
208
|
-
# @param mod [Module] Papercraft module
|
209
|
-
# @param path_info [Hash] path info
|
210
|
-
# @return [void]
|
211
|
-
def render_papercraft_module(req, mod)
|
212
|
-
template = Papercraft.html(mod)
|
213
|
-
body = template.render(request: req, resource: self)
|
214
|
-
req.respond(body, 'Content-Type' => template.mime_type)
|
215
|
-
end
|
216
|
-
|
217
|
-
# Renders a markdown file using a layout.
|
218
|
-
#
|
219
|
-
# @param req [Qeweney::Request] reqest
|
220
|
-
# @param path_info [Hash] path info
|
221
|
-
# @return [void]
|
222
|
-
def render_markdown_file(req, path_info)
|
223
|
-
layout = get_layout(path_info[:layout])
|
224
|
-
|
225
|
-
html = layout.render(request: req, resource: self, **path_info) {
|
226
|
-
emit path_info[:html_content]
|
227
|
-
}
|
228
|
-
req.respond(html, 'Content-Type' => layout.mime_type)
|
229
|
-
end
|
230
|
-
|
231
|
-
# Returns a layout component based on the given name. The given name
|
232
|
-
# defaults to 'default' if nil.
|
233
|
-
#
|
234
|
-
# @param layout [String, nil] layout name
|
235
|
-
# @return [Papercraft::Template] layout component
|
236
|
-
def get_layout(layout)
|
237
|
-
layout ||= 'default'
|
238
|
-
path = File.join(@directory, "_layouts/#{layout}.rb")
|
239
|
-
raise "Layout not found #{path}" unless File.file?(path)
|
240
|
-
|
241
|
-
import path
|
242
|
-
end
|
243
|
-
|
244
|
-
# Parses the markdown file at the given path.
|
245
|
-
#
|
246
|
-
# @param path [String] file path
|
247
|
-
# @return [Array] an tuple containing properties<Hash>, contents<String>
|
248
|
-
def parse_markdown_file(path)
|
249
|
-
content = IO.read(path) || ''
|
250
|
-
atts = {}
|
251
|
-
|
252
|
-
# Parse date from file name
|
253
|
-
if (m = path.match(DATE_REGEXP))
|
254
|
-
atts[:date] ||= Date.parse(m[1])
|
255
|
-
end
|
256
|
-
|
257
|
-
if (m = content.match(FRONT_MATTER_REGEXP))
|
258
|
-
front_matter = m[1]
|
259
|
-
content = m.post_match
|
260
|
-
|
261
|
-
yaml = YAML.safe_load(front_matter, **YAML_OPTS)
|
262
|
-
atts = atts.merge(yaml)
|
263
|
-
end
|
264
|
-
|
265
|
-
[atts, content]
|
266
|
-
end
|
267
|
-
|
268
|
-
# Returns the supported path extensions used for searching for files based
|
269
|
-
# on pretty URLs.
|
270
|
-
#
|
271
|
-
# @return [Array] list of supported path extensions
|
272
|
-
def supported_path_extensions
|
273
|
-
[:html, :rb, :md]
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
data/test/test_jamstack.rb
DELETED
@@ -1,350 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'helper'
|
4
|
-
require 'qeweney/test_adapter'
|
5
|
-
|
6
|
-
class JamstackTest < MiniTest::Test
|
7
|
-
JAMSTACK_PATH = File.join(__dir__, 'jamstack')
|
8
|
-
|
9
|
-
def setup
|
10
|
-
@jamstack = Impression::Jamstack.new(path: '/', directory: JAMSTACK_PATH)
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_jamstack_routing
|
14
|
-
req = mock_req(':method' => 'GET', ':path' => '/')
|
15
|
-
assert_equal @jamstack, @jamstack.route(req)
|
16
|
-
|
17
|
-
req = mock_req(':method' => 'GET', ':path' => '/nonexistent')
|
18
|
-
assert_equal @jamstack, @jamstack.route(req)
|
19
|
-
|
20
|
-
req = mock_req(':method' => 'GET', ':path' => '/index.html')
|
21
|
-
assert_equal @jamstack, @jamstack.route(req)
|
22
|
-
|
23
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo')
|
24
|
-
assert_equal @jamstack, @jamstack.route(req)
|
25
|
-
end
|
26
|
-
|
27
|
-
def static(path)
|
28
|
-
IO.read(File.join(JAMSTACK_PATH, path))
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_jamstack_response
|
32
|
-
req = mock_req(':method' => 'GET', ':path' => '/roo')
|
33
|
-
@jamstack.route_and_call(req)
|
34
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
35
|
-
|
36
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo2')
|
37
|
-
@jamstack.route_and_call(req)
|
38
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
39
|
-
|
40
|
-
req = mock_req(':method' => 'GET', ':path' => '/bar2')
|
41
|
-
@jamstack.route_and_call(req)
|
42
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
43
|
-
|
44
|
-
req = mock_req(':method' => 'GET', ':path' => '/assets/js/a.js')
|
45
|
-
@jamstack.route_and_call(req)
|
46
|
-
assert_response static('assets/js/a.js'), :js, req
|
47
|
-
|
48
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo')
|
49
|
-
@jamstack.route_and_call(req)
|
50
|
-
|
51
|
-
foo = Papercraft.html {
|
52
|
-
html5 {
|
53
|
-
head {
|
54
|
-
title 'Foo title'
|
55
|
-
}
|
56
|
-
body {
|
57
|
-
h1 'foo'
|
58
|
-
}
|
59
|
-
}
|
60
|
-
}
|
61
|
-
assert_response foo.render, :html, req
|
62
|
-
|
63
|
-
req = mock_req(':method' => 'GET', ':path' => '/index')
|
64
|
-
@jamstack.route_and_call(req)
|
65
|
-
|
66
|
-
index = Papercraft.html {
|
67
|
-
html5 {
|
68
|
-
head {
|
69
|
-
title 'Hello'
|
70
|
-
}
|
71
|
-
body {
|
72
|
-
h1 'Index'
|
73
|
-
}
|
74
|
-
}
|
75
|
-
}
|
76
|
-
assert_response index.render, :html, req
|
77
|
-
|
78
|
-
req = mock_req(':method' => 'GET', ':path' => '/')
|
79
|
-
@jamstack.route_and_call(req)
|
80
|
-
assert_response index.render, :html, req
|
81
|
-
|
82
|
-
req = mock_req(':method' => 'GET', ':path' => '/bar')
|
83
|
-
@jamstack.route_and_call(req)
|
84
|
-
assert_response static('bar.html'), :html, req
|
85
|
-
|
86
|
-
req = mock_req(':method' => 'GET', ':path' => '/baz')
|
87
|
-
@jamstack.route_and_call(req)
|
88
|
-
|
89
|
-
baz_index = Papercraft.html {
|
90
|
-
html5 {
|
91
|
-
head {
|
92
|
-
title 'BarBar'
|
93
|
-
}
|
94
|
-
body {
|
95
|
-
h1 'BarIndex'
|
96
|
-
}
|
97
|
-
}
|
98
|
-
}
|
99
|
-
assert_response baz_index.render, :html, req
|
100
|
-
|
101
|
-
req = mock_req(':method' => 'GET', ':path' => '/articles/a')
|
102
|
-
@jamstack.route_and_call(req)
|
103
|
-
|
104
|
-
a = Papercraft.html {
|
105
|
-
html5 {
|
106
|
-
head {
|
107
|
-
title 'AAA'
|
108
|
-
}
|
109
|
-
body {
|
110
|
-
article {
|
111
|
-
h2 'ZZZ', id: 'zzz'
|
112
|
-
}
|
113
|
-
}
|
114
|
-
}
|
115
|
-
}
|
116
|
-
assert_response a.render, :html, req
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_non_root_jamstack_response
|
120
|
-
@jamstack = Impression::Jamstack.new(path: '/app', directory: JAMSTACK_PATH)
|
121
|
-
|
122
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/roo')
|
123
|
-
@jamstack.route_and_call(req)
|
124
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
125
|
-
|
126
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/foo2')
|
127
|
-
@jamstack.route_and_call(req)
|
128
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
129
|
-
|
130
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/bar2')
|
131
|
-
@jamstack.route_and_call(req)
|
132
|
-
assert_equal Qeweney::Status::NOT_FOUND, req.response_status
|
133
|
-
|
134
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/assets/js/a.js')
|
135
|
-
@jamstack.route_and_call(req)
|
136
|
-
assert_response static('assets/js/a.js'), :js, req
|
137
|
-
|
138
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/foo')
|
139
|
-
@jamstack.route_and_call(req)
|
140
|
-
|
141
|
-
foo = Papercraft.html {
|
142
|
-
html5 {
|
143
|
-
head {
|
144
|
-
title 'Foo title'
|
145
|
-
}
|
146
|
-
body {
|
147
|
-
h1 'foo'
|
148
|
-
}
|
149
|
-
}
|
150
|
-
}
|
151
|
-
assert_response foo.render, :html, req
|
152
|
-
|
153
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/index')
|
154
|
-
@jamstack.route_and_call(req)
|
155
|
-
|
156
|
-
index = Papercraft.html {
|
157
|
-
html5 {
|
158
|
-
head {
|
159
|
-
title 'Hello'
|
160
|
-
}
|
161
|
-
body {
|
162
|
-
h1 'Index'
|
163
|
-
}
|
164
|
-
}
|
165
|
-
}
|
166
|
-
assert_response index.render, :html, req
|
167
|
-
|
168
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/')
|
169
|
-
@jamstack.route_and_call(req)
|
170
|
-
assert_response index.render, :html, req
|
171
|
-
|
172
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/bar')
|
173
|
-
@jamstack.route_and_call(req)
|
174
|
-
assert_response static('bar.html'), :html, req
|
175
|
-
|
176
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/baz')
|
177
|
-
@jamstack.route_and_call(req)
|
178
|
-
|
179
|
-
baz_index = Papercraft.html {
|
180
|
-
html5 {
|
181
|
-
head {
|
182
|
-
title 'BarBar'
|
183
|
-
}
|
184
|
-
body {
|
185
|
-
h1 'BarIndex'
|
186
|
-
}
|
187
|
-
}
|
188
|
-
}
|
189
|
-
assert_response baz_index.render, :html, req
|
190
|
-
|
191
|
-
req = mock_req(':method' => 'GET', ':path' => '/app/articles/a')
|
192
|
-
@jamstack.route_and_call(req)
|
193
|
-
|
194
|
-
a = Papercraft.html {
|
195
|
-
html5 {
|
196
|
-
head {
|
197
|
-
title 'AAA'
|
198
|
-
}
|
199
|
-
body {
|
200
|
-
article {
|
201
|
-
h2 'ZZZ', id: 'zzz'
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
}
|
206
|
-
assert_response a.render, :html, req
|
207
|
-
end
|
208
|
-
|
209
|
-
def test_page_list
|
210
|
-
@jamstack = Impression::Jamstack.new(path: '/app', directory: JAMSTACK_PATH)
|
211
|
-
|
212
|
-
list = @jamstack.page_list('/')
|
213
|
-
assert_equal [
|
214
|
-
{ kind: :file, path: File.join(JAMSTACK_PATH, 'bar.html'), ext: '.html', url: '/app/bar' },
|
215
|
-
{ kind: :markdown, path: File.join(JAMSTACK_PATH, 'index.md'), ext: '.md', url: '/app',
|
216
|
-
title: 'Hello', foo: 'BarBar', html_content: "<h1>Index</h1>\n" },
|
217
|
-
], list
|
218
|
-
|
219
|
-
|
220
|
-
list = @jamstack.page_list('/articles')
|
221
|
-
|
222
|
-
assert_equal [
|
223
|
-
{
|
224
|
-
kind: :markdown,
|
225
|
-
path: File.join(JAMSTACK_PATH, 'articles/2008-06-14-manu.md'),
|
226
|
-
url: '/app/articles/2008-06-14-manu',
|
227
|
-
ext: '.md',
|
228
|
-
title: 'MMM',
|
229
|
-
layout: 'article',
|
230
|
-
foo: {
|
231
|
-
bar: {
|
232
|
-
baz: 42
|
233
|
-
}
|
234
|
-
},
|
235
|
-
html_content: "<h2 id=\"bbb\">BBB</h2>\n",
|
236
|
-
date: Date.new(2008, 06, 14)
|
237
|
-
},
|
238
|
-
{
|
239
|
-
kind: :markdown,
|
240
|
-
path: File.join(JAMSTACK_PATH, 'articles/2009-06-12-noatche.md'),
|
241
|
-
url: '/app/articles/2009-06-12-noatche',
|
242
|
-
ext: '.md',
|
243
|
-
title: 'NNN',
|
244
|
-
layout: 'article',
|
245
|
-
html_content: "<h2 id=\"ccc\">CCC</h2>\n",
|
246
|
-
date: Date.new(2009, 06, 12)
|
247
|
-
},
|
248
|
-
{
|
249
|
-
kind: :markdown,
|
250
|
-
path: File.join(JAMSTACK_PATH, 'articles/a.md'),
|
251
|
-
url: '/app/articles/a',
|
252
|
-
ext: '.md',
|
253
|
-
title: 'AAA',
|
254
|
-
layout: 'article',
|
255
|
-
html_content: "<h2 id=\"zzz\">ZZZ</h2>\n",
|
256
|
-
},
|
257
|
-
], list
|
258
|
-
end
|
259
|
-
|
260
|
-
def test_template_resource_and_request
|
261
|
-
req = mock_req(':method' => 'GET', ':path' => '/foobar?q=42')
|
262
|
-
@jamstack.route_and_call(req)
|
263
|
-
|
264
|
-
foo = Papercraft.html {
|
265
|
-
html5 {
|
266
|
-
head {
|
267
|
-
title 'Foobar'
|
268
|
-
}
|
269
|
-
body {
|
270
|
-
h1 '42'
|
271
|
-
a 'MMM', href: '/articles/2008-06-14-manu'
|
272
|
-
a 'NNN', href: '/articles/2009-06-12-noatche'
|
273
|
-
a 'AAA', href: '/articles/a'
|
274
|
-
}
|
275
|
-
}
|
276
|
-
}
|
277
|
-
assert_response foo.render, :html, req
|
278
|
-
end
|
279
|
-
|
280
|
-
def path_info(path)
|
281
|
-
@jamstack.send(:get_path_info, path)
|
282
|
-
end
|
283
|
-
|
284
|
-
def test_path_info
|
285
|
-
assert_equal({
|
286
|
-
kind: :markdown,
|
287
|
-
path: File.join(JAMSTACK_PATH, 'index.md'),
|
288
|
-
ext: '.md',
|
289
|
-
url: '/',
|
290
|
-
title: 'Hello',
|
291
|
-
foo: 'BarBar',
|
292
|
-
html_content: "<h1>Index</h1>\n"
|
293
|
-
}, path_info('/index'))
|
294
|
-
|
295
|
-
assert_equal({
|
296
|
-
kind: :markdown,
|
297
|
-
path: File.join(JAMSTACK_PATH, 'index.md'),
|
298
|
-
ext: '.md',
|
299
|
-
url: '/',
|
300
|
-
title: 'Hello',
|
301
|
-
foo: 'BarBar',
|
302
|
-
html_content: "<h1>Index</h1>\n"
|
303
|
-
}, path_info('/'))
|
304
|
-
|
305
|
-
assert_equal({
|
306
|
-
kind: :file,
|
307
|
-
path: File.join(JAMSTACK_PATH, 'assets/js/a.js'),
|
308
|
-
ext: '.js',
|
309
|
-
url: '/assets/js/a.js'
|
310
|
-
}, path_info('/assets/js/a.js'))
|
311
|
-
|
312
|
-
assert_equal({
|
313
|
-
kind: :not_found,
|
314
|
-
}, path_info('/js/b.js'))
|
315
|
-
end
|
316
|
-
|
317
|
-
def test_resource_loading
|
318
|
-
req = mock_req(':method' => 'GET', ':path' => '/resources/greeter?name=world')
|
319
|
-
route = @jamstack.route(req)
|
320
|
-
assert_equal @jamstack, route
|
321
|
-
|
322
|
-
req = mock_req(':method' => 'GET', ':path' => '/resources/greeter?name=world')
|
323
|
-
@jamstack.route_and_call(req)
|
324
|
-
assert_response 'Hello, world!', :text, req
|
325
|
-
|
326
|
-
req = mock_req(':method' => 'GET', ':path' => '/resources/recurse/resources/greeter?name=foo')
|
327
|
-
@jamstack.route_and_call(req)
|
328
|
-
assert_response 'Hello, foo!', :text, req
|
329
|
-
end
|
330
|
-
|
331
|
-
def test_recursive_resource_loading_on_non_root_jamstack
|
332
|
-
jamstack = Impression::Jamstack.new(path: '/foo/bar', directory: JAMSTACK_PATH)
|
333
|
-
|
334
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo/bar/resources/greeter?name=world')
|
335
|
-
route = jamstack.route(req)
|
336
|
-
assert_equal jamstack, route
|
337
|
-
|
338
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo/bar/resources/greeter?name=world')
|
339
|
-
jamstack.route_and_call(req)
|
340
|
-
assert_response 'Hello, world!', :text, req
|
341
|
-
|
342
|
-
req = mock_req(':method' => 'GET', ':path' => '/foo/bar/resources/recurse/resources/greeter?name=foo')
|
343
|
-
jamstack.route_and_call(req)
|
344
|
-
assert_response 'Hello, foo!', :text, req
|
345
|
-
|
346
|
-
# req = mock_req(':method' => 'GET', ':path' => '/foo/bar/resources/recurse/bar')
|
347
|
-
# @jamstack.route_and_call(req)
|
348
|
-
# assert_response static('bar.html'), :html, req
|
349
|
-
end
|
350
|
-
end
|