pairwise 0.1.3 → 0.1.4
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 +3 -2
- data/features/customizing_pairwise_output_format.feature +27 -0
- data/lib/pairwise.rb +1 -0
- data/lib/pairwise/builder.rb +6 -43
- data/lib/pairwise/cli.rb +22 -3
- data/lib/pairwise/formatter.rb +1 -1
- data/lib/pairwise/formatter/csv.rb +17 -0
- data/lib/pairwise/pair_collection.rb +52 -0
- data/spec/pairwise/builder_spec.rb +1 -1
- data/spec/pairwise/cli_spec.rb +14 -0
- metadata +5 -2
data/VERSION.yml
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Customizing pairwise output format
|
2
|
+
In order to save time importing pairwise sets
|
3
|
+
As a tester
|
4
|
+
I want the output pairwise data to be in the most convenient format for me
|
5
|
+
|
6
|
+
Scenario: formatting output as csv
|
7
|
+
Given I have the yaml file "inputs.yml" containing:
|
8
|
+
"""
|
9
|
+
- event with image: [Football, Basketball, Soccer]
|
10
|
+
- event without image: [Football, Basketball, Soccer]
|
11
|
+
- media: [Image, Video, Music]
|
12
|
+
"""
|
13
|
+
When I run pairwise inputs.yml --format csv
|
14
|
+
Then I should see the output
|
15
|
+
"""
|
16
|
+
event with image,event without image,media
|
17
|
+
Football,Football,Image
|
18
|
+
Football,Basketball,Video
|
19
|
+
Football,Soccer,Music
|
20
|
+
Basketball,Football,Music
|
21
|
+
Basketball,Basketball,Image
|
22
|
+
Basketball,Soccer,Video
|
23
|
+
Soccer,Football,Video
|
24
|
+
Soccer,Basketball,Music
|
25
|
+
Soccer,Soccer,Image
|
26
|
+
|
27
|
+
"""
|
data/lib/pairwise.rb
CHANGED
@@ -2,6 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
require 'pairwise/test_pair'
|
5
|
+
require 'pairwise/pair_collection'
|
5
6
|
require 'pairwise/builder'
|
6
7
|
require 'pairwise/formatter'
|
7
8
|
require 'pairwise/cli'
|
data/lib/pairwise/builder.rb
CHANGED
@@ -11,8 +11,8 @@ module Pairwise
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def build
|
14
|
-
input_combinations =
|
15
|
-
@list_of_input_values.size > 2 ? in_parameter_order_generation(input_combinations) : input_combinations.
|
14
|
+
input_combinations = PairCollection.new(@list_of_input_values[0], [@list_of_input_values[1]], 0)
|
15
|
+
@list_of_input_values.size > 2 ? in_parameter_order_generation(input_combinations) : input_combinations.to_a
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
@@ -29,7 +29,7 @@ module Pairwise
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def horizontal_growth(input_combinations, input_values_for_growth, previously_grown_input_values)
|
32
|
-
uncovered_pairs =
|
32
|
+
uncovered_pairs = PairCollection.new(input_values_for_growth, previously_grown_input_values, previously_grown_input_values.size)
|
33
33
|
|
34
34
|
if input_combinations.size <= input_values_for_growth.size
|
35
35
|
input_combinations, uncovered_pairs = grow_input_combinations_and_remove_covered_pairs(input_combinations, input_values_for_growth, uncovered_pairs)
|
@@ -39,8 +39,8 @@ module Pairwise
|
|
39
39
|
|
40
40
|
range_to_grow = input_values_for_growth.size..-1
|
41
41
|
input_combinations[range_to_grow] = input_combinations[range_to_grow].map do |input_combination|
|
42
|
-
extended_input_combination = input_combination_that_covers_most_pairs(input_combination, input_values_for_growth
|
43
|
-
uncovered_pairs
|
42
|
+
extended_input_combination = uncovered_pairs.input_combination_that_covers_most_pairs(input_combination, input_values_for_growth)
|
43
|
+
uncovered_pairs.remove_pairs_covered_by!(extended_input_combination)
|
44
44
|
extended_input_combination
|
45
45
|
end
|
46
46
|
end
|
@@ -51,7 +51,7 @@ module Pairwise
|
|
51
51
|
def grow_input_combinations_and_remove_covered_pairs(input_combinations, input_values_for_growth, uncovered_pairs)
|
52
52
|
input_combinations = input_combinations.enum_for(:each_with_index).map do |input_combination, input_index|
|
53
53
|
extended_input_combination = input_combination + [input_values_for_growth[input_index]]
|
54
|
-
uncovered_pairs
|
54
|
+
uncovered_pairs.remove_pairs_covered_by!(extended_input_combination)
|
55
55
|
extended_input_combination
|
56
56
|
end
|
57
57
|
[input_combinations, uncovered_pairs]
|
@@ -104,42 +104,5 @@ module Pairwise
|
|
104
104
|
input_combination[Kernel.rand(input_combination.size)]
|
105
105
|
end
|
106
106
|
|
107
|
-
def generate_pairs_between(parameter_i, input_lists, p_index)
|
108
|
-
pairs = []
|
109
|
-
parameter_i.each do |p|
|
110
|
-
input_lists.each_with_index do |input_list, q_index|
|
111
|
-
input_list.each do |q|
|
112
|
-
pairs << TestPair.new(p_index, q_index, p, q)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
pairs
|
117
|
-
end
|
118
|
-
|
119
|
-
def remove_pairs_covered_by(extended_input_list, pairs)
|
120
|
-
pairs.reject{|pair| pair.covered_by?(extended_input_list)}
|
121
|
-
end
|
122
|
-
|
123
|
-
def input_combination_that_covers_most_pairs(input_combination, input_values_for_growth, pairs)
|
124
|
-
selected_input_combination = nil
|
125
|
-
input_values_for_growth.reduce(0) do |max_covered_count, value|
|
126
|
-
input_combination_candidate = input_combination + [value]
|
127
|
-
covered_count = pairs_covered_count(input_combination_candidate, pairs)
|
128
|
-
if covered_count >= max_covered_count
|
129
|
-
selected_input_combination = input_combination_candidate
|
130
|
-
covered_count
|
131
|
-
else
|
132
|
-
max_covered_count
|
133
|
-
end
|
134
|
-
end
|
135
|
-
selected_input_combination
|
136
|
-
end
|
137
|
-
|
138
|
-
def pairs_covered_count(input_combination, pairs)
|
139
|
-
pairs.reduce(0) do |covered_count, pair|
|
140
|
-
covered_count += 1 if pair.covered_by?(input_combination)
|
141
|
-
covered_count
|
142
|
-
end
|
143
|
-
end
|
144
107
|
end
|
145
108
|
end
|
data/lib/pairwise/cli.rb
CHANGED
@@ -2,6 +2,17 @@ require 'yaml'
|
|
2
2
|
require 'optparse'
|
3
3
|
module Pairwise
|
4
4
|
class Cli
|
5
|
+
BUILTIN_FORMATS = {
|
6
|
+
'cucumber' => [Pairwise::Formatter::Cucumber,
|
7
|
+
'Generates pairs as tables for Cucumber'],
|
8
|
+
'csv' => [Pairwise::Formatter::Csv,
|
9
|
+
'Generate pairs in a comma seperated format']}
|
10
|
+
|
11
|
+
max = BUILTIN_FORMATS.keys.map{|s| s.length}.max
|
12
|
+
FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
|
13
|
+
" #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
|
14
|
+
end)
|
15
|
+
|
5
16
|
class << self
|
6
17
|
def execute(args)
|
7
18
|
new(args).execute!
|
@@ -10,7 +21,6 @@ module Pairwise
|
|
10
21
|
|
11
22
|
def initialize(args, out = STDOUT)
|
12
23
|
@args, @out = args, out
|
13
|
-
@formatter = Formatter::Cucumber.new(@out)
|
14
24
|
@options = defaults
|
15
25
|
end
|
16
26
|
|
@@ -24,6 +34,9 @@ module Pairwise
|
|
24
34
|
opts.on("-k", "--keep-wild-cards") do
|
25
35
|
@options[:keep_wild_cards] = true
|
26
36
|
end
|
37
|
+
opts.on('-f FORMAT', '--format FORMAT', *FORMAT_HELP) do |format|
|
38
|
+
@options[:format] = format
|
39
|
+
end
|
27
40
|
opts.on_tail("--version", "Show version.") do
|
28
41
|
@out.puts Pairwise::VERSION
|
29
42
|
Kernel.exit(0)
|
@@ -46,7 +59,7 @@ module Pairwise
|
|
46
59
|
|
47
60
|
builder = Pairwise::Builder.new(input_data, @options)
|
48
61
|
|
49
|
-
|
62
|
+
formatter.display(builder.build, input_labels)
|
50
63
|
else
|
51
64
|
puts "Error: '#{@input_file}' does not contain the right yaml structure for me to generate the pairwise set!"
|
52
65
|
end
|
@@ -54,7 +67,8 @@ module Pairwise
|
|
54
67
|
|
55
68
|
private
|
56
69
|
def defaults
|
57
|
-
{:keep_wild_cards => false
|
70
|
+
{ :keep_wild_cards => false,
|
71
|
+
:format => 'cucumber' }
|
58
72
|
end
|
59
73
|
|
60
74
|
def valid_inputs?(inputs)
|
@@ -66,6 +80,11 @@ module Pairwise
|
|
66
80
|
Kernel.exit(0)
|
67
81
|
end
|
68
82
|
|
83
|
+
def formatter
|
84
|
+
format = BUILTIN_FORMATS[@options[:format]][0]
|
85
|
+
format.new(@out)
|
86
|
+
end
|
87
|
+
|
69
88
|
def parse_input_data!(inputs)
|
70
89
|
inputs = hash_inputs_to_list(inputs) if inputs.is_a?(Hash)
|
71
90
|
|
data/lib/pairwise/formatter.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
%
|
1
|
+
%w[cucumber csv].each {|file| require "pairwise/formatter/#{file}"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pairwise
|
2
|
+
module Formatter
|
3
|
+
class Csv
|
4
|
+
|
5
|
+
def initialize(out)
|
6
|
+
@out = out
|
7
|
+
end
|
8
|
+
|
9
|
+
def display(test_data, input_labels)
|
10
|
+
@out.puts input_labels.join(',')
|
11
|
+
test_data.each do |data|
|
12
|
+
@out.puts data.join(',')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Pairwise
|
2
|
+
class PairCollection < Array
|
3
|
+
|
4
|
+
def initialize(input_parameter_values, input_value_lists, input_parameter_index)
|
5
|
+
pairs = generate_pairs_between(input_parameter_values, input_value_lists, input_parameter_index)
|
6
|
+
super(pairs)
|
7
|
+
end
|
8
|
+
|
9
|
+
def remove_pairs_covered_by!(extended_input_list)
|
10
|
+
self.reject!{|pair| pair.covered_by?(extended_input_list)}
|
11
|
+
end
|
12
|
+
|
13
|
+
def input_combination_that_covers_most_pairs(input_combination, input_values_for_growth)
|
14
|
+
selected_input_combination = nil
|
15
|
+
input_values_for_growth.reduce(0) do |max_covered_count, value|
|
16
|
+
input_combination_candidate = input_combination + [value]
|
17
|
+
covered_count = pairs_covered_count(input_combination_candidate)
|
18
|
+
if covered_count >= max_covered_count
|
19
|
+
selected_input_combination = input_combination_candidate
|
20
|
+
covered_count
|
21
|
+
else
|
22
|
+
max_covered_count
|
23
|
+
end
|
24
|
+
end
|
25
|
+
selected_input_combination
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_a
|
29
|
+
self.map{|list| list.to_a}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def generate_pairs_between(input_parameter_values, input_value_lists, input_parameter_index)
|
34
|
+
pairs = []
|
35
|
+
input_parameter_values.each do |input_value_a|
|
36
|
+
input_value_lists.each_with_index do |input_list, input_value_b_index|
|
37
|
+
input_list.each do |input_value_b|
|
38
|
+
pairs << TestPair.new(input_parameter_index, input_value_b_index, input_value_a, input_value_b)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
pairs
|
43
|
+
end
|
44
|
+
|
45
|
+
def pairs_covered_count(input_combination)
|
46
|
+
self.reduce(0) do |covered_count, pair|
|
47
|
+
covered_count += 1 if pair.covered_by?(input_combination)
|
48
|
+
covered_count
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -26,7 +26,7 @@ module Pairwise
|
|
26
26
|
# We are getting the uncovered pairs in reverse
|
27
27
|
#pi.should == [[:A2, :C2],[:A1, :C3],[:B1, :C2],[:B2, :C3]]
|
28
28
|
# Cheat and check we get the list in reverse
|
29
|
-
pi.should == [[:C2, :A2], [:C2, :B1], [:C3, :A1], [:C3, :B2]]
|
29
|
+
pi.to_a.should == [[:C2, :A2], [:C2, :B1], [:C3, :A1], [:C3, :B2]]
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
data/spec/pairwise/cli_spec.rb
CHANGED
@@ -34,6 +34,20 @@ module Pairwise
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
context '-f FORMAT or --format FORMAT' do
|
38
|
+
it "defaults to the cucumber format for output" do
|
39
|
+
after_parsing('') do
|
40
|
+
options[:format].should == 'cucumber'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "overides the cucumber format when passed a specific format" do
|
45
|
+
after_parsing('--format csv') do
|
46
|
+
options[:format].should == 'csv'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
37
51
|
context "--help" do
|
38
52
|
it "displays usage" do
|
39
53
|
after_parsing('--help') do
|
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.4
|
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-
|
12
|
+
date: 2010-02-21 00:00:00 +00:00
|
13
13
|
default_executable: pairwise
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- VERSION.yml
|
50
50
|
- bin/pairwise
|
51
51
|
- features/bugs/bad_yml.feature
|
52
|
+
- features/customizing_pairwise_output_format.feature
|
52
53
|
- features/generating_pairwise_data.feature
|
53
54
|
- features/step_definitions/pairwise_data_steps.rb
|
54
55
|
- features/support/env.rb
|
@@ -59,7 +60,9 @@ files:
|
|
59
60
|
- lib/pairwise/builder.rb
|
60
61
|
- lib/pairwise/cli.rb
|
61
62
|
- lib/pairwise/formatter.rb
|
63
|
+
- lib/pairwise/formatter/csv.rb
|
62
64
|
- lib/pairwise/formatter/cucumber.rb
|
65
|
+
- lib/pairwise/pair_collection.rb
|
63
66
|
- lib/pairwise/test_pair.rb
|
64
67
|
- spec/pairwise/builder_spec.rb
|
65
68
|
- spec/pairwise/cli_spec.rb
|