dugway 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +1 -1
  6. data/LICENSE.txt +22 -0
  7. data/dugway.gemspec +3 -0
  8. data/lib/dugway/cart.rb +8 -12
  9. data/lib/dugway/cli/templates/Gemfile.tt +1 -1
  10. data/lib/dugway/cli/templates/gitignore.tt +1 -0
  11. data/lib/dugway/cli/templates/source/product.html +5 -3
  12. data/lib/dugway/cli/templates/source/stylesheets/cart.css.sass +8 -0
  13. data/lib/dugway/cli/templates/source/stylesheets/product.css.sass +32 -0
  14. data/lib/dugway/liquid/drops/cart_item_drop.rb +4 -0
  15. data/lib/dugway/liquid/drops/product_drop.rb +10 -6
  16. data/lib/dugway/liquid/drops/product_option_drop.rb +1 -1
  17. data/lib/dugway/liquid/drops/shipping_option_drop.rb +2 -0
  18. data/lib/dugway/liquid/tags/checkout_form.rb +1 -1
  19. data/lib/dugway/version.rb +1 -1
  20. data/spec/features/contact_form_spec.rb +43 -0
  21. data/spec/features/page_rendering_spec.rb +69 -0
  22. data/spec/features/shopping_spec.rb +38 -0
  23. data/spec/fixtures/store/products.js +1 -1
  24. data/spec/fixtures/store/store.js +1 -1
  25. data/spec/fixtures/theme/cart.html +22 -7
  26. data/spec/fixtures/theme/contact.html +37 -37
  27. data/spec/fixtures/theme/layout.html +8 -0
  28. data/spec/fixtures/theme/settings.json +1 -0
  29. data/spec/fixtures/theme/styles.css +2 -2
  30. data/spec/spec_helper.rb +8 -0
  31. data/spec/units/dugway/cart_spec.rb +204 -0
  32. data/spec/units/dugway/liquid/drops/account_drop_spec.rb +54 -0
  33. data/spec/units/dugway/liquid/drops/artist_drop_spec.rb +40 -0
  34. data/spec/units/dugway/liquid/drops/artists_drop_spec.rb +41 -0
  35. data/spec/units/dugway/liquid/drops/cart_drop_spec.rb +81 -0
  36. data/spec/units/dugway/liquid/drops/cart_item_drop_spec.rb +72 -0
  37. data/spec/units/dugway/liquid/drops/categories_drop_spec.rb +41 -0
  38. data/spec/units/dugway/liquid/drops/category_drop_spec.rb +40 -0
  39. data/spec/units/dugway/liquid/drops/contact_drop_spec.rb +124 -0
  40. data/spec/units/dugway/liquid/drops/country_drop_spec.rb +17 -0
  41. data/spec/units/dugway/liquid/drops/image_drop_spec.rb +23 -0
  42. data/spec/units/dugway/liquid/drops/page_drop_spec.rb +70 -0
  43. data/spec/units/dugway/liquid/drops/pages_drop_spec.rb +29 -0
  44. data/spec/units/dugway/liquid/drops/product_drop_spec.rb +269 -0
  45. data/spec/units/dugway/liquid/drops/product_option_drop_spec.rb +86 -0
  46. data/spec/units/dugway/liquid/drops/products_drop_spec.rb +127 -0
  47. data/spec/units/dugway/liquid/drops/shipping_option_drop_spec.rb +26 -0
  48. data/spec/units/dugway/liquid/drops/theme_drop_spec.rb +68 -0
  49. data/spec/units/dugway/store_spec.rb +27 -27
  50. data/spec/units/dugway/template_spec.rb +12 -0
  51. data/spec/units/dugway/theme_spec.rb +198 -0
  52. metadata +95 -57
  53. data/spec/units/dugway_spec.rb +0 -9
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dugway::Drops::ProductsDrop do
4
+ let(:order) { 'position' }
5
+ let(:params) { {} }
6
+ let(:registers) { { :params => params } }
7
+
8
+ let(:products) {
9
+ Dugway::Drops::ProductsDrop.new(Dugway.store.products.map { |p| Dugway::Drops::ProductDrop.new(p) }).tap { |drop|
10
+ drop.context = Liquid::Context.new([{}, { 'internal' => { 'order' => order }}], {}, registers)
11
+ }
12
+ }
13
+
14
+ describe "#all" do
15
+ it "should return an array of all products" do
16
+ all = products.all
17
+ all.should be_an_instance_of(WillPaginate::Collection)
18
+ all.size.should == 3
19
+
20
+ product = all.first
21
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
22
+ product.name.should == 'My Product'
23
+ end
24
+ end
25
+
26
+ describe "#current" do
27
+ it "should return an array of current products" do
28
+ current = products.current
29
+ current.should be_an_instance_of(WillPaginate::Collection)
30
+ current.size.should == 3
31
+
32
+ product = current.first
33
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
34
+ product.name.should == 'My Product'
35
+ end
36
+
37
+ describe "when filtering by artist" do
38
+ before(:each) do
39
+ registers.merge!(:artist => { 'permalink' => 'artist-one' })
40
+ end
41
+
42
+ it "should return an array of the artist's products" do
43
+ current = products.current
44
+ current.should be_an_instance_of(WillPaginate::Collection)
45
+ current.size.should == 1
46
+
47
+ product = current.first
48
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
49
+ product.name.should == 'My Product'
50
+ end
51
+ end
52
+
53
+ describe "when filtering by category" do
54
+ before(:each) do
55
+ registers.merge!(:category => { 'permalink' => 'tees' })
56
+ end
57
+
58
+ it "should return an array of the category's products" do
59
+ current = products.current
60
+ current.should be_an_instance_of(WillPaginate::Collection)
61
+ current.size.should == 2
62
+
63
+ product = current.first
64
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
65
+ product.name.should == 'My Product'
66
+ end
67
+ end
68
+
69
+ describe "when searching" do
70
+ before(:each) do
71
+ registers[:params].merge!(:search => 'my product')
72
+ end
73
+
74
+ it "should return an array of the category's products" do
75
+ current = products.current
76
+ current.should be_an_instance_of(WillPaginate::Collection)
77
+ current.size.should == 1
78
+
79
+ product = current.first
80
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
81
+ product.name.should == 'My Product'
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#on_sale" do
87
+ it "should return an array of on sale products" do
88
+ current = products.on_sale
89
+ current.should be_an_instance_of(WillPaginate::Collection)
90
+ current.size.should == 1
91
+
92
+ product = current.first
93
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
94
+ product.name.should == 'Print'
95
+ end
96
+ end
97
+
98
+ describe "#top_selling" do
99
+ it "should return nil, since it's deprecated" do
100
+ products.top_selling.should be_nil
101
+ end
102
+ end
103
+
104
+ describe "#newest" do
105
+ it "should return nil, since it's deprecated" do
106
+ products.newest.should be_nil
107
+ end
108
+ end
109
+
110
+ describe "#featured" do
111
+ it "should return nil, since it's deprecated" do
112
+ products.featured.should be_nil
113
+ end
114
+ end
115
+
116
+ describe "#permalink" do
117
+ it "should return the product by permalink" do
118
+ product = products.print
119
+ product.should be_an_instance_of(Dugway::Drops::ProductDrop)
120
+ product.name.should == 'Print'
121
+ end
122
+
123
+ it "should return the nil for an invalid permalink" do
124
+ products.blah.should be_nil
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dugway::Drops::ShippingOptionDrop do
4
+ let(:product) { Dugway::Drops::ProductDrop.new(Dugway.store.products.first) }
5
+ let(:shipping) { product.shipping.first }
6
+
7
+ describe "#amount_alone" do
8
+ it "should return the shipping's amount_alone" do
9
+ shipping.amount_alone.should == 10.0
10
+ end
11
+ end
12
+
13
+ describe "#amount_with_others" do
14
+ it "should return the shipping's amount_with_others" do
15
+ shipping.amount_with_others.should == 5.0
16
+ end
17
+ end
18
+
19
+ describe "#country" do
20
+ it "should return the shipping's country" do
21
+ country = shipping.country
22
+ country.should be_an_instance_of(Dugway::Drops::CountryDrop)
23
+ country.name.should == 'United States'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dugway::Drops::ThemeDrop do
4
+ let(:customization) {{
5
+ :logo => { :url => 'http://mysite.com/logo.png', :width => 100, :height => 50 },
6
+ :background_image => { :url => 'http://mysite.com/bg.png', :width => 10, :height => 20 }
7
+ }}
8
+
9
+ let(:theme) { Dugway::Drops::ThemeDrop.new(Dugway.theme.customization.update(customization.stringify_keys)).tap { |drop|
10
+ drop.context = Liquid::Context.new({}, {}, { :settings => Dugway.theme.settings })
11
+ }}
12
+
13
+ describe "#logo" do
14
+ it "should return the theme's logo" do
15
+ logo = theme.logo
16
+ logo.should be_an_instance_of(Dugway::Drops::ImageDrop)
17
+ logo.url.should == 'http://mysite.com/logo.png'
18
+ logo.width.should == 100
19
+ logo.height.should == 50
20
+ end
21
+ end
22
+
23
+ describe "#background_image" do
24
+ it "should return the theme's background_image" do
25
+ background_image = theme.background_image
26
+ background_image.should be_an_instance_of(Dugway::Drops::ImageDrop)
27
+ background_image.url.should == 'http://mysite.com/bg.png'
28
+ background_image.width.should == 10
29
+ background_image.height.should == 20
30
+ end
31
+ end
32
+
33
+ describe "#header_font" do
34
+ it "should return the theme's header_font" do
35
+ theme.header_font.should == 'Helvetica'
36
+ end
37
+ end
38
+
39
+ describe "#font" do
40
+ it "should return the theme's font" do
41
+ theme.font.should == 'Georgia'
42
+ end
43
+ end
44
+
45
+ describe "#background_color" do
46
+ it "should return the theme's background_color" do
47
+ theme.background_color.should == '#222222'
48
+ end
49
+ end
50
+
51
+ describe "#link_color" do
52
+ it "should return the theme's link_color" do
53
+ theme.link_color.should == 'red'
54
+ end
55
+ end
56
+
57
+ describe "#show_search" do
58
+ it "should return the theme's show_search" do
59
+ theme.show_search.should be(false)
60
+ end
61
+ end
62
+
63
+ describe "#fixed_sidebar" do
64
+ it "should return the theme's fixed_sidebar" do
65
+ theme.fixed_sidebar.should be(true)
66
+ end
67
+ end
68
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Dugway::Store do
4
4
  let(:store) { Dugway::Store.new('dugway') }
