dugway 1.2.0 → 1.3.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/.github/workflows/main.yml +1 -1
- data/README.md +32 -7
- data/dugway.gemspec +11 -9
- data/lib/dugway/cli/server.rb +67 -7
- data/lib/dugway/liquid/drops/artists_drop.rb +12 -0
- data/lib/dugway/liquid/drops/base_drop.rb +27 -2
- data/lib/dugway/liquid/drops/categories_drop.rb +12 -0
- data/lib/dugway/liquid/drops/pages_drop.rb +30 -2
- data/lib/dugway/liquid/drops/product_drop.rb +11 -0
- data/lib/dugway/liquid/drops/products_drop.rb +39 -0
- data/lib/dugway/liquid/drops/theme_drop.rb +29 -6
- data/lib/dugway/liquid/filters/core_filters.rb +169 -7
- data/lib/dugway/liquid/filters/font_filters.rb +1 -0
- data/lib/dugway/liquid/filters/util_filters.rb +1 -10
- data/lib/dugway/liquid/tags/get.rb +6 -6
- data/lib/dugway/liquid/tags/paginate.rb +61 -11
- data/lib/dugway/store.rb +39 -1
- data/lib/dugway/theme.rb +72 -33
- data/lib/dugway/version.rb +1 -1
- data/lib/dugway.rb +24 -1
- data/locales/storefront.de.yml +2 -0
- data/locales/storefront.en-CA.yml +2 -0
- data/locales/storefront.en-GB.yml +2 -0
- data/locales/storefront.en-US.yml +2 -0
- data/locales/storefront.es-ES.yml +2 -0
- data/locales/storefront.es-MX.yml +2 -0
- data/locales/storefront.fr-CA.yml +2 -0
- data/locales/storefront.fr-FR.yml +2 -0
- data/locales/storefront.id.yml +2 -0
- data/locales/storefront.it.yml +2 -0
- data/locales/storefront.ja.yml +2 -0
- data/locales/storefront.ko.yml +2 -0
- data/locales/storefront.nl.yml +2 -0
- data/locales/storefront.pl.yml +2 -0
- data/locales/storefront.pt-BR.yml +2 -0
- data/locales/storefront.pt-PT.yml +2 -0
- data/locales/storefront.ro.yml +2 -0
- data/locales/storefront.sv.yml +2 -0
- data/locales/storefront.tr.yml +2 -0
- data/locales/storefront.zh-CN.yml +2 -0
- data/locales/storefront.zh-TW.yml +2 -0
- data/mise.toml +2 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/units/dugway/liquid/drops/pages_drop_spec.rb +186 -7
- data/spec/units/dugway/liquid/drops/product_drop_spec.rb +17 -0
- data/spec/units/dugway/liquid/filters/core_filters_spec.rb +301 -3
- data/spec/units/dugway/store_spec.rb +18 -0
- data/spec/units/dugway/theme_spec.rb +246 -0
- metadata +54 -25
@@ -477,6 +477,252 @@ describe Dugway::Theme do
|
|
477
477
|
theme.errors.should include("Option 'show_foo' has invalid comparison value 'invalid_value'. Feature flags can only check for `visible`.")
|
478
478
|
|
479
479
|
end
|
480
|
+
|
481
|
+
it "allows options that require image settings" do
|
482
|
+
settings = theme.settings.merge({
|
483
|
+
'options' => [{
|
484
|
+
'variable' => 'show_header_text',
|
485
|
+
'section' => 'general',
|
486
|
+
'description' => 'Show header text when logo is not present',
|
487
|
+
'requires' => 'logo'
|
488
|
+
}],
|
489
|
+
'images' => [{
|
490
|
+
'variable' => 'logo',
|
491
|
+
'section' => 'general',
|
492
|
+
'description' => 'Site logo'
|
493
|
+
}]
|
494
|
+
})
|
495
|
+
allow(theme).to receive(:settings).and_return(settings)
|
496
|
+
|
497
|
+
theme.valid?.should be(true)
|
498
|
+
theme.errors.should be_empty
|
499
|
+
end
|
500
|
+
|
501
|
+
it "allows options that require image_sets settings" do
|
502
|
+
settings = theme.settings.merge({
|
503
|
+
'options' => [{
|
504
|
+
'variable' => 'show_gallery',
|
505
|
+
'section' => 'homepage',
|
506
|
+
'description' => 'Show image gallery',
|
507
|
+
'requires' => 'gallery_images'
|
508
|
+
}],
|
509
|
+
'image_sets' => [{
|
510
|
+
'variable' => 'gallery_images',
|
511
|
+
'section' => 'homepage',
|
512
|
+
'description' => 'Gallery images'
|
513
|
+
}]
|
514
|
+
})
|
515
|
+
allow(theme).to receive(:settings).and_return(settings)
|
516
|
+
|
517
|
+
theme.valid?.should be(true)
|
518
|
+
theme.errors.should be_empty
|
519
|
+
end
|
520
|
+
|
521
|
+
it "fails when requires references unknown image setting" do
|
522
|
+
settings = theme.settings.merge({
|
523
|
+
'options' => [{
|
524
|
+
'variable' => 'show_banner',
|
525
|
+
'section' => 'general',
|
526
|
+
'description' => 'Show banner image',
|
527
|
+
'requires' => 'unknown_image'
|
528
|
+
}]
|
529
|
+
})
|
530
|
+
allow(theme).to receive(:settings).and_return(settings)
|
531
|
+
|
532
|
+
theme.valid?.should be(false)
|
533
|
+
theme.errors.should include("Option 'show_banner' requires unknown setting 'unknown_image'")
|
534
|
+
end
|
535
|
+
|
536
|
+
describe "when validating object-based requires" do
|
537
|
+
let(:base_settings) do
|
538
|
+
{
|
539
|
+
'name' => 'Test Theme',
|
540
|
+
'version' => '1.2.3',
|
541
|
+
'colors' => required_colors.map { |color| {'variable' => color} },
|
542
|
+
'options' => [],
|
543
|
+
'images' => [{'variable' => 'slideshow_image', 'section' => 'homepage'}],
|
544
|
+
'image_sets' => [{'variable' => 'hero_images', 'section' => 'homepage'}]
|
545
|
+
}
|
546
|
+
end
|
547
|
+
|
548
|
+
before(:each) do
|
549
|
+
allow(theme).to receive(:validate_required_color_settings) { true }
|
550
|
+
end
|
551
|
+
|
552
|
+
it "validates 'any' condition with valid settings" do
|
553
|
+
settings = base_settings.merge({
|
554
|
+
'options' => [{
|
555
|
+
'variable' => 'show_hero',
|
556
|
+
'section' => 'homepage',
|
557
|
+
'description' => 'Show hero section',
|
558
|
+
'requires' => [
|
559
|
+
{
|
560
|
+
'any' => [
|
561
|
+
'slideshow_image present',
|
562
|
+
'hero_images present'
|
563
|
+
]
|
564
|
+
}
|
565
|
+
]
|
566
|
+
}]
|
567
|
+
})
|
568
|
+
allow(theme).to receive(:settings).and_return(settings)
|
569
|
+
|
570
|
+
theme.valid?.should be(true)
|
571
|
+
theme.errors.should be_empty
|
572
|
+
end
|
573
|
+
|
574
|
+
it "validates mixed array with both objects and strings" do
|
575
|
+
settings = base_settings.merge({
|
576
|
+
'options' => [{
|
577
|
+
'variable' => 'show_advanced_hero',
|
578
|
+
'section' => 'homepage',
|
579
|
+
'description' => 'Show advanced hero',
|
580
|
+
'requires' => [
|
581
|
+
{
|
582
|
+
'any' => ['slideshow_image present', 'hero_images present']
|
583
|
+
},
|
584
|
+
'inventory'
|
585
|
+
]
|
586
|
+
}]
|
587
|
+
})
|
588
|
+
allow(theme).to receive(:settings).and_return(settings)
|
589
|
+
|
590
|
+
theme.valid?.should be(true)
|
591
|
+
theme.errors.should be_empty
|
592
|
+
end
|
593
|
+
|
594
|
+
it "fails when 'any' condition references unknown settings" do
|
595
|
+
settings = base_settings.merge({
|
596
|
+
'options' => [{
|
597
|
+
'variable' => 'show_gallery',
|
598
|
+
'section' => 'homepage',
|
599
|
+
'description' => 'Show image gallery',
|
600
|
+
'requires' => [
|
601
|
+
{
|
602
|
+
'any' => [
|
603
|
+
'unknown_image present',
|
604
|
+
'slideshow_image present'
|
605
|
+
]
|
606
|
+
}
|
607
|
+
]
|
608
|
+
}]
|
609
|
+
})
|
610
|
+
allow(theme).to receive(:settings).and_return(settings)
|
611
|
+
|
612
|
+
theme.valid?.should be(false)
|
613
|
+
theme.errors.should include("Option 'show_gallery' requires unknown setting 'unknown_image'")
|
614
|
+
end
|
615
|
+
|
616
|
+
it "fails when 'any' condition is not an array" do
|
617
|
+
settings = base_settings.merge({
|
618
|
+
'options' => [{
|
619
|
+
'variable' => 'show_content',
|
620
|
+
'section' => 'homepage',
|
621
|
+
'description' => 'Show content',
|
622
|
+
'requires' => [
|
623
|
+
{
|
624
|
+
'any' => 'slideshow_image present'
|
625
|
+
}
|
626
|
+
]
|
627
|
+
}]
|
628
|
+
})
|
629
|
+
allow(theme).to receive(:settings).and_return(settings)
|
630
|
+
|
631
|
+
theme.valid?.should be(false)
|
632
|
+
theme.errors.should include("Option 'show_content' has invalid 'any' condition - must be an array of rules")
|
633
|
+
end
|
634
|
+
|
635
|
+
it "fails when 'any' condition is empty" do
|
636
|
+
settings = base_settings.merge({
|
637
|
+
'options' => [{
|
638
|
+
'variable' => 'show_empty_any',
|
639
|
+
'section' => 'homepage',
|
640
|
+
'description' => 'Show with empty any',
|
641
|
+
'requires' => [
|
642
|
+
{
|
643
|
+
'any' => []
|
644
|
+
}
|
645
|
+
]
|
646
|
+
}]
|
647
|
+
})
|
648
|
+
allow(theme).to receive(:settings).and_return(settings)
|
649
|
+
|
650
|
+
theme.valid?.should be(false)
|
651
|
+
theme.errors.should include("Option 'show_empty_any' has empty 'any' condition - must contain at least one rule")
|
652
|
+
end
|
653
|
+
|
654
|
+
it "fails when object has unsupported operator" do
|
655
|
+
settings = base_settings.merge({
|
656
|
+
'options' => [{
|
657
|
+
'variable' => 'show_unsupported',
|
658
|
+
'section' => 'homepage',
|
659
|
+
'description' => 'Show with unsupported operator',
|
660
|
+
'requires' => [
|
661
|
+
{
|
662
|
+
'all' => ['slideshow_image present']
|
663
|
+
}
|
664
|
+
]
|
665
|
+
}]
|
666
|
+
})
|
667
|
+
allow(theme).to receive(:settings).and_return(settings)
|
668
|
+
|
669
|
+
theme.valid?.should be(false)
|
670
|
+
theme.errors.should include("Option 'show_unsupported' has unsupported requires object. Only 'any' is currently supported.")
|
671
|
+
end
|
672
|
+
|
673
|
+
it "validates nested operators and values within 'any'" do
|
674
|
+
settings = base_settings.merge({
|
675
|
+
'options' => [
|
676
|
+
{
|
677
|
+
'variable' => 'enable_slideshow',
|
678
|
+
'section' => 'homepage',
|
679
|
+
'description' => 'Enable slideshow',
|
680
|
+
'type' => 'boolean',
|
681
|
+
'default' => true
|
682
|
+
},
|
683
|
+
{
|
684
|
+
'variable' => 'show_conditional_hero',
|
685
|
+
'section' => 'homepage',
|
686
|
+
'description' => 'Show conditional hero',
|
687
|
+
'requires' => [
|
688
|
+
{
|
689
|
+
'any' => [
|
690
|
+
'enable_slideshow eq true',
|
691
|
+
'slideshow_image present'
|
692
|
+
]
|
693
|
+
}
|
694
|
+
]
|
695
|
+
}
|
696
|
+
]
|
697
|
+
})
|
698
|
+
allow(theme).to receive(:settings).and_return(settings)
|
699
|
+
|
700
|
+
theme.valid?.should be(true)
|
701
|
+
theme.errors.should be_empty
|
702
|
+
end
|
703
|
+
|
704
|
+
it "validates feature flags within 'any' condition" do
|
705
|
+
settings = base_settings.merge({
|
706
|
+
'options' => [{
|
707
|
+
'variable' => 'show_feature_dependent',
|
708
|
+
'section' => 'homepage',
|
709
|
+
'description' => 'Show feature dependent content',
|
710
|
+
'requires' => [
|
711
|
+
{
|
712
|
+
'any' => [
|
713
|
+
'feature:advanced_hero eq visible',
|
714
|
+
'slideshow_image present'
|
715
|
+
]
|
716
|
+
}
|
717
|
+
]
|
718
|
+
}]
|
719
|
+
})
|
720
|
+
allow(theme).to receive(:settings).and_return(settings)
|
721
|
+
|
722
|
+
theme.valid?.should be(true)
|
723
|
+
theme.errors.should be_empty
|
724
|
+
end
|
725
|
+
end
|
480
726
|
end
|
481
727
|
|
482
728
|
describe "when validating option sections" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dugway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Big Cartel
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,28 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 5.2.8
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 5.2.8
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: liquid
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 5.5.1
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 5.5.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bigdecimal
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '2.
|
131
|
+
version: '2.12'
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '2.
|
138
|
+
version: '2.12'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: sprockets-sass
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,20 +164,34 @@ dependencies:
|
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: 1.0.3
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: sassc
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.4'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.4'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: httparty
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: 0.
|
187
|
+
version: 0.21.0
|
174
188
|
type: :runtime
|
175
189
|
prerelease: false
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
192
|
- - "~>"
|
179
193
|
- !ruby/object:Gem::Version
|
180
|
-
version: 0.
|
194
|
+
version: 0.21.0
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: better_errors
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,16 +224,16 @@ dependencies:
|
|
210
224
|
name: i18n
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
|
-
- -
|
227
|
+
- - "~>"
|
214
228
|
- !ruby/object:Gem::Version
|
215
|
-
version: '1.
|
229
|
+
version: '1.12'
|
216
230
|
type: :runtime
|
217
231
|
prerelease: false
|
218
232
|
version_requirements: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
|
-
- -
|
234
|
+
- - "~>"
|
221
235
|
- !ruby/object:Gem::Version
|
222
|
-
version: '1.
|
236
|
+
version: '1.12'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
238
|
name: htmlentities
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -240,28 +254,28 @@ dependencies:
|
|
240
254
|
requirements:
|
241
255
|
- - "~>"
|
242
256
|
- !ruby/object:Gem::Version
|
243
|
-
version: '3.
|
257
|
+
version: '3.8'
|
244
258
|
type: :runtime
|
245
259
|
prerelease: false
|
246
260
|
version_requirements: !ruby/object:Gem::Requirement
|
247
261
|
requirements:
|
248
262
|
- - "~>"
|
249
263
|
- !ruby/object:Gem::Version
|
250
|
-
version: '3.
|
264
|
+
version: '3.8'
|
251
265
|
- !ruby/object:Gem::Dependency
|
252
266
|
name: thor
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|
254
268
|
requirements:
|
255
269
|
- - "~>"
|
256
270
|
- !ruby/object:Gem::Version
|
257
|
-
version:
|
271
|
+
version: '1.2'
|
258
272
|
type: :runtime
|
259
273
|
prerelease: false
|
260
274
|
version_requirements: !ruby/object:Gem::Requirement
|
261
275
|
requirements:
|
262
276
|
- - "~>"
|
263
277
|
- !ruby/object:Gem::Version
|
264
|
-
version:
|
278
|
+
version: '1.2'
|
265
279
|
- !ruby/object:Gem::Dependency
|
266
280
|
name: rubyzip
|
267
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,14 +296,14 @@ dependencies:
|
|
282
296
|
requirements:
|
283
297
|
- - "~>"
|
284
298
|
- !ruby/object:Gem::Version
|
285
|
-
version: '1.
|
299
|
+
version: '1.2'
|
286
300
|
type: :runtime
|
287
301
|
prerelease: false
|
288
302
|
version_requirements: !ruby/object:Gem::Requirement
|
289
303
|
requirements:
|
290
304
|
- - "~>"
|
291
305
|
- !ruby/object:Gem::Version
|
292
|
-
version: '1.
|
306
|
+
version: '1.2'
|
293
307
|
- !ruby/object:Gem::Dependency
|
294
308
|
name: thin
|
295
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -332,6 +346,20 @@ dependencies:
|
|
332
346
|
- - ">="
|
333
347
|
- !ruby/object:Gem::Version
|
334
348
|
version: 1.0.0
|
349
|
+
- !ruby/object:Gem::Dependency
|
350
|
+
name: multi_json
|
351
|
+
requirement: !ruby/object:Gem::Requirement
|
352
|
+
requirements:
|
353
|
+
- - "~>"
|
354
|
+
- !ruby/object:Gem::Version
|
355
|
+
version: 1.15.0
|
356
|
+
type: :runtime
|
357
|
+
prerelease: false
|
358
|
+
version_requirements: !ruby/object:Gem::Requirement
|
359
|
+
requirements:
|
360
|
+
- - "~>"
|
361
|
+
- !ruby/object:Gem::Version
|
362
|
+
version: 1.15.0
|
335
363
|
- !ruby/object:Gem::Dependency
|
336
364
|
name: rake
|
337
365
|
requirement: !ruby/object:Gem::Requirement
|
@@ -538,6 +566,7 @@ files:
|
|
538
566
|
- locales/storefront.zh-CN.yml
|
539
567
|
- locales/storefront.zh-TW.yml
|
540
568
|
- log/dugway.log
|
569
|
+
- mise.toml
|
541
570
|
- spec/features/contact_form_spec.rb
|
542
571
|
- spec/features/page_rendering_spec.rb
|
543
572
|
- spec/features/shopping_spec.rb
|
@@ -606,7 +635,7 @@ homepage: https://github.com/bigcartel/dugway
|
|
606
635
|
licenses:
|
607
636
|
- MIT
|
608
637
|
metadata: {}
|
609
|
-
post_install_message:
|
638
|
+
post_install_message:
|
610
639
|
rdoc_options: []
|
611
640
|
require_paths:
|
612
641
|
- lib
|
@@ -614,7 +643,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
614
643
|
requirements:
|
615
644
|
- - ">="
|
616
645
|
- !ruby/object:Gem::Version
|
617
|
-
version: '2.
|
646
|
+
version: '2.7'
|
618
647
|
- - "<"
|
619
648
|
- !ruby/object:Gem::Version
|
620
649
|
version: '3'
|
@@ -624,8 +653,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
624
653
|
- !ruby/object:Gem::Version
|
625
654
|
version: '0'
|
626
655
|
requirements: []
|
627
|
-
rubygems_version: 3.
|
628
|
-
signing_key:
|
656
|
+
rubygems_version: 3.1.6
|
657
|
+
signing_key:
|
629
658
|
specification_version: 4
|
630
659
|
summary: Easily build and test Big Cartel themes.
|
631
660
|
test_files:
|