pairwise 0.1.0 → 0.1.1

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,13 @@
1
+ = Pairwise
2
+
3
+ Documentation is at http://github.com/josephwilk/pairwise/wikis/home/
4
+
5
+ == Running tests
6
+
7
+ rake
8
+
9
+ If you get errors about missing gems - just install them.
10
+
11
+ == Copyright
12
+
13
+ Copyright (c) 2009,2010 Joseph Wilk. See LICENSE for details.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 0
2
+ :patch: 1
3
3
  :major: 0
4
4
  :minor: 1
@@ -66,15 +66,15 @@ Scenario: Not replacing wild cards
66
66
  When I run pairwise inputs.yml --keep-wild-cards
67
67
  Then I should see the output
68
68
  """
69
- | A | B | C |
70
- | A1 | B1 | C1 |
71
- | A1 | B2 | C2 |
72
- | A2 | B1 | C3 |
73
- | A2 | B2 | C1 |
74
- | A3 | B1 | C2 |
75
- | A3 | B2 | C3 |
76
- | A3 | wild_card | C1 |
77
- | A2 | wild_card | C2 |
78
- | A1 | wild_card | C3 |
69
+ | A | B | C |
70
+ | A1 | B1 | C1 |
71
+ | A1 | B2 | C2 |
72
+ | A2 | B1 | C3 |
73
+ | A2 | B2 | C1 |
74
+ | A3 | B1 | C2 |
75
+ | A3 | B2 | C3 |
76
+ | A3 | any_value_of_B | C1 |
77
+ | A2 | any_value_of_B | C2 |
78
+ | A1 | any_value_of_B | C3 |
79
79
 
80
80
  """
@@ -6,81 +6,84 @@ module Pairwise
6
6
  WILD_CARD = 'wild_card'
7
7
 
8
8
  def initialize(inputs, options = {})
9
- @inputs = inputs
9
+ @list_of_input_values = inputs
10
10
  @options = options
11
11
  end
12
12
 
13
13
  def build
14
- input_lists = generate_pairs_between(@inputs[0], [@inputs[1]], 0)
15
- @inputs.size > 2 ? in_parameter_order_generation(input_lists) : input_lists.map{|list| list.to_a}
14
+ input_combinations = generate_pairs_between(@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.map{|list| list.to_a}
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def in_parameter_order_generation(input_lists)
21
- @inputs[2..-1].each_with_index do |input_list, i|
20
+ def in_parameter_order_generation(input_combinations)
21
+ @list_of_input_values[2..-1].each_with_index do |input_values, i|
22
22
  i += 2
23
- input_lists, pi = horizontal_growth(input_lists, input_list, @inputs[0..(i-1)])
24
- input_lists = vertical_growth(input_lists, pi)
23
+ input_combinations, uncovered_pairs = horizontal_growth(input_combinations, input_values, @list_of_input_values[0..(i-1)])
24
+ input_combinations = vertical_growth(input_combinations, uncovered_pairs)
25
25
  end
26
- input_lists = replace_redundant_wild_cards(input_lists)
27
- input_lists = replace_wild_cards(input_lists) unless @options[:keep_wild_cards]
28
- input_lists
26
+ input_combinations = replace_redundant_wild_cards(input_combinations)
27
+ input_combinations = replace_wild_cards(input_combinations) unless @options[:keep_wild_cards]
28
+ input_combinations
29
29
  end
30
30
 
31
- def horizontal_growth(input_lists, parameter_i, inputs)
32
- pi = generate_pairs_between(parameter_i, inputs, inputs.size)
31
+ def horizontal_growth(input_combinations, input_values_for_growth, previously_grown_input_values)
32
+ uncovered_pairs = generate_pairs_between(input_values_for_growth, previously_grown_input_values, previously_grown_input_values.size)
33
33
 
34
- if input_lists.size <= parameter_i.size
35
- input_lists = input_lists.enum_for(:each_with_index).map do |input_list, index_of_input_under_inspection|
36
- extended_input_list = input_list + [parameter_i[index_of_input_under_inspection]]
37
- pi = remove_pairs_covered_by(extended_input_list, pi)
38
- extended_input_list
39
- end
34
+ if input_combinations.size <= input_values_for_growth.size
35
+ input_combinations, uncovered_pairs = grow_input_combinations_and_remove_covered_pairs(input_combinations, input_values_for_growth, uncovered_pairs)
40
36
  else
41
- input_lists[0...parameter_i.size] = input_lists[0...parameter_i.size].enum_for(:each_with_index).map do |input_list, index_of_input_under_inspection|
42
- extended_input_list = input_list + [parameter_i[index_of_input_under_inspection]]
43
- pi = remove_pairs_covered_by(extended_input_list, pi)
44
- extended_input_list
45
- end
46
-
47
- input_lists[parameter_i.size..-1] = input_lists[parameter_i.size..-1].map do |input_list|
48
- extended_input_list = input_list_that_covers_most_pairs(input_list, parameter_i, pi)
49
- pi = remove_pairs_covered_by(extended_input_list, pi)
50
- extended_input_list
37
+ range_to_grow = 0...input_values_for_growth.size
38
+ input_combinations[range_to_grow], uncovered_pairs = grow_input_combinations_and_remove_covered_pairs(input_combinations[range_to_grow], input_values_for_growth, uncovered_pairs)
39
+
40
+ range_to_grow = input_values_for_growth.size..-1
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, uncovered_pairs)
43
+ uncovered_pairs = remove_pairs_covered_by(extended_input_combination, uncovered_pairs)
44
+ extended_input_combination
51
45
  end
