dither 0.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eaa7339d133be5eb764dc4b8aa8d1504cfefd4fb
4
+ data.tar.gz: dce4f5a332a553d1463da52cbf5feafae2579373
5
+ SHA512:
6
+ metadata.gz: 086c0fe7b98425443312ea641541684a700d3475a4928e2fb23e58322b0576952051abec719dc876a8205252ff51491d026600e12ce6f558d16192b622acaf6c
7
+ data.tar.gz: 64763c24e5bebf57c82ad2e7d3e744392771986f765e262a6ef1dca950b9b757cce962f199203469337b7163a0691cd63a2aa3f342a7e0f4ecf47f2c0bf5b151
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.0
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - jruby-19mode
5
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dither (0.0.6)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coveralls (0.7.1)
10
+ multi_json (~> 1.3)
11
+ rest-client
12
+ simplecov (>= 0.7)
13
+ term-ansicolor
14
+ thor
15
+ diff-lcs (1.2.5)
16
+ docile (1.1.5)
17
+ mime-types (2.3)
18
+ multi_json (1.10.1)
19
+ netrc (0.7.7)
20
+ rake (0.9.6)
21
+ rest-client (1.7.2)
22
+ mime-types (>= 1.16, < 3.0)
23
+ netrc (~> 0.7)
24
+ rspec (3.2.0)
25
+ rspec-core (~> 3.2.0)
26
+ rspec-expectations (~> 3.2.0)
27
+ rspec-mocks (~> 3.2.0)
28
+ rspec-core (3.2.1)
29
+ rspec-support (~> 3.2.0)
30
+ rspec-expectations (3.2.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.2.0)
33
+ rspec-mocks (3.2.1)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.2.0)
36
+ rspec-support (3.2.2)
37
+ simplecov (0.9.0)
38
+ docile (~> 1.1.0)
39
+ multi_json
40
+ simplecov-html (~> 0.8.0)
41
+ simplecov-html (0.8.0)
42
+ term-ansicolor (1.3.0)
43
+ tins (~> 1.0)
44
+ thor (0.19.1)
45
+ tins (1.3.3)
46
+
47
+ PLATFORMS
48
+ java
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ coveralls
53
+ dither!
54
+ rake (~> 0.9.2)
55
+ rspec (~> 3.2)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jason Gowan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Dither
2
+ Collection of combinatorial test generation strategies.
3
+
4
+ # Usage
5
+
6
+ Use 2-Way IPOG
7
+ ```ruby
8
+ require 'dither'
9
+
10
+ results = Dither.all_pairs([[true, false],
11
+ [:cat, :dog, :mouse],
12
+ (0...3).to_a])
13
+
14
+ results.each { |a| puts "#{a}" }
15
+
16
+ # output
17
+ [true, :cat, 0]
18
+ [true, :dog, 1]
19
+ [true, :mouse, 2]
20
+ [false, :cat, 0]
21
+ [false, :dog, 1]
22
+ [false, :mouse, 2]
23
+ [true, :cat, 0]
24
+ [true, :dog, 1]
25
+ [true, :mouse, 2]
26
+ ```
27
+
28
+ Use 3-Way IPOG
29
+ ```ruby
30
+ require 'dither'
31
+
32
+ results = Dither.all_pairs([[true, false],
33
+ [true, false],
34
+ [:cat, :dog, :mouse],
35
+ (0...5).to_a], 3)
36
+
37
+ results.each { |a| puts "#{a}" }
38
+
39
+ # output
40
+ [true, true, :cat, 0]
41
+ ...
42
+ ```
43
+
44
+ # Note on Patches/Pull Requests
45
+
46
+ * Fork the project.
47
+ * Make your feature addition or bug fix.
48
+ * Add tests for it. This is important so I don't break it in a
49
+ future version unintentionally.
50
+ * Commit, do not mess with rakefile, version, or history.
51
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
52
+ * Send me a pull request. Bonus points for topic branches
53
+
54
+ # Copyright
55
+ includes [dither-java](https://github.com/jesg/dither-java) Apache License, Version 2.0
56
+
57
+ Copyright (c) 2015 Jason Gowan See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :default => :spec
data/dither.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "dither/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "dither"
6
+ s.version = Dither::VERSION
7
+ s.licenses = ['MIT']
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jason Gowan"]
10
+ s.email = ["gowanjason@gmail.com"]
11
+ s.homepage = "https://github.com/jesg/dither"
12
+ s.summary = %q{Collection of test generation strategies}
13
+ s.description = %q{Efficient test generation strategies}
14
+
15
+ s.rubyforge_project = "dither"
16
+
17
+ s.add_development_dependency "rspec", "~> 3.2"
18
+ s.add_development_dependency "rake", "~> 0.9.2"
19
+ s.add_development_dependency "coveralls"
20
+
21
+ files = `git ls-files`.split("\n")
22
+
23
+ if RUBY_PLATFORM =~ /java/
24
+ s.platform = "java"
25
+ # compile dither-java on jdk 7
26
+ files << "lib/dither.jar"
27
+ end
28
+ s.files = files
29
+
30
+ s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
+ s.require_paths = ["lib"]
33
+ end
@@ -0,0 +1,58 @@
1
+ # coding: utf-8
2
+
3
+ module Dither
4
+ class IPOG
5
+ include IPOGHelper
6
+
7
+ def run
8
+ # add into test set a test for each combination of values
9
+ # of the first t parameter
10
+ test_set = comb
11
+
12
+ (t...params.length).each do |i|
13
+ # let pi
14
+ # be the set of t-way combinations of values involving
15
+ # parameter Pi and t -1 parameters among the first i – 1
16
+ # parameters
17
+ pi = comb_i(i)
18
+
19
+ # horizontal extension for parameter i
20
+ test_set.each do |test_case|
21
+ cover = maximize_coverage(i, test_case, pi)
22
+
23
+ if cover.nil?
24
+ test_set.delete(test_case)
25
+ else
26
+ pi -= cover
27
+ end
28
+ end
29
+
30
+ # vertical extension for parameter i
31
+ pi.each do |a|
32
+ if test_set.any? { |b| a.subset?(b) }
33
+ pi.delete(a)
34
+ else
35
+
36
+ test_case = nil
37
+ test_set.each do |b|
38
+ test_case = b.merge_without_conflict(i, a) do |a|
39
+ violates_constraints?(a)
40
+ end
41
+ break unless test_case.nil?
42
+ end
43
+
44
+ if test_case.nil?
45
+ test_set << a.create_unbound(i)
46
+ end
47
+ pi.delete(a)
48
+ end
49
+ end
50
+ end
51
+
52
+ @test_set = test_set.map { |a| fill_unbound(a) }
53
+ .delete_if(&:nil?)
54
+ .to_a
55
+ @test_set
56
+ end
57
+ end # IPOG
58
+ end # Dither
@@ -0,0 +1,141 @@
1
+ # coding: utf-8
2
+
3
+ module Dither
4
+ module IPOGHelper
5
+ attr_reader :params, :t, :constraints, :test_set, :orig_params, :unbound_param_pool
6
+ private :params, :t, :constraints, :test_set, :orig_params, :unbound_param_pool
7
+
8
+ def initialize(params, t, opts = {})
9
+ init_params(params)
10
+ @t = t
11
+ unless opts[:constraints].nil?
12
+ @constraints = opts[:constraints].map(&:to_a)
13
+ .map { |a| a.map { |b| @params[@map_to_orig_index.key(b[0])][b[1]] } }
14
+ .map(&:to_set)
15
+ end
16
+
17
+ raise Dither::Error, 't must be >= 2' if t < 2
18
+ raise Dither::Error, 't must be <= params.length' if t > params.length
19
+ params.each do |param|
20
+ raise Dither::Error, 'param length must be > 1' if param.length < 2
21
+ end
22
+ end
23
+
24
+ def init_params(user_params)
25
+ tmp = []
26
+ @input_params = user_params
27
+ user_params.each_with_index { |e, i| tmp << [i, e] }
28
+ @orig_params = tmp.sort_by { |a| a[1].length }
29
+ .reverse!
30
+
31
+ @map_to_orig_index = {}
32
+ @orig_params.each_with_index do |e, i|
33
+ @map_to_orig_index[i] = e[0]
34
+ end
35
+
36
+ @params = []
37
+ @unbound_param_pool = []
38
+ orig_params.each_with_index do |e, i|
39
+ @params << (0...e[1].length).map { |j| Param.new(i, j) }
40
+ @unbound_param_pool << UnboundParam.new(i)
41
+ end
42
+ params
43
+ end
44
+
45
+ # return nil if unable to satisfy constraints
46
+ def maximize_coverage(i, test_case, pi)
47
+ current_max = 0
48
+ current_max_j = 0
49
+ current_matches = []
50
+
51
+ (0...params[i].length).each do |j|
52
+ current_param = params[i][j]
53
+ test_case << current_param
54
+ unless violates_constraints?(test_case)
55
+ matches = pi.select { |a| a.subset?(test_case) }
56
+ count = matches.count
57
+
58
+ if count > current_max
59
+ current_max = count
60
+ current_max_j = j
61
+ current_matches = matches
62
+ end
63
+ end
64
+ test_case.delete(current_param)
65
+ end
66
+
67
+ return nil if violates_constraints?(test_case)
68
+ test_case << params[i][current_max_j]
69
+
70
+ current_matches
71
+ end
72
+
73
+ def violates_constraints?(params)
74
+ return false if constraints.nil?
75
+ constraints.any? { |b| b.subset?(params) }
76
+ end
77
+
78
+ private
79
+
80
+ def comb
81
+ ranges = (0...t).to_a.inject([]) do |a, i|
82
+ a << (0...params[i].length).map { |j| params[i][j] }
83
+ end
84
+
85
+ products = ranges[1..-1].inject(ranges[0]) do |a, b|
86
+ a = a.product(b)
87
+ end
88
+
89
+ result = products.map(&:flatten)
90
+ .map { |a| TestCase.create(params, unbound_param_pool, a) }
91
+ result
92
+ end
93
+
94
+ def comb_i(param_i)
95
+ values = (0...param_i).to_a.combination((t-1)).to_a
96
+ values.each do |a|
97
+ a << param_i
98
+ end
99
+ result = []
100
+ values.each do |a|
101
+ result += a[1..-1]
102
+ .inject((0...params[a[0]].length).map { |b| params[a[0]][b] }) { |p, i| p.product((0...params[i].length).to_a.map { |c| params[i][c] }) }
103
+ .map(&:flatten)
104
+ .map { |a| TestCase.create(params, unbound_param_pool, a) }
105
+ end
106
+ result.to_set
107
+ end
108
+
109
+
110
+ def fill_unbound(data)
111
+ arr = Array.new(params.length)
112
+ data.each do |param|
113
+ unless param.unbound?
114
+ i = @map_to_orig_index[param.i]
115
+ arr[i] = @input_params[i][param.j]
116
+ end
117
+ end
118
+
119
+ arr.each_with_index do |e, i|
120
+ next unless e.nil?
121
+
122
+ orig_param = @input_params[i]
123
+ (0...orig_param.length).each do |j|
124
+ data << params[@map_to_orig_index.key(i)][j]
125
+ if violates_constraints?(data)
126
+ data.delete(params[@map_to_orig_index.key(i)][j])
127
+ next
128
+ else
129
+ arr[i] = orig_param[j]
130
+ break
131
+ end
132
+ end
133
+ return nil if arr[i].nil?
134
+ end
135
+
136
+ return nil if violates_constraints?(data)
137
+
138
+ arr
139
+ end
140
+ end # IPOGHelper
141
+ end # Dither
@@ -0,0 +1,29 @@
1
+
2
+ module Dither
3
+
4
+ def self.all_pairs(params, t = 2, opts = {})
5
+ constraints = constraints_to_java(params.length, opts[:constraints])
6
+ com.github.jesg.dither.Dither.ipog(
7
+ t.to_java(:int),
8
+ params.map(&:to_java).to_java,
9
+ constraints).to_a
10
+ rescue com.github.jesg.dither.DitherError => e
11
+ raise Dither::Error.new(e.message)
12
+ end
13
+
14
+ private
15
+
16
+ def self.constraints_to_java(param_length, constraints)
17
+ return [].to_java if constraints.nil?
18
+ result = []
19
+ constraints.each do |constraint|
20
+ new_constraint = Array.new(param_length)
21
+ constraint.each do |k, v|
22
+ new_constraint[k] = v
23
+ puts "#{k} => #{v}"
24
+ end
25
+ result << new_constraint
26
+ end
27
+ result.map { |a| a.to_java(java.lang.Integer) }.to_java
28
+ end
29
+ end
@@ -0,0 +1,85 @@
1
+ # coding: utf-8
2
+
3
+ module Dither
4
+ class MIPOG
5
+ include Dither::IPOGHelper
6
+
7
+ def maximize_unbound_coverage(i, test_case, pi)
8
+ all_unbound = test_case.unbound
9
+ .map { |a| a.create_params(params[a.i].length) }
10
+ .flatten
11
+
12
+ current_max = 0
13
+ current_max_j = 0
14
+ current_outer_param = all_unbound[0]
15
+ current_matches = []
16
+
17
+ all_unbound.each do |outer_param|
18
+ test_case << outer_param
19
+
20
+ (0...params[i].length).each do |j|
21
+ current_param = params[i][j]
22
+ test_case << current_param
23
+ count = pi.count { |a| a.subset?(test_case) }
24
+
25
+ if count > current_max
26
+ current_max = count
27
+ current_max_j = j
28
+ current_outer_param = outer_param
29
+ end
30
+ test_case.delete(current_param)
31
+ end
32
+ test_case.delete(outer_param)
33
+ end
34
+
35
+ test_case << params[i][current_max_j]
36
+ test_case << current_outer_param
37
+ test_case.delete(unbound_param_pool[current_outer_param.i])
38
+
39
+ current_matches
40
+ end
41
+
42
+ def run
43
+ # add into test set a test for each combination of values
44
+ # of the first t parameter
45
+ test_set = comb
46
+
47
+ (t...params.length).each do |i|
48
+ # let pi
49
+ # be the set of t-way combinations of values involving
50
+ # parameter Pi and t -1 parameters among the first i – 1
51
+ # parameters
52
+ pi = comb_i(i)
53
+
54
+ # horizontal extension for parameter i
55
+ test_set.each do |test_case|
56
+ if !test_case.contains_unbound?
57
+ cover = maximize_coverage(i, test_case, pi)
58
+ else
59
+ cover = maximize_unbound_coverage(i, test_case, pi)
60
+ end
61
+
62
+ # remove covered combinations
63
+ pi -= cover
64
+ end
65
+
66
+ # vertical extension for parameter i
67
+ until pi.empty?
68
+ pi.sort!
69
+ test_case, coverage = maximize_vertical_coverage(i, pi[0].dup, pi)
70
+ test_set << test_case.create_unbound(i)
71
+ pi -= coverage
72
+ end
73
+ end
74
+ test_set.map { |a| fill_unbound(a) }
75
+ end
76
+
77
+ def maximize_vertical_coverage(i, test_case, pi)
78
+ coverage = [pi[0]]
79
+ pi[1..-1].each do |a|
80
+ coverage << a unless test_case.merge_without_conflict(i, a).nil?
81
+ end
82
+ [test_case, coverage]
83
+ end
84
+ end # MIPOG
85
+ end # Dither
@@ -0,0 +1,19 @@
1
+
2
+ module Dither
3
+ Param = Struct.new(:i, :j) do
4
+ def <=>(param)
5
+ return 1 if param.unbound?
6
+
7
+ a = i <=> param.i
8
+ if a == 0
9
+ return j <=> param.j
10
+ else
11
+ return a
12
+ end
13
+ end
14
+
15
+ def unbound?
16
+ false
17
+ end
18
+ end # Param
19
+ end # Dither
@@ -0,0 +1,80 @@
1
+
2
+ module Dither
3
+ class TestCase < Set
4
+
5
+ attr_accessor :bound_param_pool, :unbound_param_pool
6
+
7
+ def self.create(bound_param_pool, unbound_param_pool, params)
8
+ test_case = TestCase.new(params)
9
+ test_case.bound_param_pool = bound_param_pool
10
+ test_case.unbound_param_pool = unbound_param_pool
11
+ test_case
12
+ end
13
+
14
+ def contains_unbound?
15
+ self.any?(&:unbound?)
16
+ end
17
+
18
+ def unbound
19
+ self.select(&:unbound?)
20
+ end
21
+
22
+ def <=>(test_case)
23
+ result = 0
24
+ l = length <= test_case.length ? length : test_case.length
25
+ self.zip(test_case)[0...l].each do |arr|
26
+ first, second = arr
27
+ result = first <=> second
28
+ break if result != 0
29
+ end
30
+ result
31
+ end
32
+
33
+ def create_unbound(i)
34
+ bound_params = self.reject(&:unbound?).map(&:i)
35
+ ((0..i).to_a - bound_params).each do |a|
36
+ self << unbound_param_pool[a]
37
+ end
38
+ self
39
+ end
40
+
41
+ def to_ipog_array(i)
42
+ arr = Array.new(i)
43
+ self.each do |param|
44
+ arr[param.i] = param.j unless param.unbound?
45
+ end
46
+ arr
47
+ end
48
+
49
+ # return nil if there is a conflict
50
+ # return self if no conflict
51
+ def merge_without_conflict(i, test_case, &block)
52
+ new_elements = []
53
+ self.to_ipog_array(i).zip(test_case.to_ipog_array(i))
54
+ .each_with_index do |arr, a|
55
+ first, second = arr
56
+
57
+ if first.nil? && second.nil?
58
+ new_elements << unbound_param_pool[a]
59
+ elsif (first == second) || second.nil?
60
+ next
61
+ elsif first.nil?
62
+ new_elements << bound_param_pool[a][second]
63
+ else
64
+ return nil
65
+ end
66
+ end
67
+
68
+ new_self = self.clone
69
+ new_elements.each { |a| new_self << a }
70
+
71
+ return nil if block_given? && block.call(new_self)
72
+
73
+ new_elements.each do |a|
74
+ self.delete(unbound_param_pool[a.i]) unless a.unbound?
75
+ self << a
76
+ end
77
+ self
78
+ end
79
+ end # TestCase
80
+ end # Dither
@@ -0,0 +1,17 @@
1
+
2
+ module Dither
3
+ UnboundParam = Struct.new(:i) do
4
+ def <=>(param)
5
+ return -1 unless param.unbound?
6
+ i <=> param.i
7
+ end
8
+
9
+ def unbound?
10
+ true
11
+ end
12
+
13
+ def create_params(j)
14
+ (0...j).map { |a| Param.new(i, a) }
15
+ end
16
+ end # UnboundParam
17
+ end # Dither
@@ -0,0 +1,4 @@
1
+
2
+ module Dither
3
+ VERSION = '0.0.8'
4
+ end
data/lib/dither.jar ADDED
Binary file
data/lib/dither.rb ADDED
@@ -0,0 +1,30 @@
1
+
2
+ require 'set'
3
+
4
+ module Dither
5
+
6
+ class Error < StandardError; end
7
+
8
+ def self.all_pairs(params, t = 2, opts = {})
9
+ IPOG.new(params, t, opts).run
10
+ end
11
+
12
+ def self.mipog(params, t = 2, opts = {})
13
+ raise Error, 'mipog does not support constraints' if opts.key?(:constraints)
14
+ MIPOG.new(params, t, opts).run
15
+ end
16
+ end # Dither
17
+
18
+ require 'dither/param'
19
+ require 'dither/unbound_param'
20
+ require 'dither/test_case'
21
+ require 'dither/ipog_helper'
22
+ require 'dither/ipog'
23
+ require 'dither/mipog'
24
+
25
+ if RUBY_PLATFORM =~ /java/
26
+ require 'java'
27
+ require 'dither.jar'
28
+
29
+ require 'dither/java_ext/dither'
30
+ end
@@ -0,0 +1,222 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Dither do
4
+
5
+ it 'mipog does not support constraints' do
6
+ expect { Dither.mipog([[1,1],[1,2]], 2, :constraints => []) }.to raise_error(Dither::Error, 'mipog does not support constraints')
7
+ end
8
+
9
+ it 't must be >= 2' do
10
+ expect { Dither.all_pairs([], 0) }.to raise_error(Dither::Error, 't must be >= 2')
11
+ end
12
+
13
+ it 't must be <= params.length' do
14
+ expect { Dither.all_pairs([(0...3).to_a], 4) }.to raise_error(Dither::Error,'t must be <= params.length')
15
+ end
16
+
17
+ it 'param length must be > 1' do
18
+ expect { Dither.all_pairs([[], []], 2) }.to raise_error(Dither::Error,'param length must be > 1')
19
+ end
20
+
21
+ it 'can compute 2-way ipog using symbols' do
22
+ params = [[:a, :b, :c], [:d, :e, :f], [:h, :i]]
23
+ expect(Dither.all_pairs(params)).to eq([[:a, :d, :h],
24
+ [:a, :e, :i],
25
+ [:a, :f, :h],
26
+ [:b, :d, :i],
27
+ [:b, :e, :h],
28
+ [:b, :f, :i],
29
+ [:c, :d, :h],
30
+ [:c, :e, :i],
31
+ [:c, :f, :h]])
32
+ end
33
+
34
+ it 'can compute 3-way mipog' do
35
+ params = [(0...2).to_a, (0...2).to_a, (0..3).to_a]
36
+ expect(Dither.mipog(params, 3)).to eq([[0, 0, 0],
37
+ [1, 0, 0],
38
+ [0, 1, 0],
39
+ [1, 1, 0],
40
+ [0, 0, 1],
41
+ [1, 0, 1],
42
+ [0, 1, 1],
43
+ [1, 1, 1],
44
+ [0, 0, 2],
45
+ [1, 0, 2],
46
+ [0, 1, 2],
47
+ [1, 1, 2],
48
+ [0, 0, 3],
49
+ [1, 0, 3],
50
+ [0, 1, 3],
51
+ [1, 1, 3],
52
+ ])
53
+ end
54
+
55
+ it 'can compute 2-way mipog using symbols' do
56
+ params = [[:a, :b, :c], [:d, :e, :f], [:h, :i]]
57
+ expect(Dither.mipog(params).to_set).to eq([[:a, :d, :h],
58
+ [:a, :e, :i],
59
+ [:a, :f, :h],
60
+ [:b, :d, :i],
61
+ [:b, :e, :h],
62
+ [:b, :f, :i],
63
+ [:c, :d, :h],
64
+ [:c, :e, :i],
65
+ [:c, :f, :h]].to_set)
66
+ end
67
+
68
+ it 'can compute 2-way mipog' do
69
+ params = [(0...2).to_a, (0..3).to_a]
70
+ expect(Dither.mipog(params)).to eq([
71
+ [0, 0],
72
+ [1, 0],
73
+ [0, 1],
74
+ [1, 1],
75
+ [0, 2],
76
+ [1, 2],
77
+ [0, 3],
78
+ [1, 3],
79
+ ])
80
+ end
81
+
82
+ it 'can compute 2-way ipog' do
83
+ params = [(0...2).to_a, (0..3).to_a]
84
+ expect(Dither.all_pairs(params)).to eq([
85
+ [0, 0],
86
+ [1, 0],
87
+ [0, 1],
88
+ [1, 1],
89
+ [0, 2],
90
+ [1, 2],
91
+ [0, 3],
92
+ [1, 3],
93
+ ])
94
+ end
95
+
96
+ it 'can compute 3-way ipog' do
97
+ params = [(0...2).to_a, (0...2).to_a, (0..3).to_a]
98
+ expect(Dither.all_pairs(params, 3).to_set).to eq([[0, 0, 0],
99
+ [1, 0, 0],
100
+ [0, 1, 0],
101
+ [1, 1, 0],
102
+ [0, 0, 1],
103
+ [1, 0, 1],
104
+ [0, 1, 1],
105
+ [1, 1, 1],
106
+ [0, 0, 2],
107
+ [1, 0, 2],
108
+ [0, 1, 2],
109
+ [1, 1, 2],
110
+ [0, 0, 3],
111
+ [1, 0, 3],
112
+ [0, 1, 3],
113
+ [1, 1, 3],
114
+ ].to_set)
115
+ end
116
+
117
+ it 'can compute 3-way ipog with constraints' do
118
+ params = [(0...2).to_a, (0...2).to_a, (0..3).to_a]
119
+ expect(Dither.all_pairs(params, 3,
120
+ :constraints => [
121
+ {0 => 0,
122
+ 2 => 2},
123
+ {0 => 0,
124
+ 1 => 1,
125
+ 2 => 0}
126
+ ]).to_set).to eq([[0, 0, 0],
127
+ [1, 0, 0],
128
+ [1, 1, 0],
129
+ [0, 0, 1],
130
+ [1, 0, 1],
131
+ [0, 1, 1],
132
+ [1, 1, 1],
133
+ [1, 0, 2],
134
+ [1, 1, 2],
135
+ [0, 0, 3],
136
+ [1, 0, 3],
137
+ [0, 1, 3],
138
+ [1, 1, 3],
139
+ ].to_set)
140
+ end
141
+
142
+ it 'another 3-way ipog with constraints' do
143
+ params = [(0...2).to_a, (0...2).to_a, (0...2).to_a, (0..3).to_a]
144
+ expect(Dither.all_pairs(params, 3,
145
+ :constraints => [
146
+ {0 => 0,
147
+ 1 => 1,
148
+ 2 => 0}
149
+ ]).to_set).to eq([[0, 0, 0, 0],
150
+ [1, 1, 0, 0],
151
+ [1, 0, 1, 0],
152
+ [0, 1, 1, 0],
153
+ [1, 0, 0, 1],
154
+ [1, 1, 0, 1],
155
+ [0, 0, 1, 1],
156
+ [1, 1, 1, 1],
157
+ [0, 0, 0, 2],
158
+ [1, 1, 0, 2],
159
+ [1, 0, 1, 2],
160
+ [0, 1, 1, 2],
161
+ [0, 0, 0, 3],
162
+ [1, 1, 0, 3],
163
+ [1, 0, 1, 3],
164
+ [0, 1, 1, 3],
165
+ [0, 0, 0, 1],
166
+ [0, 1, 1, 1]].to_set)
167
+
168
+ # results = Dither.all_pairs([
169
+ # (0...10).to_a,
170
+ # (0...10).to_a,
171
+ # (0...4).to_a,
172
+ # (0...3).to_a,
173
+ # (0...3).to_a,
174
+ # (0...2).to_a,
175
+ # (0...2).to_a,
176
+ # (0...2).to_a,
177
+ # (0...2).to_a,
178
+ # (0...2).to_a,
179
+ # (0...2).to_a,
180
+ # (0...2).to_a,
181
+ # ], 4)
182
+
183
+ # results = Dither.all_pairs([
184
+ # (0...4).to_a,
185
+ # (0...4).to_a,
186
+ # (0...4).to_a,
187
+ # (0...4).to_a,
188
+ # (0...4).to_a,
189
+ # (0...3).to_a,
190
+ # (0...3).to_a,
191
+ # (0...3).to_a,
192
+ # (0...3).to_a,
193
+ # ], 2)
194
+
195
+
196
+ results = Dither.all_pairs([
197
+ (0...2).to_a, # user type
198
+ (0...2).to_a, # exists?
199
+ (0...2).to_a, # seats
200
+ (0...2).to_a, # seats
201
+ (0...3).to_a, # user region
202
+ (0...3).to_a, # currency
203
+ (0...3).to_a,
204
+ (0...4).to_a, # payment
205
+ (0...6).to_a, # delivery
206
+ (0...6).to_a,
207
+ ], 3)
208
+
209
+ # mipog 2-way 36... ipog 36
210
+ # mipog 3-way 156... ipog 151
211
+ # mipog 4-way 592... ipog 511
212
+
213
+ # results = Dither.all_pairs( [[1,2],
214
+ # ['1','2'],
215
+ # [1.0,2.0],
216
+ # [true, false, 3]],3)
217
+ require 'csv'
218
+ results.each { |a| puts a.to_csv }
219
+ puts results.count
220
+
221
+ end
222
+ end
@@ -0,0 +1,5 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ $LOAD_PATH.unshift File.expand_path("../lib")
5
+ require 'dither'
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dither
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: java
6
+ authors:
7
+ - Jason Gowan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ requirement: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: '3.2'
25
+ prerelease: false
26
+ type: :development
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 0.9.2
39
+ prerelease: false
40
+ type: :development
41
+ - !ruby/object:Gem::Dependency
42
+ name: coveralls
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ prerelease: false
54
+ type: :development
55
+ description: Efficient test generation strategies
56
+ email:
57
+ - gowanjason@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .ruby-version
64
+ - .travis.yml
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - dither.gemspec
71
+ - lib/dither.jar
72
+ - lib/dither.rb
73
+ - lib/dither/ipog.rb
74
+ - lib/dither/ipog_helper.rb
75
+ - lib/dither/java_ext/dither.rb
76
+ - lib/dither/mipog.rb
77
+ - lib/dither/param.rb
78
+ - lib/dither/test_case.rb
79
+ - lib/dither/unbound_param.rb
80
+ - lib/dither/version.rb
81
+ - spec/dither/dither_spec.rb
82
+ - spec/spec_helper.rb
83
+ homepage: https://github.com/jesg/dither
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project: dither
103
+ rubygems_version: 2.4.5
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Collection of test generation strategies
107
+ test_files:
108
+ - spec/dither/dither_spec.rb
109
+ - spec/spec_helper.rb