rake-pipeline 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,106 @@
1
+ # encoding: UTF-8
2
+
3
+ if "".respond_to?(:encode)
4
+ class String
5
+ def strip_heredoc
6
+ indent = scan(/^[ \t]*(?=\S)/).min
7
+ indent = indent ? indent.size : 0
8
+ gsub(/^[ \t]{#{indent}}/, '')
9
+ end
10
+ end
11
+
12
+ inputs = {
13
+ "app/javascripts/jquery.js" => <<-HERE.strip_heredoc,
14
+ var jQuery = { japanese: "こんにちは" };
15
+ HERE
16
+
17
+ "app/javascripts/sproutcore.js" => <<-HERE.strip_heredoc,
18
+ var SC = {};
19
+ assert(SC);
20
+ SC.hi = function() { console.log("こんにちは"); };
21
+ HERE
22
+ }
23
+
24
+ expected_output = <<-HERE.strip_heredoc
25
+ var jQuery = { japanese: "こんにちは" };
26
+ var SC = {};
27
+
28
+ SC.hi = function() { console.log("こんにちは"); };
29
+ HERE
30
+
31
+ describe "the pipeline's encoding handling" do
32
+ Filters = Rake::Pipeline::SpecHelpers::Filters
33
+
34
+ let(:inputs) { inputs }
35
+
36
+ def output_should_exist(expected, encoding="UTF-8")
37
+ output = File.join(tmp, "public/javascripts/application.js")
38
+
39
+ File.exists?(output).should be_true
40
+ output = File.read(output, :encoding => encoding)
41
+ output.should == expected
42
+ output.should be_valid_encoding
43
+ end
44
+
45
+ def create_files
46
+ inputs.each do |name, contents|
47
+ filename = File.join(tmp, name)
48
+ mkdir_p File.dirname(filename)
49
+
50
+ File.open(filename, "w:#{encoding}") do |file|
51
+ file.write contents.encode(encoding)
52
+ end
53
+ end
54
+ end
55
+
56
+ before do
57
+ create_files
58
+
59
+ @pipeline = Rake::Pipeline.build do
60
+ tmpdir "temporary"
61
+ input tmp, "app/javascripts/*.js"
62
+ filter Filters::ConcatFilter, "javascripts/application.js"
63
+ filter Filters::StripAssertsFilter
64
+ output "public"
65
+ end
66
+ end
67
+
68
+ describe "when the input is UTF-8" do
69
+ let(:encoding) { "UTF-8" }
70
+
71
+ it "creates the correct file" do
72
+ @pipeline.invoke
73
+ output_should_exist(expected_output)
74
+ end
75
+ end
76
+
77
+ describe "when the input is not UTF-8" do
78
+ let(:encoding) { "EUC-JP" }
79
+
80
+ it "raises an exception" do
81
+ lambda { @pipeline.invoke }.should raise_error(Rake::Pipeline::EncodingError, /not valid UTF-8/)
82
+ end
83
+ end
84
+
85
+ describe "when dealing with only BINARY-type filters" do
86
+ let(:encoding) { "EUC-JP" }
87
+
88
+ it "does not raise an exception" do
89
+ pipeline = Rake::Pipeline.build do
90
+ tmpdir "temporary"
91
+ input tmp, "app/javascripts/*.js"
92
+ filter Filters::ConcatFilter, "javascripts/application.js"
93
+ output "public"
94
+ end
95
+
96
+ pipeline.invoke
97
+
98
+ expected = inputs.map do |filename, contents|
99
+ contents.encode("EUC-JP")
100
+ end.join
101
+
102
+ output_should_exist(expected.force_encoding("BINARY"), "BINARY")
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,105 @@
1
+ describe "Rake::Pipeline::FileWrapper" do
2
+ let(:file) { Rake::Pipeline::FileWrapper.new }
3
+ let(:root) { File.expand_path("app/assets") }
4
+ let(:jquery) { File.join(root, "javascripts/jquery.js") }
5
+
6
+ before do
7
+ file.root = root
8
+ file.path = "javascripts/jquery.js"
9
+ end
10
+
11
+ it "is equal to another FileWrapper if the root and path are the same" do
12
+ other = Rake::Pipeline::FileWrapper.new
13
+ other.root = root
14
+ other.path = "javascripts/jquery.js"
15
+
16
+ file.should == other
17
+ file.hash.should == other.hash
18
+ end
19
+
20
+ it "is not equal to another FileWrapper if the root is the same but the path is different" do
21
+ other = Rake::Pipeline::FileWrapper.new
22
+ other.root = root
23
+ other.path = "javascripts/jquery2.js"
24
+
25
+ file.should_not == other
26
+ end
27
+
28
+ it "is not equal to another FileWrapper if the root is different but the path is the same" do
29
+ other = Rake::Pipeline::FileWrapper.new
30
+ other.root = "/"
31
+ other.path = "javascripts/jquery.js"
32
+
33
+ file.should_not == other
34
+ end
35
+
36
+ it "has a fullpath" do
37
+ file.fullpath.should == jquery
38
+ end
39
+
40
+ it "it knows it doesn't exist when the file doesn't exist" do
41
+ file.exists?.should == false
42
+ end
43
+
44
+ it "knows it exists when the file exists" do
45
+ touch_p jquery
46
+ file.exists?.should == true
47
+ end
48
+
49
+ it "raises an exception if trying to #read a file that doesn't exist" do
50
+ lambda { file.read }.should raise_error(Errno::ENOENT)
51
+ end
52
+
53
+ it "returns the file's body when invoking #read on a file that does exist" do
54
+ touch_p jquery
55
+ body = "This. Is. jQuery!"
56
+ File.open(jquery, "w") { |file| file.write body }
57
+
58
+ file.read.should == body
59
+ end
60
+
61
+ it "creates a file with #create" do
62
+ new_file = file.create
63
+ new_file.should be_kind_of File
64
+
65
+ File.exists?(jquery).should == true
66
+
67
+ new_file.close
68
+ end
69
+
70
+ it "complains if trying to close an unopened file" do
71
+ lambda { file.close }.should raise_error(IOError)
72
+ end
73
+
74
+ it "closes a file created using #create with #close" do
75
+ new_file = file.create
76
+ new_file.closed?.should == false
77
+
78
+ file.close
79
+ new_file.closed?.should == true
80
+
81
+ lambda { file.close }.should raise_error(IOError)
82
+ end
83
+
84
+ it "complains if trying to write to a file that was not created" do
85
+ lambda { file.write "This. Is. jQuery" }.should raise_error(Rake::Pipeline::UnopenedFile)
86
+ end
87
+
88
+ it "supports a block form of create that closes the file at the end" do
89
+ file.create do |f|
90
+ f.write "HI"
91
+ end
92
+
93
+ File.exists?(jquery).should == true
94
+ File.read(jquery).should == "HI"
95
+ file.closed?.should == true
96
+ end
97
+
98
+ it "writes to the file system if the file was created" do
99
+ new_file = file.create
100
+ file.write "This. Is. jQuery"
101
+ new_file.close
102
+
103
+ file.read.should == "This. Is. jQuery"
104
+ end
105
+ end
@@ -0,0 +1,216 @@
1
+ describe "Rake::Pipeline::Filter" do
2
+ def input_file(path, file_root=input_root)
3
+ Rake::Pipeline::FileWrapper.new(file_root, path)
4
+ end
5
+
6
+ def output_file(path, file_root=output_root)
7
+ Rake::Pipeline::FileWrapper.new(file_root, path)
8
+ end
9
+
10
+ let(:filter) { Rake::Pipeline::Filter.new }
11
+ let(:input_root) { File.join(tmp, "app/assets") }
12
+ let(:output_root) { File.join(tmp, "filter1/app/assets") }
13
+ let(:input_files) do
14
+ %w(jquery.js jquery-ui.js sproutcore.js).map { |f| input_file(f) }
15
+ end
16
+
17
+ it "accepts a series of FileWrapper objects for the input" do
18
+ filter.input_files = input_files
19
+ filter.input_files.should == input_files
20
+ end
21
+
22
+ it "accepts a root directory for the outputs" do
23
+ path = File.expand_path(tmp, "filter1/app/assets")
24
+ filter.output_root = path
25
+ filter.output_root.should == path
26
+ end
27
+
28
+ it "accepts a Rake::Application to install tasks into" do
29
+ app = Rake::Application.new
30
+ filter.rake_application = app
31
+ filter.rake_application.should == app
32
+ end
33
+
34
+ it "makes Rake.application the default rake_application" do
35
+ filter.rake_application.should == Rake.application
36
+ end
37
+
38
+ it "accepts a proc to convert the input name into an output name" do
39
+ conversion = proc { |input| input }
40
+ filter.output_name_generator = conversion
41
+ filter.output_name_generator.should == conversion
42
+ end
43
+
44
+ it "accepts a block constructor argument to convert the input name into an output name" do
45
+ conversion = proc { |input| "application.js" }
46
+ new_filter = Rake::Pipeline::Filter.new(&conversion)
47
+ new_filter.output_name_generator.should == conversion
48
+ end
49
+
50
+ describe "using the output_name proc to converting the input names into a hash" do
51
+ before do
52
+ filter.output_root = output_root
53
+ filter.input_files = input_files
54
+ end
55
+
56
+ it "with a simple output_name proc that outputs to a single file" do
57
+ output_name_generator = proc { |input| "application.js" }
58
+ filter.output_name_generator = output_name_generator
59
+
60
+ filter.outputs.should == {
61
+ output_file("application.js") => input_files
62
+ }
63
+
64
+ filter.output_files.should == [output_file("application.js")]
65
+ end
66
+
67
+ it "with a 1:1 output_name proc" do
68
+ output_name_generator = proc { |input| input }
69
+ filter.output_name_generator = output_name_generator
70
+ outputs = filter.outputs
71
+
72
+ outputs.keys.sort.should == input_files.map { |f| output_file(f.path) }.sort
73
+ outputs.values.flatten.sort.should == input_files.sort
74
+
75
+ filter.output_files.should == input_files.map { |file| output_file(file.path) }
76
+ end
77
+
78
+ it "with a more complicated proc" do
79
+ output_name_generator = proc { |input| input.split(/[-.]/, 2).first + ".js" }
80
+ filter.output_name_generator = output_name_generator
81
+ outputs = filter.outputs
82
+
83
+ outputs.keys.should == [output_file("jquery.js"), output_file("sproutcore.js")]
84
+ outputs.values.should == [[input_file("jquery.js"), input_file("jquery-ui.js")], [input_file("sproutcore.js")]]
85
+
86
+ filter.output_files.should == [output_file("jquery.js"), output_file("sproutcore.js")]
87
+ end
88
+ end
89
+
90
+ describe "generates rake tasks" do
91
+ class TestFilter < Rake::Pipeline::Filter
92
+ attr_accessor :generate_output_block
93
+
94
+ def generate_output(inputs, output)
95
+ generate_output_block.call(inputs, output)
96
+ end
97
+ end
98
+
99
+ let(:filter) { TestFilter.new }
100
+ let(:input_root) { File.join(tmp, "app/assets") }
101
+ let(:output_root) { File.join(tmp, "filter1/app/assets") }
102
+ let(:input_files) do
103
+ %w(jquery.js jquery-ui.js sproutcore.js).map do |file|
104
+ input_file("javascripts/#{file}")
105
+ end
106
+ end
107
+
108
+ before do
109
+ Rake.application = Rake::Application.new
110
+ filter.output_root = output_root
111
+ filter.input_files = input_files
112
+ end
113
+
114
+ def output_task(path, app=Rake.application)
115
+ app.define_task(Rake::FileTask, File.join(output_root, path))
116
+ end
117
+
118
+ def input_task(path)
119
+ Rake::FileTask.define_task(File.join(input_root, path))
120
+ end
121
+
122
+ it "does not generate Rake tasks onto Rake.application if an alternate application is supplied" do
123
+ app = Rake::Application.new
124
+ filter.rake_application = app
125
+ filter.output_name_generator = proc { |input| input }
126
+ filter.generate_rake_tasks
127
+ tasks = filter.rake_tasks
128
+
129
+ input_files.each do |file|
130
+ task = output_task(file.path, app)
131
+ tasks.include?(task).should == true
132
+ Rake.application.tasks.include?(task).should == false
133
+ app.tasks.include?(task).should == true
134
+ end
135
+ end
136
+
137
+ it "with a simple output_name proc that outputs to a single file" do
138
+ filter_runs = 0
139
+
140
+ filter.output_name_generator = proc { |input| "javascripts/application.js" }
141
+ filter.generate_output_block = proc do |inputs, output|
142
+ inputs.should == input_files
143
+ output.should == output_file("javascripts/application.js")
144
+
145
+ filter_runs += 1
146
+ end
147
+
148
+ filter.generate_rake_tasks
149
+ tasks = filter.rake_tasks
150
+ tasks.should == [output_task("javascripts/application.js")]
151
+ tasks[0].prerequisites.should == input_files.map { |i| i.fullpath }
152
+
153
+ tasks.each(&:invoke)
154
+
155
+ filter_runs.should == 1
156
+ end
157
+
158
+ it "with a 1:1 output_name proc" do
159
+ filter_runs = 0
160
+
161
+ filter.output_name_generator = proc { |input| input }
162
+ filter.generate_output_block = proc do |inputs, output|
163
+ inputs.should == [input_file(output.path)]
164
+
165
+ filter_runs += 1
166
+ end
167
+
168
+ filter.generate_rake_tasks
169
+ tasks = filter.rake_tasks
170
+ tasks.sort.should == input_files.map { |file| output_task(file.path) }.sort
171
+ tasks.each do |task|
172
+ name = task.name.sub(/^#{Regexp.escape(output_root)}/, '')
173
+ prereq = File.join(input_root, name)
174
+ task.prerequisites.should == [prereq]
175
+ end
176
+
177
+ tasks.each(&:invoke)
178
+
179
+ filter_runs.should == 3
180
+ end
181
+
182
+ it "with a more complicated proc" do
183
+ filter_runs = 0
184
+
185
+ filter.output_name_generator = proc { |input| input.match(%r{javascripts/[^-.]*})[0] + ".js" }
186
+ filter.generate_output_block = proc do |inputs, output|
187
+ if output.path == "javascripts/jquery.js"
188
+ inputs.should == [input_file("javascripts/jquery.js"), input_file("javascripts/jquery-ui.js")]
189
+ output.should == output_file("javascripts/jquery.js")
190
+ elsif output.path == "javascripts/sproutcore.js"
191
+ inputs.should == [input_file("javascripts/sproutcore.js")]
192
+ output.should == output_file("javascripts/sproutcore.js")
193
+ else
194
+ flunk
195
+ end
196
+
197
+ filter_runs += 1
198
+ end
199
+
200
+ filter.generate_rake_tasks
201
+ tasks = filter.rake_tasks
202
+ tasks.sort.should == [output_task("javascripts/jquery.js"), output_task("javascripts/sproutcore.js")].sort
203
+
204
+ tasks.sort[0].prerequisites.should == [
205
+ File.join(input_root, "javascripts/jquery.js"),
206
+ File.join(input_root, "javascripts/jquery-ui.js")
207
+ ]
208
+
209
+ tasks.sort[1].prerequisites.should == [File.join(input_root, "javascripts/sproutcore.js")]
210
+
211
+ tasks.each(&:invoke)
212
+
213
+ filter_runs.should == 2
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,105 @@
1
+ describe "a matcher" do
2
+ sep = File::SEPARATOR
3
+
4
+ before do
5
+ @matcher = Rake::Pipeline::Matcher.new
6
+ @files = %w(jquery.js sproutcore.js sproutcore.css).map do |file|
7
+ file_wrapper(file)
8
+ end
9
+
10
+ @matcher.input_files = @files
11
+ end
12
+
13
+ def file_wrapper(file, options={})
14
+ root = options[:root] || tmp
15
+ encoding = options[:encoding] || "UTF-8"
16
+ Rake::Pipeline::FileWrapper.new(root, file, encoding)
17
+ end
18
+
19
+ it "accepts input files" do
20
+ @matcher.input_files.should == @files
21
+ end
22
+
23
+ it "can access its glob" do
24
+ @matcher.glob = "*.js"
25
+ @matcher.glob.should == "*.js"
26
+ end
27
+
28
+ it "only processes files matching the matcher" do
29
+ @matcher.glob = "*.js"
30
+ @matcher.output_root = "tmp1"
31
+
32
+ concat = Rake::Pipeline::ConcatFilter.new
33
+ concat.output_name_generator = proc { |input| "app.js" }
34
+ @matcher.add_filter concat
35
+
36
+ @matcher.setup
37
+
38
+ concat.input_files.should == [
39
+ file_wrapper("jquery.js", :encoding => "BINARY"),
40
+ file_wrapper("sproutcore.js", :encoding => "BINARY")
41
+ ]
42
+
43
+ @matcher.output_files.should == [
44
+ file_wrapper("app.js", :root => File.join(tmp, "tmp1")),
45
+ file_wrapper("sproutcore.css")
46
+ ]
47
+ end
48
+
49
+ def should_match_glob(glob, files)
50
+ @matcher.glob = glob
51
+ @matcher.output_root = "tmp1"
52
+
53
+ concat = Rake::Pipeline::ConcatFilter.new
54
+ concat.output_name_generator = proc { |input| input }
55
+ @matcher.add_filter concat
56
+
57
+ @matcher.setup
58
+
59
+ @matcher.output_files.should == files
60
+ end
61
+
62
+ it "understands */* style globs" do
63
+ @matcher.input_files << file_wrapper("javascripts/backbone.js")
64
+
65
+ should_match_glob "*/*.js", [
66
+ file_wrapper("javascripts/backbone.js", :encoding => "BINARY", :root => File.join(tmp, "tmp1")),
67
+ file_wrapper("jquery.js"),
68
+ file_wrapper("sproutcore.js"),
69
+ file_wrapper("sproutcore.css")
70
+ ]
71
+
72
+ should_match_glob "proutcore*.js", [
73
+ file_wrapper("jquery.js"),
74
+ file_wrapper("sproutcore.js"),
75
+ file_wrapper("sproutcore.css"),
76
+ file_wrapper("javascripts/backbone.js")
77
+ ]
78
+ end
79
+
80
+ it "understands **/* style globs" do
81
+ @matcher.input_files << file_wrapper("javascripts/backbone.js")
82
+
83
+ output_root = File.join(tmp, "tmp1")
84
+
85
+ should_match_glob "**/*.js", [
86
+ file_wrapper("jquery.js", :encoding => "BINARY", :root => output_root),
87
+ file_wrapper("sproutcore.js", :encoding => "BINARY", :root => output_root),
88
+ file_wrapper("javascripts/backbone.js", :encoding => "BINARY", :root => output_root),
89
+ file_wrapper("sproutcore.css")
90
+ ]
91
+ end
92
+
93
+ it "understands {foo,bar}/* style globs" do
94
+ @matcher.input_files << file_wrapper("javascripts/backbone.js")
95
+
96
+ output_root = File.join(tmp, "tmp1")
97
+
98
+ should_match_glob "{jquery,sproutcore}.js", [
99
+ file_wrapper("jquery.js", :encoding => "BINARY", :root => output_root),
100
+ file_wrapper("sproutcore.js", :encoding => "BINARY", :root => output_root),
101
+ file_wrapper("sproutcore.css"),
102
+ file_wrapper("javascripts/backbone.js")
103
+ ]
104
+ end
105
+ end