52
46
  end
53
47
 
54
- [input_lists, pi]
48
+ [input_combinations, uncovered_pairs]
55
49
  end
56
50
 
57
- def vertical_growth(input_lists, pi)
58
- new_input_lists = []
51
+ def grow_input_combinations_and_remove_covered_pairs(input_combinations, input_values_for_growth, uncovered_pairs)
52
+ input_combinations = input_combinations.enum_for(:each_with_index).map do |input_combination, input_index|
53
+ extended_input_combination = input_combination + [input_values_for_growth[input_index]]
54
+ uncovered_pairs = remove_pairs_covered_by(extended_input_combination, uncovered_pairs)
55
+ extended_input_combination
56
+ end
57
+ [input_combinations, uncovered_pairs]
58
+ end
59
+
60
+ def vertical_growth(input_combinations, uncovered_pairs)
61
+ new_input_combinations = []
59
62
 
60
- pi.each do |uncovered_pair|
63
+ uncovered_pairs.each do |uncovered_pair|
61
64
  #TODO: Decided if we should replace all matches or single matches?
62
- if test_position = uncovered_pair.replaceable_wild_card?(new_input_lists)
63
- new_input_lists[test_position] = uncovered_pair.replace_wild_card(new_input_lists[test_position])
65
+ if test_position = uncovered_pair.replaceable_wild_card?(new_input_combinations)
66
+ new_input_combinations[test_position] = uncovered_pair.replace_wild_card(new_input_combinations[test_position])
64
67
  else
65
- new_input_lists << uncovered_pair.create_input_list
68
+ new_input_combinations << uncovered_pair.create_input_list
66
69
  end
67
70
  end
68
71
 
69
- input_lists + new_input_lists
72
+ input_combinations + new_input_combinations
70
73
  end
71
74
 
72
- def replace_redundant_wild_cards(input_lists)
73
- map_each_input_value(input_lists) do |input_value, index|
74
- if input_value == WILD_CARD && @inputs[index].length == 1
75
- @inputs[index][0]
75
+ def replace_redundant_wild_cards(input_combinations)
76
+ map_each_input_value(input_combinations) do |input_value, index|
77
+ if input_value == WILD_CARD && @list_of_input_values[index].length == 1
78
+ @list_of_input_values[index][0]
76
79
  else
77
80
  input_value
78
81
  end
79
82
  end
80
83
  end
81
84
 
82
- def replace_wild_cards(input_lists)
83
- map_each_input_value(input_lists) do |input_value, index|
85
+ def replace_wild_cards(input_combinations)
86
+ map_each_input_value(input_combinations) do |input_value, index|
84
87
  if input_value == WILD_CARD
85
88
  pick_random_value(@inputs[index])
86
89
  else
@@ -89,16 +92,16 @@ module Pairwise
89
92
  end
90
93
  end
91
94
 
92
- def map_each_input_value(input_lists)
93
- input_lists.map do |input_list|
94
- input_list.enum_for(:each_with_index).map do |input_value, index|
95
+ def map_each_input_value(input_combinations)
96
+ input_combinations.map do |input_combination|
97
+ input_combination.enum_for(:each_with_index).map do |input_value, index|
95
98
  yield input_value, index
96
99
  end
97
100
  end
98
101
  end
99
102
 
100
- def pick_random_value(input_list)
101
- input_list[rand(input_list.size)]
103
+ def pick_random_value(input_combination)
104
+ input_combination[rand(input_combination.size)]
102
105
  end
103
106
 