5
-
5
+
6
6
  describe "#account" do
7
7
  it "should return account params" do
8
8
  store.account.should be_present
@@ -10,7 +10,7 @@ describe Dugway::Store do
10
10
  store.account['url'].should == 'http://dugway.bigcartel.com'
11
11
  end
12
12
  end
13
-
13
+
14
14
  describe "#theme_pages" do
15
15
  it "should return an array of the default theme pages" do
16
16
  store.theme_pages.should be_present
@@ -18,7 +18,7 @@ describe Dugway::Store do
18
18
  store.theme_pages.first.should == { 'name' => 'Home', 'permalink' => 'home', 'url' => '/', 'category' => 'theme' }
19
19
  end
20
20
  end
21
-
21
+
22
22
  describe "#custom_pages" do
23
23
  it "should return an array of the store's custom pages" do
24
24
  store.custom_pages.should be_present
@@ -26,7 +26,7 @@ describe Dugway::Store do
26
26
  store.custom_pages.first.should == { 'category' => 'custom', 'content' => "<p>We're really cool!</p>", 'permalink' => 'about-us', 'name' => 'About Us', 'id' => 95821979, 'url' => '/about-us' }
27
27
  end
28
28
  end
29
-
29
+
30
30
  describe "#pages" do
31
31
  it "should return an array of the combined theme and custom pages" do
