sitepress-rails 4.0.9 → 4.1.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/lib/sitepress/engine.rb +50 -23
- data/lib/sitepress/model.rb +19 -5
- data/lib/sitepress/models/collection.rb +8 -13
- data/rails/app/controllers/concerns/sitepress/site_pages.rb +3 -4
- data/rails/lib/generators/sitepress/install/install_generator.rb +16 -1
- data/rails/lib/generators/sitepress/install/templates/pages/index.html.erb +1 -1
- data/spec/dummy/log/test.log +6811 -0
- data/spec/sitepress/collection_spec.rb +281 -0
- data/spec/sitepress/model_spec.rb +118 -0
- data/spec/sitepress/sitepress_site_controller_spec.rb +23 -2
- metadata +6 -4
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Sitepress::Models::Collection do
|
|
4
|
+
let(:model_class) { PageModel }
|
|
5
|
+
let(:site) { Sitepress.site }
|
|
6
|
+
let(:collection) do
|
|
7
|
+
Sitepress::Models::Collection.new(model: model_class) do
|
|
8
|
+
site.glob("**/*.html*")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "#initialize" do
|
|
13
|
+
it "accepts a model and resources block" do
|
|
14
|
+
expect(collection).to be_a(Sitepress::Models::Collection)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "stores the model class" do
|
|
18
|
+
expect(collection.model).to eq(model_class)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "#resources" do
|
|
23
|
+
it "returns an array of resources" do
|
|
24
|
+
expect(collection.resources).to be_an(Array)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "returns Sitepress::Resource instances" do
|
|
28
|
+
expect(collection.resources.first).to be_a(Sitepress::Resource)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "calls the block passed to initialize" do
|
|
32
|
+
block_called = false
|
|
33
|
+
test_collection = Sitepress::Models::Collection.new(model: model_class) do
|
|
34
|
+
block_called = true
|
|
35
|
+
site.glob("*.html*")
|
|
36
|
+
end
|
|
37
|
+
test_collection.resources
|
|
38
|
+
expect(block_called).to be true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#each" do
|
|
43
|
+
it "yields model instances, not resources" do
|
|
44
|
+
collection.each do |item|
|
|
45
|
+
expect(item).to be_a(model_class)
|
|
46
|
+
expect(item).not_to be_a(Sitepress::Resource)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "wraps each resource in the model class" do
|
|
51
|
+
resources = collection.resources
|
|
52
|
+
models = []
|
|
53
|
+
collection.each { |model| models << model }
|
|
54
|
+
|
|
55
|
+
expect(models.size).to eq(resources.size)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "returns an enumerator when no block is given" do
|
|
59
|
+
enumerator = collection.each
|
|
60
|
+
expect(enumerator).to be_a(Enumerator)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "can iterate over the enumerator" do
|
|
64
|
+
enumerator = collection.each
|
|
65
|
+
first_item = enumerator.next
|
|
66
|
+
expect(first_item).to be_a(model_class)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "Enumerable methods" do
|
|
71
|
+
describe "#map" do
|
|
72
|
+
it "maps over model instances" do
|
|
73
|
+
paths = collection.map(&:request_path)
|
|
74
|
+
expect(paths).to be_an(Array)
|
|
75
|
+
expect(paths).to all(be_a(String))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "returns results, not models" do
|
|
79
|
+
paths = collection.map(&:request_path)
|
|
80
|
+
expect(paths.first).to be_a(String)
|
|
81
|
+
expect(paths.first).not_to be_a(model_class)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "#select" do
|
|
86
|
+
it "filters model instances" do
|
|
87
|
+
filtered = collection.select { |page| page.request_path.include?("hi") }
|
|
88
|
+
expect(filtered).to be_an(Array)
|
|
89
|
+
expect(filtered).to all(be_a(model_class))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "returns fewer items when filtered" do
|
|
93
|
+
all_count = collection.count
|
|
94
|
+
filtered = collection.select { |page| page.request_path.include?("hi") }
|
|
95
|
+
expect(filtered.size).to be <= all_count
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe "#reject" do
|
|
100
|
+
it "filters out model instances" do
|
|
101
|
+
rejected = collection.reject { |page| page.request_path.include?("hi") }
|
|
102
|
+
expect(rejected).to be_an(Array)
|
|
103
|
+
expect(rejected).to all(be_a(model_class))
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "#find" do
|
|
108
|
+
it "finds a model instance" do
|
|
109
|
+
result = collection.find { |page| page.request_path == "/hi" }
|
|
110
|
+
expect(result).to be_a(model_class)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "returns nil when not found" do
|
|
114
|
+
result = collection.find { |page| page.request_path == "does-not-exist" }
|
|
115
|
+
expect(result).to be_nil
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "#first" do
|
|
120
|
+
it "returns the first model instance" do
|
|
121
|
+
expect(collection.first).to be_a(model_class)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "returns the same as accessing via each" do
|
|
125
|
+
first_via_each = nil
|
|
126
|
+
collection.each { |item| first_via_each = item; break }
|
|
127
|
+
expect(collection.first).to eq(first_via_each)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe "#count" do
|
|
132
|
+
it "returns the number of items" do
|
|
133
|
+
expect(collection.count).to be_a(Integer)
|
|
134
|
+
expect(collection.count).to be > 0
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "matches the resource count" do
|
|
138
|
+
expect(collection.count).to eq(collection.resources.count)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe "#to_a" do
|
|
143
|
+
it "converts to an array of models" do
|
|
144
|
+
array = collection.to_a
|
|
145
|
+
expect(array).to be_an(Array)
|
|
146
|
+
expect(array).to all(be_a(model_class))
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "returns all items" do
|
|
150
|
+
array = collection.to_a
|
|
151
|
+
expect(array.size).to eq(collection.count)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe "#any?" do
|
|
156
|
+
it "returns true when collection has items" do
|
|
157
|
+
expect(collection.any?).to be true
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "can be used with a block" do
|
|
161
|
+
result = collection.any? { |page| page.request_path == "/hi" }
|
|
162
|
+
expect(result).to be true
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "#all?" do
|
|
167
|
+
it "returns true when all items match" do
|
|
168
|
+
result = collection.all? { |page| page.is_a?(model_class) }
|
|
169
|
+
expect(result).to be true
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "returns false when not all items match" do
|
|
173
|
+
result = collection.all? { |page| page.request_path == "/hi" }
|
|
174
|
+
expect(result).to be false
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
describe "#none?" do
|
|
179
|
+
it "returns false when collection has items" do
|
|
180
|
+
result = collection.none? { |page| page.is_a?(model_class) }
|
|
181
|
+
expect(result).to be false
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "returns true when no items match" do
|
|
185
|
+
result = collection.none? { |page| page.request_path == "does-not-exist" }
|
|
186
|
+
expect(result).to be true
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe "chaining" do
|
|
192
|
+
it "supports chaining multiple enumerable methods" do
|
|
193
|
+
result = collection
|
|
194
|
+
.select { |page| page.request_path.length > 0 }
|
|
195
|
+
.map(&:request_path)
|
|
196
|
+
.sort
|
|
197
|
+
|
|
198
|
+
expect(result).to be_an(Array)
|
|
199
|
+
expect(result).to all(be_a(String))
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it "can chain with array methods after to_a" do
|
|
203
|
+
result = collection.to_a.reverse.first
|
|
204
|
+
expect(result).to be_a(model_class)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe "lazy evaluation" do
|
|
209
|
+
it "doesn't call the resources block until enumeration" do
|
|
210
|
+
block_called = false
|
|
211
|
+
lazy_collection = Sitepress::Models::Collection.new(model: model_class) do
|
|
212
|
+
block_called = true
|
|
213
|
+
site.glob("*.html*")
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
expect(block_called).to be false
|
|
217
|
+
lazy_collection.first
|
|
218
|
+
expect(block_called).to be true
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "calls the resources block multiple times if accessed multiple times" do
|
|
222
|
+
call_count = 0
|
|
223
|
+
counting_collection = Sitepress::Models::Collection.new(model: model_class) do
|
|
224
|
+
call_count += 1
|
|
225
|
+
site.glob("*.html*")
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
counting_collection.first
|
|
229
|
+
counting_collection.count
|
|
230
|
+
expect(call_count).to eq(2)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe "with custom model" do
|
|
235
|
+
let(:custom_model) do
|
|
236
|
+
Class.new(Sitepress::Model) do
|
|
237
|
+
def custom_method
|
|
238
|
+
"custom"
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
let(:custom_collection) do
|
|
244
|
+
Sitepress::Models::Collection.new(model: custom_model) do
|
|
245
|
+
site.glob("*.html*")
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it "returns instances of the custom model" do
|
|
250
|
+
expect(custom_collection.first).to be_a(custom_model)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "has access to custom methods" do
|
|
254
|
+
expect(custom_collection.first.custom_method).to eq("custom")
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
describe "with empty results" do
|
|
259
|
+
let(:empty_collection) do
|
|
260
|
+
Sitepress::Models::Collection.new(model: model_class) do
|
|
261
|
+
site.glob("does-not-exist-*.html")
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "returns zero count" do
|
|
266
|
+
expect(empty_collection.count).to eq(0)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it "returns nil for first" do
|
|
270
|
+
expect(empty_collection.first).to be_nil
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "returns empty array for to_a" do
|
|
274
|
+
expect(empty_collection.to_a).to eq([])
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it "returns false for any?" do
|
|
278
|
+
expect(empty_collection.any?).to be false
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
@@ -14,6 +14,9 @@ describe Sitepress::Model do
|
|
|
14
14
|
it "is instances of model" do
|
|
15
15
|
expect(subject.first).to be_instance_of PageModel
|
|
16
16
|
end
|
|
17
|
+
it "returns a Collection" do
|
|
18
|
+
expect(subject).to be_a(Sitepress::Models::Collection)
|
|
19
|
+
end
|
|
17
20
|
end
|
|
18
21
|
describe "#resources" do
|
|
19
22
|
subject { model.all.resources }
|
|
@@ -53,4 +56,119 @@ describe Sitepress::Model do
|
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
end
|
|
59
|
+
|
|
60
|
+
describe ".collection" do
|
|
61
|
+
context "with block (new style)" do
|
|
62
|
+
it "returns a Collection directly" do
|
|
63
|
+
test_model = Class.new(Sitepress::Model)
|
|
64
|
+
result = test_model.collection(:custom_pages) { test_model.site.glob("*.html*") }
|
|
65
|
+
expect(result).to be_a(Sitepress::Models::Collection)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "returns model instances from the collection" do
|
|
69
|
+
test_model = Class.new(Sitepress::Model)
|
|
70
|
+
result = test_model.collection { test_model.site.glob("*.html*") }
|
|
71
|
+
expect(result.first).to be_a(test_model)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "can be chained with enumerable methods" do
|
|
75
|
+
test_model = Class.new(Sitepress::Model)
|
|
76
|
+
result = test_model.collection { test_model.site.glob("*.html*") }
|
|
77
|
+
paths = result.map(&:request_path)
|
|
78
|
+
expect(paths).to be_an(Array)
|
|
79
|
+
expect(paths).to all(be_a(String))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "without block (deprecated style)" do
|
|
84
|
+
let(:test_model) do
|
|
85
|
+
Class.new(Sitepress::Model) do
|
|
86
|
+
collection :deprecated_pages, glob: "*.html*"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "defines the collection method" do
|
|
91
|
+
expect(test_model).to respond_to(:deprecated_pages)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "shows deprecation warning" do
|
|
95
|
+
expect(ActiveSupport::Deprecation).to receive(:new).and_call_original
|
|
96
|
+
test_model.deprecated_pages
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "still returns a Collection" do
|
|
100
|
+
expect(test_model.deprecated_pages).to be_a(Sitepress::Models::Collection)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "still returns model instances" do
|
|
104
|
+
expect(test_model.deprecated_pages.first).to be_a(test_model)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe ".glob" do
|
|
110
|
+
it "returns a Collection" do
|
|
111
|
+
expect(model.glob("*.html*")).to be_a(Sitepress::Models::Collection)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "returns model instances" do
|
|
115
|
+
result = model.glob("*.html*")
|
|
116
|
+
expect(result.first).to be_a(PageModel)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "filters resources by glob pattern" do
|
|
120
|
+
result = model.glob("hi.html")
|
|
121
|
+
expect(result.count).to eql 1
|
|
122
|
+
expect(result.first.request_path).to eql "/hi"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "chaining" do
|
|
127
|
+
it "supports standard enumerable methods" do
|
|
128
|
+
result = model.all.select { |page| page.request_path.include?("hi") }
|
|
129
|
+
expect(result).to be_an(Array)
|
|
130
|
+
expect(result).to all(be_a(PageModel))
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "supports map" do
|
|
134
|
+
paths = model.all.map(&:request_path)
|
|
135
|
+
expect(paths).to be_an(Array)
|
|
136
|
+
expect(paths).to all(be_a(String))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "supports each" do
|
|
140
|
+
count = 0
|
|
141
|
+
model.all.each { |page| count += 1 }
|
|
142
|
+
expect(count).to eql 3
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "supports first" do
|
|
146
|
+
expect(model.all.first).to be_a(PageModel)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "supports count" do
|
|
150
|
+
expect(model.all.count).to be_a(Integer)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "can convert to array" do
|
|
154
|
+
array = model.all.to_a
|
|
155
|
+
expect(array).to be_an(Array)
|
|
156
|
+
expect(array).to all(be_a(PageModel))
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
describe "model equality" do
|
|
161
|
+
it "considers models equal if they have the same page and class" do
|
|
162
|
+
page1 = model.first
|
|
163
|
+
page2 = model.get(page1.request_path)
|
|
164
|
+
expect(page1).to eq(page2)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "considers models unequal if they have different pages" do
|
|
168
|
+
pages = model.all.to_a
|
|
169
|
+
if pages.size >= 2
|
|
170
|
+
expect(pages[0]).not_to eq(pages[1])
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
56
174
|
end
|
|
@@ -70,8 +70,29 @@ describe Sitepress::SiteController, type: :controller do
|
|
|
70
70
|
context "helper_paths" do
|
|
71
71
|
subject{ Sitepress::SiteController.helpers_path }
|
|
72
72
|
it { is_expected.to include(site.helpers_path.to_s) }
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
|
|
74
|
+
it "adds helpers_path to Rails autoload_paths" do
|
|
75
|
+
expect(Rails.application.config.autoload_paths).to include(site.helpers_path)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "adds helpers_path to Rails eager_load_paths" do
|
|
79
|
+
expect(Rails.application.config.eager_load_paths).to include(site.helpers_path)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "makes helpers autoloadable" do
|
|
83
|
+
# SampleHelper is defined in app/content/helpers/sample_helper.rb
|
|
84
|
+
expect { SampleHelper }.not_to raise_error
|
|
85
|
+
expect(SampleHelper).to be_a(Module)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "model_paths" do
|
|
90
|
+
it "adds models_path to Rails autoload_paths" do
|
|
91
|
+
expect(Rails.application.config.autoload_paths).to include(site.models_path)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "adds models_path to Rails eager_load_paths" do
|
|
95
|
+
expect(Rails.application.config.eager_load_paths).to include(site.models_path)
|
|
75
96
|
end
|
|
76
97
|
end
|
|
77
98
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sitepress-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0
|
|
4
|
+
version: 4.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brad Gessler
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-
|
|
10
|
+
date: 2025-11-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rspec-rails
|
|
@@ -57,14 +57,14 @@ dependencies:
|
|
|
57
57
|
requirements:
|
|
58
58
|
- - '='
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 4.0
|
|
60
|
+
version: 4.1.0
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - '='
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 4.0
|
|
67
|
+
version: 4.1.0
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: railties
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -205,6 +205,7 @@ files:
|
|
|
205
205
|
- spec/dummy/public/favicon.ico
|
|
206
206
|
- spec/dummy/tmp/local_secret.txt
|
|
207
207
|
- spec/sitepress-rails_spec.rb
|
|
208
|
+
- spec/sitepress/collection_spec.rb
|
|
208
209
|
- spec/sitepress/compiler_spec.rb
|
|
209
210
|
- spec/sitepress/model_spec.rb
|
|
210
211
|
- spec/sitepress/rails_configuration_spec.rb
|
|
@@ -302,6 +303,7 @@ test_files:
|
|
|
302
303
|
- spec/dummy/public/apple-touch-icon.png
|
|
303
304
|
- spec/dummy/public/favicon.ico
|
|
304
305
|
- spec/dummy/tmp/local_secret.txt
|
|
306
|
+
- spec/sitepress/collection_spec.rb
|
|
305
307
|
- spec/sitepress/compiler_spec.rb
|
|
306
308
|
- spec/sitepress/model_spec.rb
|
|
307
309
|
- spec/sitepress/rails_configuration_spec.rb
|