104
107
  def generate_pairs_between(parameter_i, input_lists, p_index)
@@ -113,28 +116,28 @@ module Pairwise
113
116
  pairs
114
117
  end
115
118
 
116
- def remove_pairs_covered_by(extended_input_list, pi)
117
- pi.reject{|pair| pair.covered_by?(extended_input_list)}
119
+ def remove_pairs_covered_by(extended_input_list, pairs)
120
+ pairs.reject{|pair| pair.covered_by?(extended_input_list)}
118
121
  end
119
122
 
120
- def input_list_that_covers_most_pairs(input_list, parameter_i, pi)
121
- selected_input_list = nil
122
- parameter_i.reduce(0) do |max_covered_count, value|
123
- input_list_candidate = input_list + [value]
124
- covered_count = pairs_covered_count(input_list_candidate, pi)
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)
125
128
  if covered_count >= max_covered_count
126
- selected_input_list = input_list_candidate
129
+ selected_input_combination = input_combination_candidate
127
130
  covered_count
128
131
  else
129
132
  max_covered_count
130
133
  end
131
134
  end
132
- selected_input_list
135
+ selected_input_combination
133
136
  end
134
137
 
135
- def pairs_covered_count(input_list, pairs)
138
+ def pairs_covered_count(input_combination, pairs)
136
139
  pairs.reduce(0) do |covered_count, pair|
137
- covered_count += 1 if pair.covered_by?(input_list)
140
+ covered_count += 1 if pair.covered_by?(input_combination)
138
141
  covered_count
139
142
  end
140
143
  end
@@ -7,16 +7,17 @@ module Pairwise
7
7
  @max = {}
8
8
  end
9
9
 
10
- def display(test_data, inputs)
11
- @test_data, @inputs = test_data, inputs
12
-
10
+ def display(test_data, input_labels)
11
+ @test_data = label_wild_cards(test_data, input_labels)
12
+ @input_labels = input_labels
13
+
13
14
  @out.print "|"
14
- inputs.each_with_index do |key, column|
15
- @out.print padded_string(key, column) + "|"
15
+ @input_labels.each_with_index do |label, column|
16
+ @out.print padded_string(label, column) + "|"
16
17
  end
17
18
  @out.puts
18
19
 
19
- test_data.each do |data|
20
+ @test_data.each do |data|
20
21
  @out.print "|"
21
22
  data.each_with_index do |datum, column|
22
23
  @out.print padded_string(datum, column) + "|"
@@ -26,13 +27,21 @@ module Pairwise
26
27
  end
27
28
 
28
29
  private
30
+ def label_wild_cards(test_data, labels)
31
+ test_data.map do |data|
32
+ data.enum_for(:each_with_index).map do |datum, column|
33
+ datum == Builder::WILD_CARD ? "any_value_of_#{labels[column]}" : datum
34
+ end
35
+ end
36
+ end
37
+
29
38
  def padded_string(string, column)
30
39
  padding_length = max_line_length(column) - string.length
31
40
  " #{string} " + (" " * padding_length)
32
41
  end
33
42
 
34
43
  def max_line_length(column)
35
- @max[column] ||= ([@inputs[column].length] + @test_data.map{|data| data[column].length}).max
44
+ @max[column] ||= ([@input_labels[column].length] + @test_data.map{|data| data[column].length}).max
36
45
  end
37
46
 
38
47
  end
@@ -30,9 +30,9 @@ module Pairwise
30
30
  input_list
31
31
  end
32
32
 
33
- def replaceable_wild_card?(input_lists)
34
- wild_card_list = input_lists.map do |input_list|
35
- input_list[@p2_position] == Builder::WILD_CARD && input_list[@p1_position] == @p1
33
+ def replaceable_wild_card?(input_combinations)
34
+ wild_card_list = input_combinations.map do |input_combination|
35
+ input_combination[@p2_position] == Builder::WILD_CARD && input_combination[@p1_position] == @p1
36
36
  end
37
37
  wild_card_list.rindex(true)
38
38
  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.0
4
+ version: 0.1.1
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-01-05 00:00:00 +00:00
12
+ date: 2010-01-07 00:00:00 +00:00
13
13
  default_executable: pairwise
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,9 +40,11 @@ extensions: []
40
40
 
41
41
  extra_rdoc_files:
42
42
  - LICENSE
43
+ - README.rdoc
43
44
  files:
44
45
  - .gitignore
45
46
  - LICENSE
47
+ - README.rdoc
46
48
  - Rakefile
47
49
  - VERSION.yml
48
50
  - bin/pairwise