32
32
  store.pages.should be_present
@@ -35,21 +35,21 @@ describe Dugway::Store do
35
35
  store.pages.last.should == { 'category' => 'custom', 'content' => "<p>We're really cool!</p>", 'permalink' => 'about-us', 'name' => 'About Us', 'id' => 95821979, 'url' => '/about-us' }
36
36
  end
37
37
  end
38
-
38
+
39
39
  describe "#page" do
40
40
  it "should return a theme page by permalink" do
41
41
  store.page('home').should == { 'name' => 'Home', 'permalink' => 'home', 'url' => '/', 'category' => 'theme' }
42
42
  end
43
-
43
+
44
44
  it "should return a custom page by permalink" do
45
45
  store.page('about-us').should == { 'category' => 'custom', 'content' => "<p>We're really cool!</p>", 'permalink' => 'about-us', 'name' => 'About Us', 'id' => 95821979, 'url' => '/about-us' }
46
46
  end
47
-
47
+
48
48
  it "should return nil with a bad permalink" do
49
49
  store.page('blah').should be_nil
50
50
  end
51
51
  end
52
-
52
+
53
53
  describe "#categories" do
54
54
  it "should return an array of the store's categories" do
55
55
  store.categories.should be_present
@@ -57,59 +57,59 @@ describe Dugway::Store do
57
57
  store.categories.first.should == { 'permalink' => 'cds', 'name' => 'CDs', 'id' => 4615184, 'url' => '/category/cds' }
