pairwise 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/features/bugs/bad_arguments.feature +32 -0
- data/features/bugs/bad_yml.feature +21 -21
- data/features/generating_pairwise_data.feature +91 -66
- data/features/step_definitions/pairwise_data_steps.rb +14 -1
- data/features/support/env.rb +8 -2
- data/lib/pairwise.rb +2 -0
- data/lib/pairwise/cli.rb +12 -33
- data/lib/pairwise/input_data.rb +25 -0
- data/lib/pairwise/input_file.rb +59 -0
- data/spec/pairwise/cli_spec.rb +1 -1
- metadata +5 -2
data/VERSION.yml
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
Feature: Bad arguments
|
2
|
+
|
3
|
+
Scenario: Non existent file
|
4
|
+
When I run pairwise file_with_does_not_exist
|
5
|
+
And I should see in the errors
|
6
|
+
"""
|
7
|
+
No such file or directory
|
8
|
+
"""
|
9
|
+
|
10
|
+
Scenario: Existing folder
|
11
|
+
Given I have a folder "empty"
|
12
|
+
When I run pairwise empty/
|
13
|
+
Then I should see in the output
|
14
|
+
"""
|
15
|
+
Usage: pairwise
|
16
|
+
"""
|
17
|
+
|
18
|
+
Scenario: Unsupported input file type
|
19
|
+
Given I have the file "example.rar"
|
20
|
+
When I run pairwise example.rar
|
21
|
+
Then I should see in the errors
|
22
|
+
"""
|
23
|
+
Unsupported file type: rar
|
24
|
+
"""
|
25
|
+
|
26
|
+
Scenario: Unsupported input file without extension
|
27
|
+
Given I have the file "example"
|
28
|
+
When I run pairwise example
|
29
|
+
Then I should see in the errors
|
30
|
+
"""
|
31
|
+
Cannot determine file type for: example
|
32
|
+
"""
|
@@ -1,25 +1,25 @@
|
|
1
1
|
Feature: Bad yml
|
2
2
|
|
3
|
-
Scenario: Empty yml
|
4
|
-
|
5
|
-
|
3
|
+
Scenario: Empty yml
|
4
|
+
Given I have the yaml file "inputs.yml" containing:
|
5
|
+
"""
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
"""
|
8
|
+
When I run pairwise inputs.yml
|
9
|
+
Then it should not show any errors
|
10
|
+
And I should see in the output
|
11
|
+
"""
|
12
|
+
Error: 'inputs.yml' does not contain the right structure for me to generate the pairwise set!
|
13
|
+
"""
|
14
14
|
|
15
|
-
Scenario: yml with no lists
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
Scenario: yml with no lists
|
16
|
+
Given I have the yaml file "listey_inputs.yml" containing:
|
17
|
+
"""
|
18
|
+
mookey
|
19
|
+
"""
|
20
|
+
When I run pairwise listey_inputs.yml
|
21
|
+
Then it should not show any errors
|
22
|
+
And I should see in the output
|
23
|
+
"""
|
24
|
+
Error: 'listey_inputs.yml' does not contain the right structure for me to generate the pairwise set!
|
25
|
+
"""
|
@@ -3,45 +3,83 @@ Feature: Generating pairwise data
|
|
3
3
|
As a tester
|
4
4
|
I want a set of tests which is smaller than all the possible combinations of my specified inputs
|
5
5
|
|
6
|
-
Scenario: No input file specified
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
Scenario: No input file specified
|
7
|
+
When I run pairwise
|
8
|
+
Then I should see in the output
|
9
|
+
"""
|
10
|
+
Usage: pairwise [options] FILE.[yml|csv]
|
11
|
+
"""
|
12
|
+
|
13
|
+
Scenario: Ordered yaml inputs
|
14
|
+
Given I have the yaml file "inputs.yml" containing:
|
15
|
+
"""
|
16
|
+
- event with image: [Football, Basketball, Soccer]
|
17
|
+
- event without image: [Football, Basketball, Soccer]
|
18
|
+
- media: [Image, Video, Music]
|
19
|
+
"""
|
20
|
+
When I run pairwise inputs.yml
|
21
|
+
Then I should see the output
|
22
|
+
"""
|
23
|
+
| event with image | event without image | media |
|
24
|
+
| Football | Football | Image |
|
25
|
+
| Football | Basketball | Video |
|
26
|
+
| Football | Soccer | Music |
|
27
|
+
| Basketball | Football | Music |
|
28
|
+
| Basketball | Basketball | Image |
|
29
|
+
| Basketball | Soccer | Video |
|
30
|
+
| Soccer | Football | Video |
|
31
|
+
| Soccer | Basketball | Music |
|
32
|
+
| Soccer | Soccer | Image |
|
33
|
+
|
34
|
+
"""
|
35
|
+
|
36
|
+
Scenario: Unorderd yaml inputs
|
37
|
+
Given I have the yaml file "inputs.yml" containing:
|
38
|
+
"""
|
39
|
+
event with image: [Football, Basketball, Soccer]
|
40
|
+
event without image: [Football, Basketball, Soccer]
|
41
|
+
media: [Image, Video, Music]
|
42
|
+
"""
|
43
|
+
When I run pairwise inputs.yml
|
44
|
+
Then I should see the output
|
45
|
+
"""
|
46
|
+
| media | event without image | event with image |
|
47
|
+
| Image | Football | Football |
|
48
|
+
| Image | Basketball | Basketball |
|
49
|
+
| Image | Soccer | Soccer |
|
50
|
+
| Video | Football | Soccer |
|
51
|
+
| Video | Basketball | Football |
|
52
|
+
| Video | Soccer | Basketball |
|
53
|
+
| Music | Football | Basketball |
|
54
|
+
| Music | Basketball | Soccer |
|
55
|
+
| Music | Soccer | Football |
|
56
|
+
|
57
|
+
"""
|
12
58
|
|
13
|
-
Scenario:
|
14
|
-
|
59
|
+
Scenario: Single value yaml inputs
|
60
|
+
Given I have the yaml file "inputs.yml" containing:
|
15
61
|
"""
|
16
|
-
|
17
|
-
|
18
|
-
- media: [Image, Video, Music]
|
62
|
+
1: 1
|
63
|
+
2: 2
|
19
64
|
"""
|
20
|
-
|
21
|
-
|
65
|
+
When I run pairwise inputs.yml
|
66
|
+
Then I should see the output
|
22
67
|
"""
|
23
|
-
|
|
24
|
-
|
|
25
|
-
| Football | Basketball | Video |
|
26
|
-
| Football | Soccer | Music |
|
27
|
-
| Basketball | Football | Music |
|
28
|
-
| Basketball | Basketball | Image |
|
29
|
-
| Basketball | Soccer | Video |
|
30
|
-
| Soccer | Football | Video |
|
31
|
-
| Soccer | Basketball | Music |
|
32
|
-
| Soccer | Soccer | Image |
|
68
|
+
| 1 | 2 |
|
69
|
+
| 1 | 2 |
|
33
70
|
|
34
71
|
"""
|
35
72
|
|
36
|
-
Scenario:
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
73
|
+
Scenario: inputing as csv
|
74
|
+
Given I have the csv file "inputs.csv" containing:
|
75
|
+
"""
|
76
|
+
media, event with image, event without image
|
77
|
+
Image, Football, Football
|
78
|
+
Video, Basketball, Basketball
|
79
|
+
Music, Soccer, Soccer
|
80
|
+
"""
|
81
|
+
When I run pairwise inputs.csv
|
82
|
+
Then I should see the output
|
45
83
|
"""
|
46
84
|
| media | event without image | event with image |
|
47
85
|
| Image | Football | Football |
|
@@ -56,38 +94,25 @@ Scenario: Unorderd yaml inputs
|
|
56
94
|
|
57
95
|
"""
|
58
96
|
|
59
|
-
Scenario:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
When I run pairwise inputs.yml --keep-wild-cards
|
80
|
-
Then I should see the output
|
81
|
-
"""
|
82
|
-
| A | B | C |
|
83
|
-
| A1 | B1 | C1 |
|
84
|
-
| A1 | B2 | C2 |
|
85
|
-
| A2 | B1 | C3 |
|
86
|
-
| A2 | B2 | C1 |
|
87
|
-
| A3 | B1 | C2 |
|
88
|
-
| A3 | B2 | C3 |
|
89
|
-
| A3 | any_value_of_B | C1 |
|
90
|
-
| A2 | any_value_of_B | C2 |
|
91
|
-
| A1 | any_value_of_B | C3 |
|
97
|
+
Scenario: Not replacing wild cards
|
98
|
+
Given I have the yaml file "inputs.yml" containing:
|
99
|
+
"""
|
100
|
+
- A: [A1, A2, A3]
|
101
|
+
- B: [B1, B2]
|
102
|
+
- C: [C1, C2, C3]
|
103
|
+
"""
|
104
|
+
When I run pairwise inputs.yml --keep-wild-cards
|
105
|
+
Then I should see the output
|
106
|
+
"""
|
107
|
+
| A | B | C |
|
108
|
+
| A1 | B1 | C1 |
|
109
|
+
| A1 | B2 | C2 |
|
110
|
+
| A2 | B1 | C3 |
|
111
|
+
| A2 | B2 | C1 |
|
112
|
+
| A3 | B1 | C2 |
|
113
|
+
| A3 | B2 | C3 |
|
114
|
+
| A3 | any_value_of_B | C1 |
|
115
|
+
| A2 | any_value_of_B | C2 |
|
116
|
+
| A1 | any_value_of_B | C3 |
|
92
117
|
|
93
|
-
|
118
|
+
"""
|
@@ -1,7 +1,15 @@
|
|
1
|
-
Given /^I have the yaml file "([^\"]*)" containing:$/ do |file_name, file_contents|
|
1
|
+
Given /^I have the (?:yaml |csv )?file "([^\"]*)" containing:$/ do |file_name, file_contents|
|
2
2
|
create_file(file_name, file_contents)
|
3
3
|
end
|
4
4
|
|
5
|
+
Given /^I have the file "([^\"]*)"$/ do |filename|
|
6
|
+
Given %Q{I have the file "#{filename}" containing:}, ""
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^I have a folder "([^\"]*)"$/ do |folder_name|
|
10
|
+
create_folder(folder_name)
|
11
|
+
end
|
12
|
+
|
5
13
|
When /^I run (.+)$/ do |command|
|
6
14
|
run(command)
|
7
15
|
end
|
@@ -11,9 +19,14 @@ Then /^I should see the output$/ do |text|
|
|
11
19
|
end
|
12
20
|
|
13
21
|
Then /^I should see in the output$/ do |string|
|
22
|
+
Then "it should not show any errors"
|
14
23
|
last_stdout.should include(string)
|
15
24
|
end
|
16
25
|
|
26
|
+
Then /^I should see in the errors$/ do |string|
|
27
|
+
last_stderr.should include(string)
|
28
|
+
end
|
29
|
+
|
17
30
|
Then /^it should not show any errors$/ do
|
18
31
|
last_stderr.should == ""
|
19
32
|
end
|
data/features/support/env.rb
CHANGED
@@ -34,7 +34,7 @@ class PairwiseWorld
|
|
34
34
|
def last_stdout
|
35
35
|
@last_stdout
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def create_file(file_name, file_content)
|
39
39
|
in_current_dir do
|
40
40
|
FileUtils.mkdir_p(File.dirname(file_name)) unless File.directory?(File.dirname(file_name))
|
@@ -42,9 +42,15 @@ class PairwiseWorld
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def create_folder(folder_name)
|
46
|
+
in_current_dir do
|
47
|
+
FileUtils.mkdir_p(folder_name) unless File.directory?(folder_name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
45
51
|
def set_env_var(variable, value)
|
46
52
|
@original_env_vars ||= {}
|
47
|
-
@original_env_vars[variable] = ENV[variable]
|
53
|
+
@original_env_vars[variable] = ENV[variable]
|
48
54
|
ENV[variable] = value
|
49
55
|
end
|
50
56
|
|
data/lib/pairwise.rb
CHANGED
data/lib/pairwise/cli.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'yaml'
|
2
1
|
require 'optparse'
|
2
|
+
|
3
3
|
module Pairwise
|
4
4
|
class Cli
|
5
5
|
BUILTIN_FORMATS = {
|
@@ -27,7 +27,7 @@ module Pairwise
|
|
27
27
|
def parse!
|
28
28
|
@args.extend(::OptionParser::Arguable)
|
29
29
|
@args.options do |opts|
|
30
|
-
opts.banner = ["Usage: pairwise [options] FILE.yml", "",
|
30
|
+
opts.banner = ["Usage: pairwise [options] FILE.[yml|csv]", "",
|
31
31
|
"Example:",
|
32
32
|
"pairwise data/inputs.yml", "", "",
|
33
33
|
].join("\n")
|
@@ -50,22 +50,19 @@ module Pairwise
|
|
50
50
|
end
|
51
51
|
end.parse!
|
52
52
|
|
53
|
-
@
|
53
|
+
@filename_with_path = @args[0] unless @args.empty?
|
54
54
|
end
|
55
55
|
|
56
56
|
def execute!
|
57
57
|
parse!
|
58
|
-
|
59
|
-
|
60
|
-
inputs = YAML.load_file(@input_file)
|
61
|
-
if valid_inputs?(inputs)
|
62
|
-
input_data, input_labels = *parse_input_data!(inputs)
|
58
|
+
validate_options!
|
63
59
|
|
64
|
-
|
60
|
+
if inputs = InputFile.load(@filename_with_path)
|
61
|
+
builder = Pairwise::Builder.new(inputs.data, @options)
|
65
62
|
|
66
|
-
formatter.display(builder.build,
|
63
|
+
formatter.display(builder.build, inputs.labels)
|
67
64
|
else
|
68
|
-
puts "Error: '#{@
|
65
|
+
puts "Error: '#{@filename_with_path}' does not contain the right structure for me to generate the pairwise set!"
|
69
66
|
end
|
70
67
|
end
|
71
68
|
|
@@ -75,8 +72,10 @@ module Pairwise
|
|
75
72
|
:format => 'cucumber' }
|
76
73
|
end
|
77
74
|
|
78
|
-
def
|
79
|
-
|
75
|
+
def validate_options!
|
76
|
+
exit_with_help if @filename_with_path.nil? || @filename_with_path.empty?
|
77
|
+
raise Errno::ENOENT, @filename_with_path unless File.exist?(@filename_with_path)
|
78
|
+
exit_with_help unless File.file?(@filename_with_path)
|
80
79
|
end
|
81
80
|
|
82
81
|
def exit_with_help
|
@@ -89,25 +88,5 @@ module Pairwise
|
|
89
88
|
format.new(@out)
|
90
89
|
end
|
91
90
|
|
92
|
-
def parse_input_data!(inputs)
|
93
|
-
inputs = hash_inputs_to_list(inputs) if inputs.is_a?(Hash)
|
94
|
-
|
95
|
-
raw_inputs = inputs.map {|input| input.values[0]}
|
96
|
-
input_labels = input_names(inputs)
|
97
|
-
|
98
|
-
[raw_inputs, input_labels]
|
99
|
-
end
|
100
|
-
|
101
|
-
def hash_inputs_to_list(inputs_hash)
|
102
|
-
inputs_hash.map do |key, value|
|
103
|
-
value = [value] unless value.is_a?(Array)
|
104
|
-
{key => value}
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def input_names(inputs)
|
109
|
-
inputs.map{|input| input.keys}.flatten
|
110
|
-
end
|
111
|
-
|
112
91
|
end
|
113
92
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pairwise
|
2
|
+
class InputData
|
3
|
+
|
4
|
+
def initialize(inputs)
|
5
|
+
@inputs = inputs.is_a?(Hash) ? hash_inputs_to_list(inputs) : inputs
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
@data ||= @inputs.map {|input| input.values[0]}
|
10
|
+
end
|
11
|
+
|
12
|
+
def labels
|
13
|
+
@labels ||= @inputs.map{|input| input.keys}.flatten
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def hash_inputs_to_list(inputs_hash)
|
19
|
+
inputs_hash.map do |key, value|
|
20
|
+
value = [value] unless value.is_a?(Array)
|
21
|
+
{key => value}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Pairwise
|
2
|
+
class InputFile
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def load(filename)
|
6
|
+
inputs = self.new(filename).load_and_parse
|
7
|
+
InputData.new(inputs) if valid?(inputs)
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?(inputs)
|
11
|
+
inputs && (inputs.is_a?(Array) || inputs.is_a?(Hash))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(filename)
|
16
|
+
@filename = filename
|
17
|
+
self.extend(input_file_module)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def input_file_module
|
23
|
+
type = @filename[/\.(.+)$/, 1]
|
24
|
+
raise "Cannot determine file type for: #{@filename}" unless type
|
25
|
+
case type.downcase
|
26
|
+
when 'yaml', 'yml' then Yaml
|
27
|
+
else
|
28
|
+
Pairwise.const_get(type.capitalize) rescue raise "Unsupported file type: #{type}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module Yaml
|
35
|
+
def load_and_parse
|
36
|
+
require 'yaml'
|
37
|
+
|
38
|
+
inputs = YAML.load_file(@filename)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module Csv
|
43
|
+
def load_and_parse
|
44
|
+
require 'csv'
|
45
|
+
|
46
|
+
csv_data = CSV.read @filename
|
47
|
+
headers = csv_data.shift.map {|head| head.to_s.strip }
|
48
|
+
string_data = csv_data.map {|row| row.map {|cell| cell.to_s.strip } }
|
49
|
+
|
50
|
+
inputs = Hash.new {|h,k| h[k] = []}
|
51
|
+
|
52
|
+
string_data.each do |row|
|
53
|
+
row.each_with_index { |value, index| inputs[headers[index]] << value }
|
54
|
+
end
|
55
|
+
|
56
|
+
inputs
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/pairwise/cli_spec.rb
CHANGED
@@ -51,7 +51,7 @@ module Pairwise
|
|
51
51
|
context "--help" do
|
52
52
|
it "displays usage" do
|
53
53
|
after_parsing('--help') do
|
54
|
-
output_stream.string.should =~ /Usage: pairwise \[options\] FILE
|
54
|
+
output_stream.string.should =~ /Usage: pairwise \[options\] FILE\.\[yml|csv\]/
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pairwise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Wilk
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-27 00:00:00 +00:00
|
13
13
|
default_executable: pairwise
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- Rakefile
|
49
49
|
- VERSION.yml
|
50
50
|
- bin/pairwise
|
51
|
+
- features/bugs/bad_arguments.feature
|
51
52
|
- features/bugs/bad_yml.feature
|
52
53
|
- features/customizing_pairwise_output_format.feature
|
53
54
|
- features/generating_pairwise_data.feature
|
@@ -62,6 +63,8 @@ files:
|
|
62
63
|
- lib/pairwise/formatter.rb
|
63
64
|
- lib/pairwise/formatter/csv.rb
|
64
65
|
- lib/pairwise/formatter/cucumber.rb
|
66
|
+
- lib/pairwise/input_data.rb
|
67
|
+
- lib/pairwise/input_file.rb
|
65
68
|
- lib/pairwise/pair_collection.rb
|
66
69
|
- lib/pairwise/test_pair.rb
|
67
70
|
- spec/pairwise/builder_spec.rb
|