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.
@@ -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
- it "has site#helper_paths in ActiveSupport::Dependencies.autoload_paths" do
74
- expect(ActiveSupport::Dependencies.autoload_paths).to include(site.helpers_path.to_s)
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.9
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-11 00:00:00.000000000 Z
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.9
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.9
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