cup 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,223 @@
1
+ require 'spec_helper'
2
+ require 'cup/directory'
3
+ require 'cup'
4
+
5
+ describe Cup::Directory do
6
+
7
+ let(:directory){ Cup::Directory.current }
8
+
9
+ describe '.__current__' do
10
+ it 'should return a Cup::Directory for the current working directory' do
11
+ Cup::Directory.__current__.path.should == Pathname.new('.').expand_path
12
+ end
13
+ end
14
+
15
+ describe '#cupfile' do
16
+ it 'should return a cupfile for the current directory' do
17
+ directory.cupfile.path.should == directory.path + 'Cupfile'
18
+ end
19
+
20
+ it 'should raise a CupfileError if the current directories cupfile is invalid' do
21
+
22
+ cupfile = directory.cupfile
23
+ cupfile.instance_variable_set :@name, nil
24
+ cupfile.should_not be_valid
25
+
26
+ directory.instance_variable_set :@cupfile, cupfile
27
+
28
+ expect {
29
+ directory.cupfile
30
+ }.to raise_error Cup::Cupfile::CupfileError
31
+ end
32
+ end
33
+
34
+ describe '#path' do
35
+ it 'should return the full path to the javascript cup directory' do
36
+ directory.path.should == Pathname.new(test_example_cup_name).expand_path
37
+ end
38
+ end
39
+
40
+ describe '#name' do
41
+ it 'should be the directory name of the project' do
42
+ directory.name.should == test_example_cup_name
43
+ end
44
+ end
45
+
46
+ describe '#concatenated' do
47
+
48
+ it 'should be absolute path to <cup_name>-<version>.js' do
49
+ directory.concatenated.should == File.expand_path("#{directory.path}/build/#{directory.cupfile.name}-#{Cup.version}.js")
50
+ end
51
+
52
+ it 'should give a path relative to the directory if :relative => true is passed' do
53
+ directory.concatenated(:relative => true).should == "build/#{directory.cupfile.name}-#{Cup.version}.js"
54
+ end
55
+ end
56
+
57
+ describe '#minified' do
58
+
59
+ it 'should be absolute path to <cup_name>-<version>.min.js' do
60
+ directory.minified.should == File.expand_path("#{directory.path}/build/#{directory.cupfile.name}-#{Cup.version}.min.js")
61
+ end
62
+
63
+ it 'should give a path relative to the directory if :relative => true is passed' do
64
+ directory.minified(:relative => true).should == "build/#{directory.cupfile.name}-#{Cup.version}.min.js"
65
+ end
66
+ end
67
+
68
+ describe '#license' do
69
+
70
+ it 'should be absolute path to license.txt' do
71
+ directory.license.should == File.expand_path("#{directory.path}/license.txt")
72
+ end
73
+
74
+ it 'should give a path relative to the license if :relative => true is passed' do
75
+ directory.license(:relative => true).should == "license.txt"
76
+ end
77
+ end
78
+
79
+ describe '#stylesheets' do
80
+ it 'returns an array with Pathname objects to all stylesheets' do
81
+ directory.stylesheets.count.should be >= 20
82
+ directory.stylesheets.each do |css|
83
+ css.should be_instance_of Pathname
84
+ css.to_s.downcase.should match /.*\.css$/
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#javascripts' do
90
+
91
+ share_examples_for :all_schemes do
92
+
93
+ it 'should not be empty' do
94
+ javascripts.empty?.should be_false
95
+ end
96
+
97
+ it 'should only include javascripts' do
98
+ javascripts.each do |js|
99
+ js.should match /(.*)\.js$/
100
+ end
101
+ end
102
+
103
+ it 'should not contain duplicates' do
104
+ javascripts.length.should == javascripts.uniq.length
105
+ end
106
+
107
+ it "should return scripts from the load paths in the correct order" do
108
+
109
+ acceptor = JavascriptLoadOrderAcceptor.new
110
+ acceptor.accepts?(javascripts).should be_true
111
+ end
112
+
113
+ context 'when a cupfile specifies an order of patterns' do
114
+
115
+ let(:directory){Cup::Directory.current}
116
+ let(:cupfile){directory.cupfile}
117
+
118
+ def set_patterns &block
119
+ Cup::Cupfile::DSL::JavascriptsDSL.interpret cupfile, &block
120
+ end
121
+
122
+ it 'should include files in that order' do
123
+
124
+ set_patterns do
125
+ spec 'subdir/spec2.js', 'spec3.js', :*
126
+ vendor [:*, 'vendor2.js']
127
+ end
128
+
129
+ cupfile.javascripts[:spec][0].should == "#{directory.path}/spec/subdir/spec2.js"
130
+ cupfile.javascripts[:spec][1].should == "#{directory.path}/spec/spec3.js"
131
+ cupfile.javascripts[:spec].count.should be > 2
132
+
133
+ cupfile.javascripts[:vendor][-1].should == "#{directory.path}/vendor/vendor2.js"
134
+ cupfile.javascripts[:vendor].count.should be > 1
135
+ end
136
+
137
+ # because this is the one that matters when including javascripts in dependent order
138
+ it 'should include the item in its first position when there are duplicates' do
139
+ set_patterns do
140
+ lib 'lib3.js', :*, 'lib3.js'
141
+ end
142
+
143
+ cupfile.javascripts[:lib][0].should == "#{directory.path}/lib/lib3.js"
144
+ end
145
+ end
146
+ end
147
+
148
+ share_examples_for :build_input_schemes do
149
+ it 'should include exactly ONE build output' do
150
+ remains = javascripts.reject {|js| ! (js =~ /(.\/)?(build)(\/)/)}
151
+ remains.length.should == 1
152
+ end
153
+ it 'should not include src or lib' do
154
+ javascripts.should_not include_javascripts_from_load_paths(:src, :lib)
155
+ end
156
+ end
157
+
158
+ share_examples_for :non_build_input_scheme do
159
+ it 'should include lib and src' do
160
+ javascripts.should include_javascripts_from_load_paths(:lib, :src)
161
+ end
162
+ it 'should not include build output' do
163
+ javascripts.should_not include_javascripts_from_load_paths(:build)
164
+ end
165
+ end
166
+
167
+ context 'when calling with :build_input' do
168
+
169
+ let(:javascripts){directory.javascripts(:build_input)}
170
+
171
+ it_behaves_like :all_schemes
172
+ it_behaves_like :non_build_input_scheme
173
+
174
+ it 'should not include vendor build or specs' do
175
+ javascripts.should_not include_javascripts_from_load_paths(:vendor, :build, :spec)
176
+ end
177
+ end
178
+
179
+ context 'when calling with :spec' do
180
+
181
+ let(:javascripts){directory.javascripts(:spec)}
182
+
183
+ it_behaves_like :all_schemes
184
+ it_behaves_like :non_build_input_scheme
185
+ end
186
+
187
+ context 'when calling with :spec_concatenated' do
188
+
189
+ let(:javascripts){directory.javascripts(:spec_concatenated)}
190
+
191
+ it_behaves_like :all_schemes
192
+ it_behaves_like :build_input_schemes
193
+
194
+ it 'should include the build output' do
195
+ javascripts.should include directory.concatenated
196
+ end
197
+ end
198
+
199
+ context 'when calling with :spec_minified' do
200
+
201
+ let(:javascripts){directory.javascripts(:spec_minified)}
202
+
203
+ it_behaves_like :all_schemes
204
+ it_behaves_like :build_input_schemes
205
+
206
+ it 'should include the minified output' do
207
+ javascripts.should include directory.minified
208
+ end
209
+ end
210
+
211
+ context 'when calling with :debug' do
212
+
213
+ let(:javascripts){directory.javascripts(:debug)}
214
+
215
+ it_behaves_like :all_schemes
216
+ it_behaves_like :non_build_input_scheme
217
+
218
+ it 'should not include specs' do
219
+ javascripts.should_not include_javascripts_from_load_paths(:spec)
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'cup/server/app'
3
+
4
+ describe Cup::Server::App do
5
+ def app
6
+ Cup::Server::App
7
+ end
8
+
9
+ it 'should serve public from the cup directory' do
10
+ app.settings.public_folder.should == Cup::Directory.current.path.to_s
11
+ end
12
+
13
+ it 'should serve views and public from the cup/views directory' do
14
+ app.settings.views.should == File.expand_path('../../../../views', __FILE__)
15
+ end
16
+
17
+ it "should render concatenated output at /concatenate" do
18
+ get '/concatenate'
19
+ last_response.should be_ok
20
+ last_response.content_type.should include 'text/javascript'
21
+ end
22
+
23
+ it "should render concatenated output at /minify" do
24
+ get '/minify'
25
+ last_response.should be_ok
26
+ last_response.content_type.should include 'text/javascript'
27
+ end
28
+
29
+ it "should render /" do
30
+ get '/'
31
+ last_response.should be_ok
32
+ end
33
+
34
+ it "should render /debug" do
35
+ get '/debug'
36
+ last_response.should be_ok
37
+ end
38
+
39
+ it "should render /empty" do
40
+ get '/empty'
41
+ last_response.should be_ok
42
+ end
43
+
44
+ it "should render /spec" do
45
+ get '/spec'
46
+ last_response.should be_ok
47
+ end
48
+
49
+ it "should render /spec/concatenated" do
50
+ get '/spec/concatenated'
51
+ last_response.should be_ok
52
+ end
53
+
54
+ it "should render /spec/minified" do
55
+ get '/spec/minified'
56
+ last_response.should be_ok
57
+ end
58
+
59
+ it "should render /spec/visual" do
60
+ get '/spec/visual'
61
+ last_response.should be_ok
62
+ end
63
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'cup/server/visual_specs'
3
+
4
+ describe Cup::Server::VisualSpecs, '.get' do
5
+
6
+ subject { Cup::Server::VisualSpecs.get }
7
+
8
+ it { subject.should be_instance_of Hash }
9
+
10
+ # should match the number of generated valid visual specs
11
+ it { subject.values.count.should == 6 }
12
+
13
+ context 'hrefs' do
14
+ subject { Cup::Server::VisualSpecs.get.values.map{|vs| vs.href } }
15
+
16
+ it { should include '/spec/visual/visual2'}
17
+ it { should include '/spec/visual/visual1'}
18
+ it { should include '/spec/visual/subdir/visual1'}
19
+ it { should include '/spec/visual/subdir/visual2'}
20
+ end
21
+
22
+ context 'names' do
23
+ subject { Cup::Server::VisualSpecs.get.values.map{|vs| vs.name } }
24
+
25
+ it { should include 'visual2'}
26
+ it { should include 'visual1'}
27
+ it { should include 'subdir/visual1'}
28
+ it { should include 'subdir/visual2'}
29
+ end
30
+ end
data/spec/env.rb ADDED
@@ -0,0 +1,2 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ ENV['RACK_ENV'] = 'test'
data/spec/spec_helper.rb CHANGED
@@ -1 +1,28 @@
1
- $:.push File.expand_path('../lib', __FILE__)
1
+ require 'env'
2
+
3
+ require 'rspec'
4
+ require 'shoulda'
5
+ require 'rack/test'
6
+ require 'ruby-debug'
7
+ require 'support/macros'
8
+ require 'support/stub_helpers'
9
+ require 'support/javascript_load_order_acceptor'
10
+ require 'support/javascripts_matchers'
11
+
12
+ require 'cup/directory'
13
+ stub_current_directory
14
+ require 'cup/command_line'
15
+ stub_create_helper_downloaders
16
+
17
+ RSpec.configure do |config|
18
+
19
+ config.include Rack::Test::Methods
20
+ config.include Support::Macros
21
+
22
+ config.before(:all) do
23
+ remove_test_example
24
+ generate_test_example
25
+ end
26
+
27
+ config.after(:all) { remove_test_example }
28
+ end
@@ -0,0 +1,63 @@
1
+ require 'statemachine'
2
+ # a state machine for checking the include order of javascripts
3
+ class JavascriptLoadOrderAcceptor
4
+
5
+ def initialize
6
+ @sm = Statemachine.build do
7
+
8
+ trans :vendor, :build, :build
9
+ trans :vendor, :vendor, :vendor
10
+ trans :vendor, :spec, :spec
11
+ trans :vendor, :lib, :lib
12
+ trans :vendor, :src, :src
13
+
14
+ trans :spec, :build, :build
15
+ trans :spec, :vendor, :error
16
+ trans :spec, :spec, :spec
17
+ trans :spec, :lib, :lib
18
+ trans :spec, :src, :src
19
+
20
+ trans :lib, :vendor, :error
21
+ trans :lib, :build, :error
22
+ trans :lib, :spec, :error
23
+ trans :lib, :lib, :lib
24
+ trans :lib, :src, :src
25
+
26
+ trans :src, :vendor, :error
27
+ trans :src, :build, :error
28
+ trans :src, :spec, :error
29
+ trans :src, :lib, :error
30
+ trans :src, :src, :src
31
+
32
+ trans :build, :vendor, :error
33
+ trans :build, :build, :error
34
+ trans :build, :spec, :error
35
+ trans :build, :lib, :error
36
+ trans :build, :src, :error
37
+
38
+ end
39
+ end
40
+
41
+ def accepts? javascripts
42
+ javascripts.each{ |javascript_path| input javascript_path }
43
+
44
+ accept = @sm.state != :error
45
+ @sm.reset
46
+
47
+ accept
48
+ end
49
+
50
+ def input javascript_path
51
+
52
+ regex = /(.\/)?([^\/]+)(\/)/
53
+ matches = regex.match(javascript_path)
54
+ dir = matches[2] if matches
55
+
56
+ begin
57
+ @sm.process_event dir.to_sym
58
+ rescue Statemachine::TransitionMissingException => e
59
+ end
60
+
61
+ nil
62
+ end
63
+ end
@@ -0,0 +1,22 @@
1
+ RSpec::Matchers.define :include_javascripts_from_load_paths do |*expected|
2
+
3
+ match do |actual|
4
+ expected.all? do |e|
5
+ actual.any? do |a|
6
+ /(\.\/)?(#{e})\// =~ a
7
+ end
8
+ end
9
+ end
10
+
11
+ failure_message_for_should do |actual|
12
+ "expected that #{actual} would include files from #{expected}"
13
+ end
14
+
15
+ failure_message_for_should_not do |actual|
16
+ "expected that #{actual} would not include files from #{expected}"
17
+ end
18
+
19
+ description do
20
+ "include files from #{expected}"
21
+ end
22
+ end
@@ -0,0 +1,74 @@
1
+ require 'pathname'
2
+ require 'rake'
3
+
4
+ module Support
5
+ module Macros
6
+ include RakeFileUtils
7
+ RakeFileUtils.verbose_flag = false
8
+
9
+ def test_example_cup_name
10
+ 'cup_test_example'
11
+ end
12
+
13
+ def cup_directory
14
+ Cup::Directory.new test_example_cup_path
15
+ end
16
+
17
+ def test_example_cup_path
18
+ Pathname.new test_example_cup_name
19
+ end
20
+
21
+ def generate_test_example
22
+ require 'cup/command_line'
23
+
24
+ cli = Cup::CommandLine.new
25
+ cli.create(test_example_cup_name)
26
+
27
+ build_dir = "#{test_example_cup_name}/build"
28
+ mkdir build_dir
29
+
30
+ touch "#{test_example_cup_name}/build/#{test_example_cup_name}.js"
31
+ touch "#{test_example_cup_name}/build/#{test_example_cup_name}.min.js"
32
+ touch "#{test_example_cup_name}/license.txt"
33
+
34
+ %w[vendor lib spec src].each do |dir|
35
+ path = "#{test_example_cup_name}/#{dir}"
36
+ subdir = "#{path}/subdir"
37
+ mkdir_p subdir
38
+
39
+ touch "#{path}/README"
40
+ touch "#{path}/image.jpg"
41
+
42
+ name = dir.gsub('/', '_')
43
+
44
+ 3.times do |i|
45
+ touch "#{path}/#{name}#{i}.js"
46
+ touch "#{path}/#{name}#{i}.css"
47
+ 2.times do |j|
48
+ touch "#{subdir}/#{name}#{j}.js"
49
+ touch "#{subdir}/#{name}#{j}.css"
50
+ end
51
+ end
52
+ end
53
+
54
+ visuals_path = test_example_cup_path + 'spec' + 'visual'
55
+ visuals_subdir_path = visuals_path + 'subdir'
56
+
57
+ mkdir_p visuals_subdir_path
58
+
59
+ 3.times do |i|
60
+ touch visuals_path + "visual#{i}.slim"
61
+ touch visuals_path + "visual#{i}.js"
62
+ touch visuals_subdir_path + "visual#{i}.js"
63
+ touch visuals_subdir_path + "visual#{i}.slim"
64
+ end
65
+
66
+ test_example_cup_name
67
+ end
68
+
69
+ def remove_test_example
70
+ rm_r test_example_cup_name if Dir.exists? test_example_cup_name
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,30 @@
1
+
2
+ # to speed up specs and ensure specs work offline
3
+ def stub_create_helper_downloaders
4
+ Cup::CommandLine::Helper.module_eval do
5
+
6
+ def get_jquery
7
+ "\"#{__FILE__} mocked download of http://code.jquery.com/jquery.min.js\""
8
+ end
9
+
10
+ def download_jasmine
11
+ %x{
12
+ touch #{root + 'vendor/jasmine.js'}
13
+ touch #{root + 'vendor/jasmine-html.js'}
14
+ touch #{root + 'vendor/jasmine.css'}
15
+ }
16
+ end
17
+ end
18
+ end
19
+
20
+ def stub_current_directory
21
+ Cup::Directory.instance_eval do
22
+
23
+ # ordinarily this would be the current working directory
24
+ # for testing we must test within a generated directory
25
+ def current
26
+ extend Support::Macros
27
+ Cup::Directory.new(test_example_cup_path)
28
+ end
29
+ end
30
+ end
data/views/blank.slim ADDED
@@ -0,0 +1,9 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title = name
5
+
6
+ - for javascript in javascripts do
7
+ script src=javascript type='text/javascript'
8
+ body
9
+ == yield
data/views/cup.coffee ADDED
@@ -0,0 +1,4 @@
1
+ jQuery(document).ready ->
2
+ jQuery('#cup_header nav a').each (i, e) ->
3
+ if e.href == document.location.href
4
+ jQuery(e).addClass 'current'