pairwise 0.1.5 → 0.1.6
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.
- 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
|