pig-spec 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pig-unit.gemspec
4
+ gemspec
@@ -0,0 +1,56 @@
1
+ Summary/Description
2
+ ===================
3
+ PigSpec is a Ruby gem which can be used to test Pig scripts. It was designed to be easily integrated with the RSpec framework. It is loosely based on PigUnit (see: https://pig.apache.org/docs/r0.8.1/pigunit.html).
4
+
5
+ Building the gem:
6
+ -----------------
7
+ The PigSpec gem can be built with the following command:
8
+
9
+ ```bash
10
+ gem build pig-spec.gemspec
11
+ ```
12
+
13
+ Example usage:
14
+ --------------
15
+ ```ruby
16
+ require 'pig-spec'
17
+
18
+ describe 'something to be tested' do
19
+ include PigSpec
20
+
21
+ it 'should run the pig script and produce a single line of output' do
22
+ test_pig_script 'pig-0.6.0-core.jar', 'fake_script.pig', { "generated_file.txt" => "PigSpec creates this file. Current time is: #{Time.now}" }, { "output.csv" => "1,2,3,4" }, { "param1" => "foo", "param2" => "bar" }
23
+ verify_output(false).should == true
24
+ end
25
+ end
26
+ ```
27
+
28
+ If PigSpec is properly installed, you will see the following line (along with standard RSpec output) when the spec is run:
29
+
30
+ >Running the following command: java -jar pig-0.6.0-core.jar -x local -p param1=foo -p param2=bar fake_script.pig
31
+
32
+ Unless you've made some modifications to the above example (e.g. pointing it to an actual Pig JAR & script on your system), the above example will fail and produce output that looks like:
33
+
34
+ >Running the following command: java -jar pig-0.6.0-core.jar -x local -p param1=foo -p param2=bar fake_script.pig
35
+ >Unable to access jarfile pig-0.6.0-core.jar
36
+ >Pig script exited with non-zero exit code: 256.
37
+ >\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
38
+ >| Verifying Pig script output... |
39
+ >\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
40
+ >Pig script exited with non-zero exit code: 256.
41
+ >F
42
+ >
43
+ >Failures:
44
+ >
45
+ > 1) something to be tested should run the pig script and produce a single line of output
46
+ > Failure/Error: verify_output(false).should == true
47
+ > expected: true
48
+ > got: false (using ==)
49
+ > # ./spec/example_spec.rb:8
50
+ >
51
+ >Finished in 0.0131 seconds
52
+ >1 example, 1 failure
53
+ >
54
+ >Failed examples:
55
+ >
56
+ >rspec ./spec/example_spec.rb:6 # something to be tested should run the pig script and produce a single line of output
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ require "pig-spec/version"
2
+
3
+ require 'pig-spec/pig_unit_core'
4
+
5
+ module PigSpec
6
+ end
@@ -0,0 +1,130 @@
1
+ module PigSpec
2
+ require 'fileutils'
3
+ INPUT_DIR_PREFIX = "pig_test_"
4
+ PIG_CMD_PREFIX = "java -jar "
5
+
6
+ attr_reader :output_files, :input_dir, :error_stream, :stdout_stream, :exit_code
7
+ @@test_number = 0
8
+
9
+ def initialize
10
+ @output_files = {}
11
+ @input_dir = ""
12
+ @error_stream = $stderr
13
+ @stdout_stream = $stdout
14
+ @exit_code = 0
15
+ end
16
+
17
+ def self.test_number
18
+ @@test_number
19
+ end
20
+
21
+ def test_pig_script(pig_binary, pig_script, input_files_hash, output_files_hash, params)
22
+ @error_stream = error_stream
23
+ @stdout_stream = stdout_stream
24
+ @@test_number = @@test_number + 1
25
+
26
+ write_input_files(input_files_hash)
27
+ @output_files = output_files_hash
28
+ run_script(pig_binary, pig_script, params)
29
+ end
30
+
31
+ def build_pig_script_params(params)
32
+ if params.class != Hash
33
+ error_stream.puts "Params had unexpected class: #{params.class}"
34
+ return ""
35
+ end
36
+
37
+ params.reduce("") do |param_str, param|
38
+ param_str + (param_str.empty? ? "" : " ") + "-p " + param[0].to_s + "=" + param[1].to_s
39
+ end
40
+ end
41
+
42
+ def build_cmd_line(pig_binary, pig_script, params)
43
+ pig_params = build_pig_script_params(params)
44
+ pig_params = pig_params.empty? ? "" : "#{pig_params} "
45
+ "#{PIG_CMD_PREFIX}#{pig_binary} -x local #{pig_params}#{pig_script}"
46
+ end
47
+
48
+ def run_script(pig_binary, pig_script, params)
49
+ cmd_to_run = build_cmd_line(pig_binary, pig_script, params)
50
+ stdout_stream.puts("Running the following command: #{cmd_to_run}")
51
+ original_cwd = Dir.pwd
52
+ Dir.chdir(input_dir)
53
+ system cmd_to_run
54
+ @exit_code = $?
55
+ if exit_code != 0
56
+ error_stream.puts "Pig script exited with non-zero exit code: #{exit_code}."
57
+ end
58
+ Dir.chdir(original_cwd)
59
+ end
60
+
61
+ def write_input_files(input_files_hash)
62
+ @input_dir = File.expand_path(INPUT_DIR_PREFIX + PigSpec.test_number.to_i.to_s)
63
+
64
+ FileUtils.rm_rf(input_dir)
65
+ FileUtils.mkdir_p(input_dir)
66
+
67
+ if input_files_hash.class != Hash
68
+ error_stream.puts "Input files had unexpected class: #{input_files_hash.class}"
69
+ return
70
+ end
71
+
72
+ input_files_hash.keys.each do |file_name|
73
+ File.open(File.join(input_dir, file_name.to_s), "w") { |f| f.print(input_files_hash[file_name]) }
74
+ end
75
+ end
76
+
77
+ def print_mismatch_error(file)
78
+ error_stream.puts "Mismatch detected in '#{file}':"
79
+ end
80
+
81
+ def compare_pairs(file, pairs, mapping)
82
+ pairs.each do |pair|
83
+ if pair[0] != pair[1]
84
+ print_mismatch_error(file)
85
+ error_stream.puts "\tExpected line: '#{pair[mapping[:expected]]}'"
86
+ error_stream.puts "\tActual line: '#{pair[mapping[:actual]]}'"
87
+ return false
88
+ end
89
+ end
90
+ end
91
+
92
+ def verify_output(order_matters)
93
+ stdout_stream.puts "----------------------------------"
94
+ stdout_stream.puts "| Verifying Pig script output... |"
95
+ stdout_stream.puts "----------------------------------"
96
+ if output_files.class != Hash
97
+ error_stream.puts "Expected hash of expected output with (filename, file content) pairs. Unexpected class: #{output_files.class}"
98
+ return false
99
+ elsif output_files.size == 0
100
+ error_stream.puts "No output files to verify."
101
+ return false
102
+ end
103
+
104
+ if exit_code != 0
105
+ error_stream.puts "Pig script exited with non-zero exit code: #{exit_code}."
106
+ return false
107
+ end
108
+
109
+ all_output_matched = true
110
+ original_cwd = Dir.pwd
111
+ Dir.chdir(input_dir)
112
+
113
+ output_files.keys.each do |file|
114
+ file_lines_array = IO.read(file).split("\n")
115
+ file_lines_array = file_lines_array.sort if !order_matters
116
+
117
+ expected_output_array = output_files[file].split("\n")
118
+ expected_output_array = expected_output_array.sort if !order_matters
119
+
120
+ if (!compare_pairs(file, expected_output_array.zip(file_lines_array), { :expected => 0, :actual => 1 }) ||
121
+ !compare_pairs(file, file_lines_array.zip(expected_output_array), { :expected => 1, :actual => 0 }))
122
+ all_output_matched = false
123
+ next
124
+ end
125
+ end
126
+
127
+ Dir.chdir(original_cwd)
128
+ all_output_matched
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ module PigSpec
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pig-spec/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "pig-spec"
7
+ s.version = PigSpec::VERSION
8
+ s.authors = ["Matt Martin"]
9
+ s.email = ["matt [dot] martin [at] thinkbiganalytics [dot] com"]
10
+ s.homepage = "http://www.thinkbiganalytics.com/"
11
+ s.summary = %q{PigSpec is a PigUnit-like program implemented in Ruby.}
12
+ s.description = %q{PigSpec is a PigUnit-like program implemented in Ruby. It can be easily included into RSpec for running integration tests of existing Pig scripts.}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency "rspec"
20
+ end
@@ -0,0 +1,379 @@
1
+ require 'spec_helper'
2
+ require 'pig-spec/pig_unit_core'
3
+
4
+ class DummyPigSpec
5
+ include PigSpec
6
+ end
7
+
8
+ describe PigSpec do
9
+ subject { DummyPigSpec.new }
10
+
11
+ let(:pig_binary) { "pig-0.6.0-core.jar" }
12
+ let(:script_name) { "test.pig" }
13
+ let(:input_hash) { {"foo.txt" => "bar"} }
14
+ let(:output_hash) { {:foo => "baz"} }
15
+ let(:params) { {:param1 => "baz"} }
16
+ let(:unique_spec_dir) { PigSpec::INPUT_DIR_PREFIX.to_s + PigSpec.test_number.to_s }
17
+ let(:mock_stdout) { mock }
18
+ let(:mock_stderr) { mock }
19
+
20
+ before do
21
+ # Stub out stdout and stderr for tests where they are not relevant
22
+ subject.stub(:stdout_stream => mock_stdout)
23
+ mock_stdout.stub(:puts)
24
+
25
+ subject.stub(:error_stream => mock_stderr)
26
+ mock_stderr.stub(:puts)
27
+ end
28
+
29
+ def generate_unique_str
30
+ Time.now.to_f.to_s.gsub(".", "_")
31
+ end
32
+
33
+ describe '#test_pig_script' do
34
+ before do
35
+ subject.stub(:write_input_files)
36
+ subject.stub(:run_script)
37
+ end
38
+
39
+ it "should call the run_script method with the appropriate command line parameters" do
40
+ subject.should_receive(:run_script).with(pig_binary, script_name, params)
41
+ subject.test_pig_script(pig_binary, script_name, input_hash, output_hash, params)
42
+ end
43
+
44
+ it "should call the write_input_files method" do
45
+ subject.should_receive(:write_input_files).with(input_hash)
46
+ subject.test_pig_script(pig_binary, script_name, input_hash, output_hash, params)
47
+ end
48
+
49
+ it "should store the expected output files in an instance variable" do
50
+ subject.test_pig_script(pig_binary, script_name, input_hash, output_hash, params)
51
+ subject.output_files.should == output_hash
52
+ end
53
+
54
+ it "should increment the test number" do
55
+ prev_test_number = PigSpec.test_number
56
+ subject.test_pig_script(pig_binary, script_name, input_hash, output_hash, params)
57
+ PigSpec.test_number.should == prev_test_number + 1
58
+ end
59
+ end
60
+
61
+ describe '#write_input_files' do
62
+ before do
63
+ PigSpec.stub(:test_number).and_return(Time.now.to_i)
64
+ FileUtils.rm_rf(unique_spec_dir) if File.exists?(unique_spec_dir)
65
+ end
66
+
67
+ after do
68
+ FileUtils.rm_rf(unique_spec_dir) if File.exists?(unique_spec_dir)
69
+ end
70
+
71
+ let(:input_files) { {} }
72
+
73
+ context "when a temporary output directory does not already exist" do
74
+ it "should create a temporary directory using the test number" do
75
+ subject.write_input_files(input_files)
76
+ File.directory?(unique_spec_dir).should == true
77
+ end
78
+ end
79
+
80
+ context "when a temporary output directory already exists" do
81
+ before do
82
+ FileUtils.mkdir_p(unique_spec_dir)
83
+ File.open(File.join(unique_spec_dir, generate_unique_str + ".txt"), "w") { |f| f.print("hello world") }
84
+ end
85
+
86
+ it "should delete the existing directory contents" do
87
+ Dir.glob(File.join(unique_spec_dir, "*")).size.should > 0
88
+ subject.write_input_files(input_files)
89
+ Dir.glob(File.join(unique_spec_dir, "*")).size.should == 0
90
+ end
91
+ end
92
+
93
+ context "when the hash of input files is not empty" do
94
+ let(:input_files) { { "foo_#{generate_unique_str}.txt" => generate_unique_str,
95
+ "bar_#{generate_unique_str}.txt" => generate_unique_str } }
96
+
97
+ it "should create one file per hash key and use the hash keys as the filename and hash values as the content" do
98
+ subject.write_input_files(input_files)
99
+
100
+ input_files.keys.each do |file_name|
101
+ file_path = File.join(unique_spec_dir, file_name)
102
+ File.exists?(file_path).should == true
103
+ IO.readlines(file_path).join("").should == input_files[file_name]
104
+ end
105
+ end
106
+ end
107
+
108
+ context "when the paramter is not a hash" do
109
+ let(:input_files) { nil }
110
+ before do
111
+ input_files.class.should_not == Hash
112
+ end
113
+
114
+ it "should print an error and return an empty string" do
115
+ subject.should_receive(:error_stream).and_return(mock_stderr)
116
+ mock_stderr.should_receive(:puts).with("Input files had unexpected class: #{input_files.class}")
117
+
118
+ subject.write_input_files(input_files)
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#build_pig_script_params' do
124
+ context "when at least one paramter exists" do
125
+ let(:params) { {"foo" => 123, "bAr" => "234"} }
126
+ it "should create a string where the hash keys are the parameter names and the parameter values are the hash values" do
127
+ subject.build_pig_script_params(params).should == "-p foo=123 -p bAr=234"
128
+ end
129
+ end
130
+
131
+ context "when the hash of paramters is empty" do
132
+ let(:params) { {} }
133
+ it "should return an empty string" do
134
+ subject.build_pig_script_params(params).should == ""
135
+ end
136
+ end
137
+
138
+ context "when the paramter is not a hash" do
139
+ let(:params) { nil }
140
+ before do
141
+ params.class.should_not == Hash
142
+ end
143
+
144
+ it "should print an error and return an empty string" do
145
+ subject.should_receive(:error_stream).and_return(mock_stderr)
146
+ mock_stderr.should_receive(:puts).with("Params had unexpected class: #{params.class}")
147
+
148
+ subject.build_pig_script_params(params).should == ""
149
+ end
150
+ end
151
+ end
152
+
153
+ describe '#build_cmd_line' do
154
+ it "should call the build_pig_script_params helper method" do
155
+ subject.should_receive(:build_pig_script_params).with(params).and_return("-p fake=fake_value")
156
+ subject.build_cmd_line(pig_binary, script_name, params)
157
+ end
158
+
159
+ it "should build a string which joins a standard prefix with the flattened pig parameters and pig script name" do
160
+ subject.build_cmd_line(pig_binary, script_name, params).should == "#{PigSpec::PIG_CMD_PREFIX}#{pig_binary} -x local -p param1=baz #{script_name}"
161
+ end
162
+
163
+ context "when there are no Pig script parameters" do
164
+ let(:params) { {} }
165
+ it "should build a script which joins a standard prefix and the pig script name" do
166
+ subject.build_cmd_line(pig_binary, script_name, params).should == "#{PigSpec::PIG_CMD_PREFIX}#{pig_binary} -x local #{script_name}"
167
+ end
168
+ end
169
+ end
170
+
171
+ describe '#run_script' do
172
+ before do
173
+ Dir.stub(:chdir)
174
+ end
175
+
176
+ it "should call the build_cmd_line helper method" do
177
+ subject.should_receive(:build_cmd_line).with(pig_binary, script_name, params).and_return("echo 'echo' is a harmless command")
178
+ subject.run_script(pig_binary, script_name, params)
179
+ end
180
+
181
+ it "should print the command that it is running to stdout" do
182
+ subject.stub(:build_cmd_line => 'echo')
183
+ mock_stdout.should_receive(:puts).with("Running the following command: echo")
184
+ subject.run_script(pig_binary, script_name, params)
185
+ end
186
+
187
+ def echo_string_to_unique_file(base_dir)
188
+ unique_str = generate_unique_str
189
+ unique_filename = File.join(base_dir, "temp_" + unique_str + ".txt")
190
+ FileUtils.rm_rf(unique_filename) if File.exists?(unique_filename)
191
+
192
+ subject.stub(:build_cmd_line => 'echo "' + unique_str + '" > ' + unique_filename)
193
+
194
+ subject.run_script(pig_binary, script_name, params)
195
+ File.exists?(unique_filename).should == true
196
+ IO.readlines(unique_filename).join("") == unique_str
197
+
198
+ FileUtils.rm_rf(unique_filename)
199
+ end
200
+
201
+ it "should run the string returned by the build_cmd_line helper method" do
202
+ unique_filename = echo_string_to_unique_file(File.expand_path("."))
203
+ end
204
+
205
+ context "when the command fails" do
206
+ it "should print an error message with the appropriate exit code" do
207
+ subject.stub(:build_cmd_line => 'false')
208
+ system 'false'
209
+ false_exit_code = $?
210
+
211
+ subject.should_receive(:error_stream).and_return(mock_stderr)
212
+ mock_stderr.should_receive(:puts).with("Pig script exited with non-zero exit code: #{false_exit_code}.")
213
+
214
+ subject.exit_code.should == 0
215
+ subject.run_script(pig_binary, script_name, params)
216
+ subject.exit_code.should == false_exit_code
217
+ end
218
+ end
219
+
220
+ it "should run the command within the temporary directory created for this test" do
221
+ original_cwd = Dir.pwd
222
+ unique_dir = File.expand_path(FileUtils.mkdir_p(generate_unique_str))
223
+ subject.should_receive(:input_dir).and_return(unique_dir)
224
+
225
+ unique_filename = echo_string_to_unique_file(unique_dir)
226
+ Dir.pwd.should == original_cwd
227
+
228
+ FileUtils.rm_rf(unique_dir)
229
+ end
230
+ end
231
+
232
+ describe '#verify_output' do
233
+ let(:order_matters) { true }
234
+
235
+ it "should print a standard message letting the user know that it's about to start verifying output" do
236
+ mock_stdout.should_receive(:puts).with("----------------------------------")
237
+ mock_stdout.should_receive(:puts).with("| Verifying Pig script output... |")
238
+ mock_stdout.should_receive(:puts).with("----------------------------------")
239
+ subject.verify_output(order_matters)
240
+ end
241
+
242
+ context "when there is no expected output" do
243
+ before do
244
+ subject.stub(:output_files).and_return( {} )
245
+ end
246
+
247
+ it "should print an error message and return false" do
248
+ subject.should_receive(:error_stream).and_return(mock_stderr)
249
+ mock_stderr.should_receive(:puts).with("No output files to verify.")
250
+ subject.verify_output(order_matters).should == false
251
+ end
252
+ end
253
+
254
+ context "when the expected output is not a hash" do
255
+ before do
256
+ subject.stub(:output_files).and_return( nil )
257
+ end
258
+
259
+ it "should return false and print an error message" do
260
+ subject.should_receive(:error_stream).and_return(mock_stderr)
261
+ mock_stderr.should_receive(:puts).with("Expected hash of expected output with (filename, file content) pairs. Unexpected class: #{nil.class}")
262
+ subject.verify_output(order_matters).should == false
263
+ end
264
+ end
265
+
266
+ context "when there is one or more output files to compare and there are no type errors" do
267
+ let(:file_paths) { [File.join(generate_unique_str + ".txt"),
268
+ File.join(generate_unique_str + ".txt")] }
269
+ let(:file_contents) { ["hello world\ngoodbye world\nhi world\nhey world\nlater world\nbye world\n",
270
+ "hello universe\ngoodbye universe\nhi universe\nhey universe\nlater universe\nbye universe"] }
271
+ let(:actual_output) { Hash[*file_paths.zip(file_contents).flatten] }
272
+ let(:reordered_output) { actual_output.merge( {file_paths[0] => file_contents[0].split("\n").sort.join("\n")} ) }
273
+
274
+ before do
275
+ subject.stub(:input_dir).and_return(generate_unique_str)
276
+ FileUtils.mkdir_p(subject.input_dir)
277
+
278
+ actual_output.keys.each do |file_path|
279
+ File.open(File.join(subject.input_dir, file_path), "w") { |f| f.print(actual_output[file_path]) }
280
+ end
281
+
282
+ subject.stub(:output_files).and_return( actual_output )
283
+
284
+ reordered_output.should_not == actual_output
285
+ end
286
+
287
+ after do
288
+ FileUtils.rm_rf(subject.input_dir) if File.exists?(subject.input_dir)
289
+ end
290
+
291
+ it "should return false when the Pig script exits with a non-zero exit code" do
292
+ subject.stub(:exit_code).and_return(123)
293
+ subject.should_receive(:error_stream).and_return(mock_stderr)
294
+ mock_stderr.should_receive(:puts).with("Pig script exited with non-zero exit code: 123.")
295
+ subject.verify_output(order_matters).should == false
296
+ end
297
+
298
+ context "when the actual output has one or more lines than the expected output" do
299
+ let(:mismatch) { actual_output[file_paths[0]].split("\n")[0..-2].join("\n") }
300
+ before do
301
+ subject.stub(:output_files).and_return( actual_output.merge( file_paths[0] => mismatch ) )
302
+ end
303
+ it "should print the first extra line and return false" do
304
+ subject.should_receive(:error_stream).and_return(mock_stderr)
305
+ mock_stderr.should_receive(:puts).with("Mismatch detected in '#{file_paths[0]}':")
306
+ mock_stderr.should_receive(:puts).with("\tExpected line: ''")
307
+ mock_stderr.should_receive(:puts).with("\tActual line: '#{actual_output[file_paths[0]].split("\n")[-1]}'")
308
+ subject.verify_output(order_matters).should == false
309
+ end
310
+ end
311
+
312
+ context "when the expected output has one or more lines than the actual output" do
313
+ let(:mismatch) { actual_output[file_paths[0]] + "extra line\n" }
314
+ before do
315
+ subject.stub(:output_files).and_return( actual_output.merge( file_paths[0] => mismatch ) )
316
+ end
317
+ it "should print the first extra line and return false" do
318
+ subject.should_receive(:error_stream).and_return(mock_stderr)
319
+ mock_stderr.should_receive(:puts).with("Mismatch detected in '#{file_paths[0]}':")
320
+ mock_stderr.should_receive(:puts).with("\tExpected line: '#{mismatch.split("\n")[-1]}'")
321
+ mock_stderr.should_receive(:puts).with("\tActual line: ''")
322
+ subject.verify_output(order_matters).should == false
323
+ end
324
+ end
325
+
326
+ context "when output order matters" do
327
+ let(:order_matters) { true }
328
+
329
+ context "when the output is exactly the same as the file contents" do
330
+ it "should return true" do
331
+ subject.verify_output(order_matters).should == true
332
+ end
333
+ end
334
+
335
+ context "when the output is not exactly the same as the file contents" do
336
+ before do
337
+ subject.stub(:output_files).and_return( reordered_output )
338
+ end
339
+
340
+ it "should return false" do
341
+ subject.should_receive(:error_stream).and_return(mock_stderr)
342
+ mock_stderr.should_receive(:puts).with("Mismatch detected in '#{file_paths[0]}':")
343
+ mock_stderr.should_receive(:puts).with("\tExpected line: '#{reordered_output[file_paths[0]].split("\n")[0]}'")
344
+ mock_stderr.should_receive(:puts).with("\tActual line: '#{actual_output[file_paths[0]].split("\n")[0]}'")
345
+ subject.verify_output(order_matters).should == false
346
+ end
347
+ end
348
+ end
349
+
350
+ context "when output order doesn't matter" do
351
+ let(:order_matters) { false }
352
+
353
+ context "when expected output contains the same lines as the file, but in a different order" do
354
+ before do
355
+ subject.stub(:output_files).and_return( reordered_output )
356
+ end
357
+
358
+ it "should return true" do
359
+ subject.verify_output(order_matters).should == true
360
+ end
361
+ end
362
+
363
+ context "when expected output does not contain the same lines as the file" do
364
+ let(:mismatch) { reordered_output[file_paths[0]] + "2" }
365
+ before do
366
+ subject.stub(:output_files).and_return( reordered_output.merge( file_paths[0] => mismatch ) )
367
+ end
368
+ it "should return false" do
369
+ subject.should_receive(:error_stream).and_return(mock_stderr)
370
+ mock_stderr.should_receive(:puts).with("Mismatch detected in '#{file_paths[0]}':")
371
+ mock_stderr.should_receive(:puts).with("\tExpected line: '#{mismatch.split("\n")[-1]}'")
372
+ mock_stderr.should_receive(:puts).with("\tActual line: '#{mismatch[0, mismatch.size - 1].split("\n")[-1]}'")
373
+ subject.verify_output(order_matters).should == false
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end
379
+ end
@@ -0,0 +1,4 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'rspec'
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pig-spec
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Matt Martin
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-21 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :development
33
+ version_requirements: *id001
34
+ description: PigSpec is a PigUnit-like program implemented in Ruby. It can be easily included into RSpec for running integration tests of existing Pig scripts.
35
+ email:
36
+ - matt [dot] martin [at] thinkbiganalytics [dot] com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - README.md
47
+ - Rakefile
48
+ - lib/pig-spec.rb
49
+ - lib/pig-spec/pig_unit_core.rb
50
+ - lib/pig-spec/version.rb
51
+ - pig-spec.gemspec
52
+ - spec/pig-spec/pig_unit_core_spec.rb
53
+ - spec/spec_helper.rb
54
+ homepage: http://www.thinkbiganalytics.com/
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options: []
59
+
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.11
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: PigSpec is a PigUnit-like program implemented in Ruby.
87
+ test_files:
88
+ - spec/pig-spec/pig_unit_core_spec.rb
89
+ - spec/spec_helper.rb