58
58
  end
59
59
  end
60
-
60
+
61
61
  describe "#category" do
62
62
  it "should return a category by permalink" do
63
63
  store.category('cds').should == { 'permalink' => 'cds', 'name' => 'CDs', 'id' => 4615184, 'url' => '/category/cds' }
64
64
  end
65
-
65
+
66
66
  it "should return nil with a bad permalink" do
67
67
  store.category('blah').should be_nil
68
68
  end
69
69
  end
70
-
70
+
71
71
  describe "#category_products" do
72
72
  it "should return an array of products for that category" do
73
73
  products = store.category_products('tees')
74
74
  products.size.should == 2
75
75
  products.first['name'].should == 'My Product'
76
76
  end
77
-
77
+
78
78
  it "should return an empty array with a bad permalink" do
79
79
  store.category_products('blah').should == []
80
80
  end
81
81
  end
82
-
82
+
83
83
  describe "#artists" do
84
84
  it "should return an array of the store's artists" do
85
85
  store.artists.should be_present
86
- store.artists.size.should == 2
86
+ store.artists.size.should == 3
87
87
  store.artists.first.should == { 'permalink' => 'artist-one', 'name' => 'Artist One', 'id' => 176141, 'url' => '/artist/artist-one' }
88
88
  end
89
89
  end
90
-
90
+
91
91
  describe "#artist" do
92
92
  it "should return an artist by permalink" do
93
93
  store.artist('artist-one').should == { 'permalink' => 'artist-one', 'name' => 'Artist One', 'id' => 176141, 'url' => '/artist/artist-one' }
94
94
  end
95
-
95
+
96
96
  it "should return nil with a bad permalink" do
97
97
  store.artist('blah').should be_nil
98
98
  end
99
99
  end
100
-
100
+
101
101
  describe "#artist_products" do
102
102
  it "should return an array of products for that artist" do
103
103
  products = store.artist_products('artist-one')
104
104
  products.size.should == 1
105
105
  products.first['name'].should == 'My Product'
106
106
  end
107
-
107
+
108
108
  it "should return an empty array with a bad permalink" do
109
109
  store.artist_products('blah').should == []
110
110
  end
111
111
  end
112
-
112
+
113
113
  describe "#products" do
114
114
  it "should return an array of the store's products" do
115
115
  store.products.should be_present
@@ -117,17 +117,17 @@ describe Dugway::Store do
117
117
  store.products.first['name'].should == 'My Product'
118
118
  end
119
119
  end
120
-
120
+
121
121
  describe "#product" do
122
122
  it "should return a product by permalink" do
123
123
  store.product('my-product')['name'].should == 'My Product'
124
124
  end
125
-
125
+
126
126
  it "should return nil with a bad permalink" do
127
127
  store.product('blah').should be_nil
128
128
  end
129
129
  end
130
-
130
+
131
131
  describe "#product_and_option" do
132
132
  it "should a product and option by option id" do
133
133
  product, option = store.product_and_option(29474321)
@@ -152,7 +152,7 @@ describe Dugway::Store do
152
152
 
153
153
  describe "#next_product" do
154
154
  it "should return the next product when there is one" do
155
- store.next_product('my-tee')['name'].should == 'My Print'
155
+ store.next_product('my-tee')['name'].should == 'Print'
156
156
  end
157
157
 
158
158
  it "should return nil when there isn't one" do
@@ -166,24 +166,24 @@ describe Dugway::Store do
166
166
  products.size.should == 1
