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,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