rake-pipeline 0.5.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,149 @@
1
+ require "rake-pipeline/middleware"
2
+ require "rake-pipeline/filters"
3
+ require "rack/test"
4
+
5
+ describe "Rake::Pipeline Middleware" do
6
+ include Rack::Test::Methods
7
+
8
+ ConcatFilter = Rake::Pipeline::SpecHelpers::Filters::ConcatFilter
9
+
10
+ class StripAssertsFilter < Rake::Pipeline::Filter
11
+ def generate_output(inputs, output)
12
+ inputs.each do |input|
13
+ output.write input.read.gsub(%r{^\s*assert\(.*\)\s*;?\s*$}m, '')
14
+ end
15
+ end
16
+ end
17
+
18
+ inputs = {
19
+ "app/javascripts/jquery.js" => "var jQuery = {};\n",
20
+
21
+ "app/javascripts/sproutcore.js" => <<-HERE.gsub(/^ {6}/, ''),
22
+ var SC = {};
23
+ assert(SC);
24
+ SC.hi = function() { console.log("hi"); };
25
+ HERE
26
+
27
+ "app/index.html" => "<html>HI</html>",
28
+ "app/javascripts/index.html" => "<html>JAVASCRIPT</html>",
29
+ "app/empty_dir" => nil
30
+ }
31
+
32
+ expected_output = <<-HERE.gsub(/^ {4}/, '')
33
+ var jQuery = {};
34
+ var SC = {};
35
+
36
+ SC.hi = function() { console.log("hi"); };
37
+ HERE
38
+
39
+ app = middleware = pipeline = nil
40
+
41
+ before do
42
+ app = lambda { |env| [404, {}, ['not found']] }
43
+
44
+ pipeline = Rake::Pipeline.build do
45
+ input tmp, "app/**/*"
46
+
47
+ match "*.js" do
48
+ filter(ConcatFilter) { "javascripts/application.js" }
49
+ filter(StripAssertsFilter) { |input| input }
50
+ end
51
+
52
+ # copy the rest
53
+ filter(ConcatFilter) { |input| input.sub(/^app\//, '') }
54
+
55
+ output "public"
56
+ end
57
+
58
+ middleware = Rake::Pipeline::Middleware.new(app, pipeline)
59
+
60
+ inputs.each do |name, string|
61
+ path = File.join(tmp, name)
62
+ if string
63
+ mkdir_p File.dirname(path)
64
+ File.open(path, "w") { |file| file.write(string) }
65
+ else
66
+ mkdir_p path
67
+ end
68
+ end
69
+
70
+ get "/javascripts/application.js"
71
+ end
72
+
73
+ let(:app) { middleware }
74
+
75
+ it "returns files relative to the output directory" do
76
+ last_response.should be_ok
77
+
78
+ last_response.body.should == expected_output
79
+ last_response.headers["Content-Type"].should == "application/javascript"
80
+ end
81
+
82
+ it "updates the output when files change" do
83
+ age_existing_files
84
+
85
+ File.open(File.join(tmp, "app/javascripts/jquery.js"), "w") do |file|
86
+ file.write "var jQuery = {};\njQuery.trim = function() {};\n"
87
+ end
88
+
89
+ expected = <<-HERE.gsub(/^ {6}/, '')
90
+ var jQuery = {};
91
+ jQuery.trim = function() {};
92
+ var SC = {};
93
+
94
+ SC.hi = function() { console.log("hi"); };
95
+ HERE
96
+
97
+ get "/javascripts/application.js"
98
+
99
+ last_response.body.should == expected
100
+ last_response.headers["Content-Type"].should == "application/javascript"
101
+ end
102
+
103
+ it "updates the output when new files are added" do
104
+ age_existing_files
105
+
106
+ File.open(File.join(tmp, "app/javascripts/history.js"), "w") do |file|
107
+ file.write "var History = {};\n"
108
+ end
109
+
110
+ expected = <<-HERE.gsub(/^ {6}/, '')
111
+ var History = {};
112
+ var jQuery = {};
113
+ var SC = {};
114
+
115
+ SC.hi = function() { console.log("hi"); };
116
+ HERE
117
+
118
+ get "/javascripts/application.js"
119
+
120
+ last_response.body.should == expected
121
+ last_response.headers["Content-Type"].should == "application/javascript"
122
+ end
123
+
124
+ it "returns index.html for directories" do
125
+ get "/"
126
+
127
+ last_response.body.should == "<html>HI</html>"
128
+ last_response.headers["Content-Type"].should == "text/html"
129
+
130
+ get "/javascripts"
131
+
132
+ last_response.body.should == "<html>JAVASCRIPT</html>"
133
+ last_response.headers["Content-Type"].should == "text/html"
134
+ end
135
+
136
+ it "ignores directories without index.html" do
137
+ get "/empty_dir"
138
+
139
+ last_response.body.should == "not found"
140
+ last_response.status.should == 404
141
+ end
142
+
143
+ it "falls back to the app" do
144
+ get "/zomg.notfound"
145
+
146
+ last_response.body.should == "not found"
147
+ last_response.status.should == 404
148
+ end
149
+ end
@@ -0,0 +1,160 @@
1
+ describe "Rake::Pipeline" do
2
+ ConcatFilter = Rake::Pipeline::SpecHelpers::Filters::ConcatFilter
3
+ StripAssertsFilter = Rake::Pipeline::SpecHelpers::Filters::StripAssertsFilter
4
+
5
+ let(:pipeline) { Rake::Pipeline.new }
6
+
7
+ it "accepts a input root" do
8
+ pipeline.input_root = "app/assets"
9
+ pipeline.input_root.should == File.expand_path("app/assets")
10
+ end
11
+
12
+ it "raises an exception on #relative_input_files if input_files are not provided" do
13
+ pipeline.input_root = "app/assets"
14
+ lambda { pipeline.input_files }.should raise_error(Rake::Pipeline::Error)
15
+ end
16
+
17
+ it "raises an exception on #relative_input_files if input_root is not provided" do
18
+ pipeline.input_glob = "app/assets/javascripts/**/*.js"
19
+ lambda { pipeline.input_files }.should raise_error(Rake::Pipeline::Error)
20
+ end
21
+
22
+ it "accepts a temporary directory" do
23
+ pipeline.tmpdir = "tmp"
24
+ pipeline.tmpdir.should == File.expand_path("tmp")
25
+ end
26
+
27
+ it "accepts an output directory" do
28
+ pipeline.output_root = "public"
29
+ pipeline.output_root.should == File.expand_path("public")
30
+ end
31
+
32
+ it "accepts a rake application" do
33
+ app = Rake::Application.new
34
+ pipeline.rake_application = app
35
+ pipeline.rake_application.should == app
36
+ end
37
+
38
+ it "defaults the rake application to Rake.application" do
39
+ pipeline.rake_application.should == Rake.application
40
+ end
41
+
42
+ it "can have filters added to it" do
43
+ filter = ConcatFilter.new
44
+ pipeline.add_filter filter
45
+ end
46
+
47
+ shared_examples_for "when working with input" do
48
+ def input_file(path, root=File.join(tmp, "app/assets"))
49
+ Rake::Pipeline::FileWrapper.new root, path
50
+ end
51
+
52
+ let(:files) do
53
+ %w(javascripts/jquery.js javascripts/sproutcore.js).map do |filename|
54
+ input_file(filename)
55
+ end
56
+ end
57
+
58
+ before do
59
+ Rake.application = Rake::Application.new
60
+
61
+ files.each do |file|
62
+ mkdir_p File.dirname(file.fullpath)
63
+
64
+ File.open(file.fullpath, "w") do |file|
65
+ file.write "// This is #{file.path}\n"
66
+ end
67
+ end
68
+
69
+ pipeline.input_root = "app/assets"
70
+ setup_input(pipeline)
71
+ pipeline.output_root = "public"
72
+ end
73
+
74
+ it "accepts a list of relative input files" do
75
+ pipeline.input_files.should == files
76
+ end
77
+
78
+ it "configures the filters with outputs and inputs with #rake_tasks" do
79
+ concat = ConcatFilter.new
80
+ concat.output_name_generator = proc { |input| "javascripts/application.js" }
81
+
82
+ strip_asserts = StripAssertsFilter.new
83
+ strip_asserts.output_name_generator = proc { |input| input }
84
+
85
+ pipeline.add_filters concat, strip_asserts
86
+ pipeline.setup
87
+
88
+ concat.input_files.should == pipeline.input_files
89
+ strip_asserts.input_files.each { |file| file.root.should == concat.output_root }
90
+
91
+ strip_asserts.input_files.should == [input_file("javascripts/application.js", concat.output_root)]
92
+ strip_asserts.output_root.should == File.expand_path(pipeline.output_root)
93
+ end
94
+
95
+ describe "generating rake tasks" do
96
+ tasks = nil
97
+
98
+ before do
99
+ concat = ConcatFilter.new
100
+ concat.output_name_generator = proc { |input| "javascripts/application.js" }
101
+ pipeline.add_filter concat
102
+ end
103
+
104
+ it "generates rake tasks in Rake.application" do
105
+ pipeline.setup
106
+ tasks = pipeline.rake_tasks
107
+
108
+ tasks.size.should == 1
109
+ task = tasks[0]
110
+ task.name.should == File.join(pipeline.output_root, "javascripts/application.js")
111
+
112
+ deps = task.prerequisites
113
+ deps.size.should == 2
114
+ deps[0].should == File.join(pipeline.input_root, "javascripts/jquery.js")
115
+ deps[1].should == File.join(pipeline.input_root, "javascripts/sproutcore.js")
116
+
117
+ Rake.application.tasks.size.should == 3
118
+ end
119
+
120
+ it "generates rake tasks is an alternate Rake::Application" do
121
+ app = Rake::Application.new
122
+ pipeline.rake_application = app
123
+ pipeline.setup
124
+ tasks = pipeline.rake_tasks
125
+
126
+ Rake.application.tasks.size.should == 0
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "using a glob for input files" do
132
+ it_behaves_like "when working with input"
133
+
134
+ def setup_input(pipeline)
135
+ pipeline.input_glob = "javascripts/**/*.js"
136
+ end
137
+ end
138
+
139
+ describe "using a glob containing directories for input files" do
140
+ it_behaves_like "when working with input"
141
+
142
+ def setup_input(pipeline)
143
+ pipeline.input_glob = "**/*"
144
+ end
145
+ end
146
+
147
+ describe "using an array for input files" do
148
+ it_behaves_like "when working with input"
149
+
150
+ def setup_input(pipeline)
151
+ Dir.chdir("app/assets") do
152
+ files = Dir["javascripts/**/*.js"]
153
+ wrappers = files.map do |file|
154
+ Rake::Pipeline::FileWrapper.new(File.join(tmp, "app/assets"), file)
155
+ end
156
+ pipeline.input_files = wrappers
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,240 @@
1
+ require "rake-pipeline/filters"
2
+
3
+ describe "A realistic pipeline" do
4
+
5
+ INPUTS = {
6
+
7
+ "app/javascripts/jquery.js" => <<-HERE,
8
+ var jQuery = {};
9
+ HERE
10
+
11
+ "app/javascripts/sproutcore.js" => <<-HERE,
12
+ var SC = {};
13
+ assert(SC);
14
+ SC.hi = function() { console.log("hi"); };
15
+ HERE
16
+
17
+ "app/stylesheets/jquery.css" => <<-HERE,
18
+ #jquery {
19
+ color: red;
20
+ }
21
+ HERE
22
+
23
+ "app/stylesheets/sproutcore.css" => <<-HERE,
24
+ #sproutcore {
25
+ color: green;
26
+ }
27
+ HERE
28
+
29
+ "app/index.html" => <<-HERE
30
+ <html></html>
31
+ HERE
32
+
33
+ }
34
+
35
+ EXPECTED_JS_OUTPUT = <<-HERE
36
+ var jQuery = {};
37
+ var SC = {};
38
+
39
+ SC.hi = function() { console.log("hi"); };
40
+ HERE
41
+
42
+ EXPECTED_CSS_OUTPUT = <<-HERE
43
+ #jquery {
44
+ color: red;
45
+ }
46
+ #sproutcore {
47
+ color: green;
48
+ }
49
+ HERE
50
+
51
+ EXPECTED_HTML_OUTPUT = <<-HERE
52
+ <html></html>
53
+ HERE
54
+
55
+ before do
56
+ Rake.application = Rake::Application.new
57
+
58
+ INPUTS.each do |name, string|
59
+ mkdir_p File.dirname(File.join(tmp, name))
60
+ File.open(File.join(tmp, name), "w") { |file| file.write(string) }
61
+ end
62
+ end
63
+
64
+ def input_wrapper(path)
65
+ Rake::Pipeline::FileWrapper.new(tmp, path)
66
+ end
67
+
68
+ def output_should_exist(expected = EXPECTED_JS_OUTPUT)
69
+ output = File.join(tmp, "public/javascripts/application.js")
70
+ temp = File.join(tmp, "temporary")
71
+
72
+ File.exists?(output).should be_true
73
+ File.exists?(temp).should be_true
74
+
75
+ File.read(output).should == expected
76
+ end
77
+
78
+ concat_filter = Rake::Pipeline::ConcatFilter
79
+ strip_asserts_filter = Rake::Pipeline::SpecHelpers::Filters::StripAssertsFilter
80
+
81
+ it "can successfully apply filters" do
82
+ concat = concat_filter.new
83
+ concat.input_files = INPUTS.keys.select { |key| key =~ /javascript/ }.map { |file| input_wrapper(file) }
84
+ concat.output_root = File.join(tmp, "temporary", "concat_filter")
85
+ concat.output_name_generator = proc { |input| "javascripts/application.js" }
86
+
87
+ strip_asserts = strip_asserts_filter.new
88
+ strip_asserts.input_files = concat.output_files
89
+ strip_asserts.output_root = File.join(tmp, "public")
90
+ strip_asserts.output_name_generator = proc { |input| input }
91
+
92
+ concat.generate_rake_tasks
93
+ Rake::Task.define_task(:default => strip_asserts.generate_rake_tasks)
94
+ Rake.application[:default].invoke
95
+
96
+ output_should_exist
97
+ end
98
+
99
+ it "can be configured using the pipeline" do
100
+ pipeline = Rake::Pipeline.new
101
+ pipeline.input_root = File.expand_path(tmp)
102
+ pipeline.output_root = File.expand_path("public")
103
+ pipeline.input_glob = "app/javascripts/*.js"
104
+ pipeline.tmpdir = "temporary"
105
+
106
+ concat = concat_filter.new
107
+ concat.output_name_generator = proc { |input| "javascripts/application.js" }
108
+
109
+ strip_asserts = strip_asserts_filter.new
110
+ strip_asserts.output_name_generator = proc { |input| input }
111
+
112
+ pipeline.add_filters(concat, strip_asserts)
113
+ pipeline.invoke
114
+
115
+ output_should_exist
116
+ end
117
+
118
+ describe "using the pipeline DSL" do
119
+
120
+ attr_reader :pipeline
121
+
122
+ shared_examples_for "the pipeline DSL" do
123
+ it "can be configured using the pipeline DSL" do
124
+ pipeline.invoke
125
+ output_should_exist
126
+ end
127
+
128
+ it "can be configured using the pipeline DSL with an alternate Rake application" do
129
+ pipeline.rake_application = Rake::Application.new
130
+ pipeline.invoke
131
+ output_should_exist
132
+ end
133
+
134
+ it "can be invoked repeatedly to reflected updated changes" do
135
+ pipeline.invoke
136
+ age_existing_files
137
+
138
+ File.open(File.join(tmp, "app/javascripts/jquery.js"), "w") do |file|
139
+ file.write "var jQuery = {};\njQuery.trim = function() {};\n"
140
+ end
141
+
142
+ expected = <<-HERE.gsub(/^ {10}/, '')
143
+ var jQuery = {};
144
+ jQuery.trim = function() {};
145
+ var SC = {};
146
+
147
+ SC.hi = function() { console.log("hi"); };
148
+ HERE
149
+
150
+ pipeline.invoke
151
+
152
+ output_should_exist(expected)
153
+ end
154
+
155
+ it "can be restarted to reflect new files" do
156
+ pipeline.invoke
157
+ age_existing_files
158
+
159
+ File.open(File.join(tmp, "app/javascripts/history.js"), "w") do |file|
160
+ file.write "var History = {};\n"
161
+ end
162
+
163
+ pipeline.invoke_clean
164
+
165
+ expected = <<-HERE.gsub(/^ {10}/, '')
166
+ var History = {};
167
+ var jQuery = {};
168
+ var SC = {};
169
+
170
+ SC.hi = function() { console.log("hi"); };
171
+ HERE
172
+
173
+ output_should_exist(expected)
174
+ end
175
+ end
176
+
177
+ describe "the raw pipeline DSL" do
178
+ it_behaves_like "the pipeline DSL"
179
+
180
+ before do
181
+ @pipeline = Rake::Pipeline.build do
182
+ tmpdir "temporary"
183
+ input tmp, "app/javascripts/*.js"
184
+ filter(concat_filter) { "javascripts/application.js" }
185
+ filter(strip_asserts_filter) { |input| input }
186
+ output "public"
187
+ end
188
+ end
189
+ end
190
+
191
+ describe "the raw pipeline DSL" do
192
+ it_behaves_like "the pipeline DSL"
193
+
194
+ before do
195
+ @pipeline = Rake::Pipeline.build do
196
+ tmpdir "temporary"
197
+ input tmp, "app/javascripts/*.js"
198
+ filter concat_filter, "javascripts/application.js"
199
+ filter strip_asserts_filter
200
+ output "public"
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "using the matcher spec" do
206
+
207
+ def output_should_exist(expected=EXPECTED_JS_OUTPUT)
208
+ super
209
+
210
+ css = File.join(tmp, "public/stylesheets/application.css")
211
+
212
+ File.exists?(css).should be_true
213
+ File.read(css).should == EXPECTED_CSS_OUTPUT
214
+
215
+ html = File.join(tmp, "public/index.html")
216
+ File.exists?(html).should be_true
217
+ File.read(html).should == EXPECTED_HTML_OUTPUT
218
+ end
219
+
220
+ it_behaves_like "the pipeline DSL"
221
+
222
+ before do
223
+ @pipeline = Rake::Pipeline.build do
224
+ tmpdir "temporary"
225
+ input File.join(tmp, "app"), "**/*.{js,css,html}"
226
+ output "public"
227
+
228
+ match "**/*.js" do
229
+ filter strip_asserts_filter
230
+ filter concat_filter, "javascripts/application.js"
231
+ end
232
+
233
+ match "**/*.css" do
234
+ filter concat_filter, "stylesheets/application.css"
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end