167
167
  products.first['name'].should == 'My Product'
168
168
  end
169
-
169
+
170
170
  it "should return an empty array with a bad permalink" do
171
171
  store.search_products('blah').should == []
172
172
  end
173
173
  end
174
-
174
+
175
175
  describe "#country" do
176
176
  it "returns the store's country" do
177
177
  store.country.should == { 'name' => 'United States', 'id' => 43, 'code' => 'US' }
178
178
  end
179
179
  end
180
-
180
+
181
181
  describe "#currency" do
182
182
  it "returns the store's currency" do
183
183
  store.currency.should == { 'sign' => '$', 'name' => 'U.S. Dollar', 'id' => 1, 'code' => 'USD' }
184
184
  end
185
185
  end
186
-
186
+
187
187
  describe "#locale" do
188
188
  it "returns the store's locale based on their currency" do
189
189
  store.locale.should == 'en-US'
@@ -141,5 +141,17 @@ describe Dugway::Template do
141
141
  template.render(request, variables)
142
142
  end
143
143
  end
144
+
145
+ describe "when passing a page variable containing content" do
146
+ let(:page) { store.page('about-us') }
147
+ let(:variables) { { :page => page } }
148
+ let(:content) { page['content'] }
149
+
150
+ it "calls renders properly with Liquifier" do
151
+ Dugway::Liquifier.any_instance.should_receive(:render).with(content, variables) { content }
152
+ Dugway::Liquifier.any_instance.should_receive(:render).with(layout, variables.update(:page_content => content))
153
+ template.render(request, variables)
154
+ end
155
+ end
144
156
  end
145
157
  end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dugway::Theme do
