pairwise 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|