pig-spec 0.0.2

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