4
+ let(:theme) { Dugway.theme }
5
+
6
+ describe "#layout" do
7
+ it "should return the theme's layout" do
8
+ theme.layout.should == read_file('layout.html')
9
+ end
10
+ end
11
+
12
+ describe "#settings" do
13
+ it "should return a hash of the theme's settings" do
14
+ theme.settings.should == JSON.parse(read_file('settings.json'))
15
+ end
16
+ end
17
+
18
+ describe "#fonts" do
19
+ it "should return a hash of font settings values" do
20
+ theme.fonts.should == {
21
+ 'font' => 'Georgia',
22
+ 'header_font' => 'Helvetica'
23
+ }
24
+ end
25
+ end
26
+
27
+ describe "#customization" do
28
+ it "should return a hash of font, color, and option settings values" do
29
+ theme.customization.should == {
30
+ 'background_color' => '#222222',
31
+ 'fixed_sidebar' => true,
32
+ 'font' => 'Georgia',
33
+ 'header_font' => 'Helvetica',
34
+ 'link_color' => 'red',
35
+ 'show_search' => false
36
+ }
37
+ end
38
+
39
+ describe "when there are overridden customization" do
40
+ before(:each) do
41
+ Dugway.stub(:theme) {
42
+ Dugway::Theme.new(:fixed_sidebar => false, :link_color => 'blue')
43
+ }
44
+ end
45
+
46
+ it "should merge those values into the defaults" do
47
+ theme.customization.should == {
48
+ 'background_color' => '#222222',
49
+ 'fixed_sidebar' => false,
50
+ 'font' => 'Georgia',
51
+ 'header_font' => 'Helvetica',
52
+ 'link_color' => 'blue',
53
+ 'show_search' => false
54
+ }
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "#name" do
60
+ it "should return the theme's name" do
61
+ theme.name.should == 'Test Theme'
62
+ end
63
+ end
64
+
65
+ describe "#version" do
66
+ it "should return the theme's version" do
67
+ theme.version.should == '1.2.3'
68
+ end
69
+ end
70
+
71
+ describe "#file_content" do
72
+ it "should return the file content for most files" do
73
+ %w( home.html products.html screenshot.jpg ).each { |file_name|
74
+ theme.file_content(file_name).should == read_file(file_name)
75
+ }
76
+ end
77
+
78
+ it "should sprocketize scripts.js" do
79
+ theme.file_content('scripts.js').gsub(/\s+/, '').should == %{$(function(){console.log('One')});(function(){$(function(){returnconsole.log('Two');});}).call(this);}
80
+ end
81
+
82
+ it "should sprocketize and liquify styles.css" do
83
+ theme.file_content('styles.css').gsub(/\s+/, '').should == %{html,body{height:100%;}a{color:red;}/**/}
84
+ end
85
+ end
86
+
87
+ describe "#build_file" do
88
+ it "should return the file content for most files" do
89
+ %w( home.html products.html screenshot.jpg ).each { |file_name|
90
+ theme.build_file(file_name).should == read_file(file_name)
91
+ }
92
+ end
93
+
94
+ it "should sprocketize and compress scripts.js" do
95
+ theme.build_file('scripts.js').should == %{$(function(){console.log(\"One\")});(function(){$(function(){return console.log(\"Two\")})}).call(this);}
96
+ end
97
+
98
+ it "should sprocketize and not liquify styles.css" do
99
+ theme.build_file('styles.css').gsub(/\s+/, '').should == %{html,body{height:100%;}a{color:{{theme.link_color}};}/**/}
100
+ end
101
+ end
102
+
103
+ describe "#files" do
104
+ it "should return an array of all files" do
105
+ theme.files.should == ["layout.html", "home.html", "products.html", "product.html", "cart.html", "checkout.html", "success.html", "contact.html", "maintenance.html", "scripts.js", "styles.css", "settings.json", "screenshot.jpg", "images/bc_badge.png"]
106
+ end
107
+ end
108
+
109
+ describe "#image_files" do
110
+ it "should return an array of all image files" do
111
+ theme.image_files.should == ["images/bc_badge.png"]
112
+ end
113
+ end
114
+
115
+ describe "#valid?" do
116
+ it "should return true when a theme has everything it needs" do
117
+ theme.valid?.should be(true)
118
+ theme.errors.should be_empty
119
+ end
120
+
121
+ describe "when missing a required file" do
122
+ before(:each) do
123
+ theme.stub(:read_source_file).with('layout.html') { theme.unstub!(:read_source_file); nil }
124
+ end
125
+
126
+ it "should not be valid" do
127
+ theme.valid?.should be(false)
128
+ theme.errors.size.should == 1
129
+ theme.errors.first.should == 'Missing source/layout.html'
130
+ end
131
+ end
132
+
133
+ describe "when missing a name" do
134
+ before(:each) do
135
+ theme.stub(:name) { nil }
136
+ end
137
+
138
+ it "should not be valid" do
139
+ theme.valid?.should be(false)
140
+ theme.errors.size.should == 1
141
+ theme.errors.first.should == 'Missing theme name in source/settings.json'
142
+ end
143
+ end
144
+
145
+ describe "when missing a version" do
146
+ before(:each) do
147
+ theme.stub(:version) { nil }
148
+ end
149
+
150
+ it "should not be valid" do
151
+ theme.valid?.should be(false)
152
+ theme.errors.size.should == 1
153
+ theme.errors.first.should == 'Invalid theme version in source/settings.json (ex: 1.0.3)'
154
+ end
155
+ end
156
+
157
+ describe "when having an invalid version" do
158
+ before(:each) do
159
+ theme.stub(:version) { '1.3' }
160
+ end
161
+
162
+ it "should not be valid" do
163
+ theme.valid?.should be(false)
164
+ theme.errors.size.should == 1
165
+ theme.errors.first.should == 'Invalid theme version in source/settings.json (ex: 1.0.3)'
166
+ end
167
+ end
168
+
169
+ describe "when missing at least one image" do
170
+ before(:each) do
171
+ theme.stub(:image_files) { [] }
172
+ end
173
+
174
+ it "should not be valid" do
175
+ theme.valid?.should be(false)
176
+ theme.errors.size.should == 1
177
+ theme.errors.first.should == 'Missing images in source/images'
178
+ end
179
+ end
180
+
181
+ describe "when there are several errors" do
182
+ before(:each) do
183
+ theme.stub(:name) { nil }
184
+ theme.stub(:version) { nil }
185
+ theme.stub(:image_files) { [] }
186
+ end
187
+
188
+ it "should return all of them" do
189
+ theme.valid?.should be(false)
190
+ theme.errors.size.should == 3
191
+ end
192
+ end
193
+ end
194
+
195
+ def read_file(file_name)
196
+ File.read(File.join(Dugway.source_dir, file_name))
197
+ end
198
+ end