casegen 1.3.0 → 2.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +25 -0
- data/LICENSE +21 -0
- data/README.md +132 -0
- data/Rakefile +11 -0
- data/TODO +26 -0
- data/bin/casegen +2 -7
- data/casegen.gemspec +26 -0
- data/{src → doc}/calc.sample.txt +0 -0
- data/doc/cart.sample.rb +3 -0
- data/{src → doc}/cart.sample.txt +0 -0
- data/{src/ruby_array.sample.txt → doc/ruby_array.sample.rb} +6 -0
- data/{src → lib}/agents/sets.rb +49 -72
- data/{src → lib}/agents/sets/enum/by.rb +0 -0
- data/{src → lib}/agents/sets/enum/cluster.rb +0 -0
- data/lib/agents/sets/enum/inject.rb +50 -0
- data/{src → lib}/agents/sets/enum/nest.rb +0 -0
- data/{src → lib}/agents/sets/enum/op.rb +0 -0
- data/{src → lib}/agents/sets/enum/pipe.rb +0 -0
- data/{src → lib}/agents/sets/enum/tree.rb +0 -0
- data/{src → lib}/casegen.rb +1 -7
- data/test/agents/console_output_test.rb +27 -0
- data/test/agents/sets.test.rb +227 -0
- data/test/agents_test.rb +41 -0
- data/test/casegen.tests.rb +0 -0
- data/test/parser_test.rb +163 -0
- data/test/test_helper.rb +2 -0
- metadata +93 -35
- data/src/agents/sets/enum/inject.rb +0 -50
- data/src/agents/sets/enum/install.rb +0 -73
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ee14f6a724a837cba03b3ec269718713400ad45e2b49b11c3e9022abe56e4587
|
4
|
+
data.tar.gz: 1b2ccea7698217314e4722f4c3543e2b54566e6d2c003d3f00e7942b46802962
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3b8a1f42c2bff9fa37a147e96807123afa94941c41588f00903f8cb82541bd90ca0ab72b4fdf53dd319d9fb7e557cbf39485bcaa38b24b69870eb1e193c5470
|
7
|
+
data.tar.gz: 7fb847d1589799ef522a3fde0ff1f8d6322c67045fb555ed809baa98432b66f86b07cb339ddfc703e232e3a905b71721b85eb1add2bf8bada8704e1a7106b78f
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.1
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
casegen (2.0.0)
|
5
|
+
tablesmith
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
minitest (5.11.3)
|
11
|
+
rake (12.3.1)
|
12
|
+
tablesmith (0.4.1)
|
13
|
+
text-table
|
14
|
+
text-table (1.2.4)
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
casegen!
|
21
|
+
minitest
|
22
|
+
rake
|
23
|
+
|
24
|
+
BUNDLED WITH
|
25
|
+
1.17.3
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Chris Morris
|
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,132 @@
|
|
1
|
+
# CaseGen
|
2
|
+
|
3
|
+
CaseGen is a small Ruby external DSL for generating combinations of variables,
|
4
|
+
optionally restricted by a set of rules.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
This input file:
|
9
|
+
|
10
|
+
sets
|
11
|
+
------------
|
12
|
+
payment: Credit, Check, Online Bank
|
13
|
+
amount: 100, 1,000, 10,000
|
14
|
+
shipping: Ground, Air
|
15
|
+
ship to country: US, Outside US
|
16
|
+
bill to country: US, Outside US
|
17
|
+
|
18
|
+
|
19
|
+
rules(sets)
|
20
|
+
---------------------------
|
21
|
+
exclude shipping = Ground AND ship to country = Outside US
|
22
|
+
Our ground shipper will only ship things within the US.
|
23
|
+
|
24
|
+
exclude payment = Check AND bill to country == Outside US
|
25
|
+
Our bank will not accept checks written from banks outside the US.
|
26
|
+
|
27
|
+
exclude payment = Online Bank AND amount == 1,000
|
28
|
+
exclude payment = Online Bank AND amount == 10,000
|
29
|
+
While the online bank will process amounts > $1,000, we've experienced
|
30
|
+
occasional problems with their services and have had to write off some
|
31
|
+
transactions, so we no longer allow this payment option for amounts greater
|
32
|
+
than $1,000
|
33
|
+
|
34
|
+
exclude ship to country = US AND bill to country = Outside US
|
35
|
+
If we're shipping to the US, billing party cannot be outside US
|
36
|
+
|
37
|
+
|
38
|
+
console(rules)
|
39
|
+
----------
|
40
|
+
|
41
|
+
|
42
|
+
produces this output:
|
43
|
+
|
44
|
+
+-------------+--------+----------+-----------------+-----------------+
|
45
|
+
| payment | amount | shipping | ship to country | bill to country |
|
46
|
+
+-------------+--------+----------+-----------------+-----------------+
|
47
|
+
| Credit | 100 | Ground | US | US |
|
48
|
+
| Credit | 100 | Air | US | US |
|
49
|
+
| Credit | 100 | Air | Outside US | US |
|
50
|
+
| Credit | 100 | Air | Outside US | Outside US |
|
51
|
+
| Credit | 1,000 | Ground | US | US |
|
52
|
+
| Credit | 1,000 | Air | US | US |
|
53
|
+
| Credit | 1,000 | Air | Outside US | US |
|
54
|
+
| Credit | 1,000 | Air | Outside US | Outside US |
|
55
|
+
| Credit | 10,000 | Ground | US | US |
|
56
|
+
| Credit | 10,000 | Air | US | US |
|
57
|
+
| Credit | 10,000 | Air | Outside US | US |
|
58
|
+
| Credit | 10,000 | Air | Outside US | Outside US |
|
59
|
+
| Check | 100 | Ground | US | US |
|
60
|
+
| Check | 100 | Air | US | US |
|
61
|
+
| Check | 100 | Air | Outside US | US |
|
62
|
+
| Check | 1,000 | Ground | US | US |
|
63
|
+
| Check | 1,000 | Air | US | US |
|
64
|
+
| Check | 1,000 | Air | Outside US | US |
|
65
|
+
| Check | 10,000 | Ground | US | US |
|
66
|
+
| Check | 10,000 | Air | US | US |
|
67
|
+
| Check | 10,000 | Air | Outside US | US |
|
68
|
+
| Online Bank | 100 | Ground | US | US |
|
69
|
+
| Online Bank | 100 | Air | US | US |
|
70
|
+
| Online Bank | 100 | Air | Outside US | US |
|
71
|
+
| Online Bank | 100 | Air | Outside US | Outside US |
|
72
|
+
+-------------+--------+----------+-----------------+-----------------+
|
73
|
+
|
74
|
+
exclude shipping = Ground AND ship to country = Outside US
|
75
|
+
Our ground shipper will only ship things within the US.
|
76
|
+
|
77
|
+
exclude payment = Check AND bill to country == Outside US
|
78
|
+
Our bank will not accept checks written from banks outside the US.
|
79
|
+
|
80
|
+
exclude payment = Online Bank AND amount == 1,000
|
81
|
+
|
82
|
+
exclude payment = Online Bank AND amount == 10,000
|
83
|
+
While the online bank will process amounts > $1,000, we've experienced
|
84
|
+
occasional problems with their services and have had to write off some
|
85
|
+
transactions, so we no longer allow this payment option for amounts greater
|
86
|
+
than $1,000
|
87
|
+
|
88
|
+
exclude ship to country = US AND bill to country = Outside US
|
89
|
+
If we're shipping to the US, billing party cannot be outside US
|
90
|
+
|
91
|
+
If you pull the source locally, you can execute this:
|
92
|
+
|
93
|
+
casegen doc/cart.sample.txt
|
94
|
+
|
95
|
+
## FAQ
|
96
|
+
|
97
|
+
How can I use this lib inside another Ruby file, instead of having a separate
|
98
|
+
input file?
|
99
|
+
|
100
|
+
sample.rb:
|
101
|
+
|
102
|
+
require "bundler/inline"
|
103
|
+
|
104
|
+
gemfile do
|
105
|
+
source "https://rubygems.org"
|
106
|
+
gem "casegen", "~> 2.0"
|
107
|
+
end
|
108
|
+
|
109
|
+
require 'casegen'
|
110
|
+
|
111
|
+
CLabs::CaseGen::CaseGen.new(DATA.read)
|
112
|
+
|
113
|
+
__END__
|
114
|
+
|
115
|
+
sets
|
116
|
+
----
|
117
|
+
a: 1, 2
|
118
|
+
b: 3, 4
|
119
|
+
|
120
|
+
rules(sets)
|
121
|
+
-----------
|
122
|
+
exclude a = 1
|
123
|
+
|
124
|
+
console(rules)
|
125
|
+
--------------
|
126
|
+
|
127
|
+
|
128
|
+
### Are there other tools similar to CaseGen?
|
129
|
+
|
130
|
+
<a href="http://code.google.com/p/tcases/">tcases</a> is one to check out.
|
131
|
+
Another is <a href="http://www.satisfice.com/tools.shtml">AllPairs</a> by James
|
132
|
+
Bach.
|
data/Rakefile
ADDED
data/TODO
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
- OR not supported yet.
|
2
|
+
- Nested booleans not supported yet.
|
3
|
+
- performance problems
|
4
|
+
|
5
|
+
two problems: formatting table is very slow, too many iterations. Sets agent can get
|
6
|
+
col widths easy, but it may not be passed to the console agent, so may need to support
|
7
|
+
"console(rules, sets)" syntax
|
8
|
+
|
9
|
+
the actual enum product call is fairly quick, but the rules are 3x as slow. Need a way
|
10
|
+
to maybe hold off on generating the combinations and then hook in with a block to filter
|
11
|
+
them as they're being made - save another run through the whole set.
|
12
|
+
|
13
|
+
- support for "assign ... when ..."
|
14
|
+
- if condition specified has an incorrect value, notify user
|
15
|
+
- don't require comma AND SPACE in set lists ... ? (This is currently that way to allow thousands separators in values)
|
16
|
+
|
17
|
+
- this case:
|
18
|
+
exclude Cl = Ser AND Rec = K12RF(1.01)
|
19
|
+
exclude Cl = Ser AND Rec = G2IR(white)
|
20
|
+
exclude Cl = Num AND Herf(11)
|
21
|
+
|
22
|
+
blows up without a meaningful error
|
23
|
+
|
24
|
+
- meaningful exceptions still are exceptions, and you have a full stacktrace - make it purty.
|
25
|
+
|
26
|
+
- LICENSE of enum lib contents.
|
data/bin/casegen
CHANGED
data/casegen.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'casegen'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'casegen'
|
7
|
+
gem.version = CLabs::CaseGen::CaseGen.version
|
8
|
+
gem.authors = ['chrismo']
|
9
|
+
gem.email = 'chrismo@clabs.org'
|
10
|
+
gem.description = 'Simple Ruby DSL to generate use cases restricted by sets of rules'
|
11
|
+
gem.summary = 'Simple Ruby DSL to generate use cases restricted by sets of rules'
|
12
|
+
gem.homepage = 'https://github.com/chrismo/casegen'
|
13
|
+
gem.license = 'MIT'
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = 'casegen'
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.required_ruby_version = '~> 2.3'
|
21
|
+
|
22
|
+
gem.add_dependency 'tablesmith'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'minitest'
|
25
|
+
gem.add_development_dependency 'rake'
|
26
|
+
end
|
data/{src → doc}/calc.sample.txt
RENAMED
File without changes
|
data/doc/cart.sample.rb
ADDED
data/{src → doc}/cart.sample.txt
RENAMED
File without changes
|
data/{src → lib}/agents/sets.rb
RENAMED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "#{File.dirname(__FILE__)}/../casegen"
|
2
2
|
$LOAD_PATH << "#{File.expand_path(File.join(File.dirname(__FILE__), 'sets'))}"
|
3
3
|
require 'enum/op'
|
4
|
+
require 'tablesmith'
|
4
5
|
|
5
6
|
class String
|
6
7
|
def to_u
|
@@ -11,35 +12,35 @@ end
|
|
11
12
|
module CLabs::CaseGen
|
12
13
|
class Set
|
13
14
|
attr_reader :name, :data
|
14
|
-
|
15
|
+
|
15
16
|
def initialize(name, data_array)
|
16
17
|
@name = name
|
17
18
|
@data = data_array
|
18
19
|
strip_data
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
def strip_data
|
22
23
|
@data.collect! do |datum| datum.strip end
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
def values
|
26
27
|
@data
|
27
28
|
end
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
class Sets < Agent
|
31
32
|
attr_accessor :sets, :combinations, :set_titles
|
32
|
-
|
33
|
+
|
33
34
|
def Sets.agent_id
|
34
35
|
"casegen:sets"
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
def initialize(data, reference_agents=nil)
|
38
39
|
@data = data
|
39
40
|
@sets = []
|
40
41
|
parse_sets
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
def parse_sets
|
44
45
|
set_names = @data.scan(/^\s*(\w.*):/)
|
45
46
|
set_data = @data.scan(/:(.*)/)
|
@@ -49,7 +50,7 @@ module CLabs::CaseGen
|
|
49
50
|
end
|
50
51
|
generate_combinations
|
51
52
|
end
|
52
|
-
|
53
|
+
|
53
54
|
def generate_combinations
|
54
55
|
arrays = []
|
55
56
|
@set_titles = []
|
@@ -66,30 +67,30 @@ module CLabs::CaseGen
|
|
66
67
|
EnumerableOperator::Product.new(*args).each { |tuple|
|
67
68
|
result << tuple
|
68
69
|
}
|
69
|
-
result
|
70
|
+
result
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
def set_names
|
73
74
|
names = []
|
74
75
|
@sets.each do |set| names << set.name end
|
75
76
|
names
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
def set_by_name(setname)
|
79
80
|
@sets.detect do |set| set.name =~ /#{Regexp.escape(setname)}/ end
|
80
81
|
end
|
81
|
-
|
82
|
+
|
82
83
|
end
|
83
|
-
|
84
|
+
|
84
85
|
class Criteria
|
85
86
|
attr_reader :set_names, :set_values, :equalities
|
86
|
-
|
87
|
+
|
87
88
|
def initialize(data)
|
88
89
|
@data = data
|
89
90
|
@equalities = {}
|
90
91
|
parse
|
91
92
|
end
|
92
|
-
|
93
|
+
|
93
94
|
def parse
|
94
95
|
@data.split(/AND/).each do |bit|
|
95
96
|
set_name, set_value = bit.split(/==|=/)
|
@@ -102,8 +103,8 @@ module CLabs::CaseGen
|
|
102
103
|
@set_names = @equalities.keys
|
103
104
|
@set_values = @equalities.values
|
104
105
|
end
|
105
|
-
|
106
|
-
# hash keys should be valid set names and hash values should be valid
|
106
|
+
|
107
|
+
# hash keys should be valid set names and hash values should be valid
|
107
108
|
# set values in the named set
|
108
109
|
def match(hash)
|
109
110
|
# must match all equalities
|
@@ -114,20 +115,20 @@ module CLabs::CaseGen
|
|
114
115
|
end
|
115
116
|
return true
|
116
117
|
end
|
117
|
-
|
118
|
+
|
118
119
|
def to_s
|
119
120
|
@data
|
120
121
|
end
|
121
122
|
end
|
122
|
-
|
123
|
+
|
123
124
|
class Rule
|
124
125
|
attr_reader :criteria, :description, :data
|
125
|
-
|
126
|
+
|
126
127
|
def initialize(rule_data)
|
127
128
|
@data = rule_data
|
128
129
|
parse_rule
|
129
130
|
end
|
130
|
-
|
131
|
+
|
131
132
|
def parse_rule
|
132
133
|
data = @data.sub(self.class.regexp, '')
|
133
134
|
criteria_data, *@description = data.split(/\n/)
|
@@ -136,41 +137,41 @@ module CLabs::CaseGen
|
|
136
137
|
@description = (@description.join("\n") + "\n").outdent.strip
|
137
138
|
end
|
138
139
|
end
|
139
|
-
|
140
|
+
|
140
141
|
class ExcludeRule < Rule
|
141
142
|
def type_description
|
142
143
|
"exclude"
|
143
144
|
end
|
144
|
-
|
145
|
+
|
145
146
|
def ExcludeRule.regexp
|
146
147
|
/^exclude/i
|
147
148
|
end
|
148
|
-
|
149
|
+
|
149
150
|
def ExcludeRule.create(rule_data)
|
150
151
|
return ExcludeRule.new(rule_data) if rule_data =~ regexp
|
151
152
|
return nil
|
152
153
|
end
|
153
154
|
end
|
154
|
-
|
155
|
+
|
155
156
|
class Rules < Agent
|
156
157
|
def Rules.agent_id
|
157
158
|
"casegen:rules"
|
158
159
|
end
|
159
|
-
|
160
|
+
|
160
161
|
def initialize(data, reference_agents=[])
|
161
162
|
@data = data
|
162
163
|
@agents = reference_agents
|
163
164
|
@rules = []
|
164
165
|
@rule_classes = []
|
165
|
-
ObjectSpace.each_object(Class) do |obj|
|
166
|
-
@rule_classes << obj if obj.ancestors.include?(Rule) && obj != Rule
|
166
|
+
ObjectSpace.each_object(Class) do |obj|
|
167
|
+
@rule_classes << obj if obj.ancestors.include?(Rule) && obj != Rule
|
167
168
|
end
|
168
169
|
parse_data
|
169
170
|
end
|
170
|
-
|
171
|
+
|
171
172
|
def parse_data
|
172
173
|
raw_rules = @data.split(/(?=^\S)/)
|
173
|
-
|
174
|
+
|
174
175
|
raw_rules.each do |rule|
|
175
176
|
@rule_classes.each do |rule_class|
|
176
177
|
@rules << rule_class.create(rule.strip)
|
@@ -180,7 +181,7 @@ module CLabs::CaseGen
|
|
180
181
|
@rules.flatten!
|
181
182
|
validate_rules
|
182
183
|
end
|
183
|
-
|
184
|
+
|
184
185
|
def validate_rules
|
185
186
|
@agents.each do |agent|
|
186
187
|
if agent.class == Sets
|
@@ -188,7 +189,7 @@ module CLabs::CaseGen
|
|
188
189
|
rule.criteria.equalities.each_pair do |set_name, set_value|
|
189
190
|
set = agent.set_by_name(set_name)
|
190
191
|
if set.nil?
|
191
|
-
raise ParserException.new("Invalid set name <#{set_name}> " +
|
192
|
+
raise ParserException.new("Invalid set name <#{set_name}> " +
|
192
193
|
"in rule <#{rule.criteria}>. Valid set names are <#{agent.set_names.join(', ')}>.")
|
193
194
|
end
|
194
195
|
if !set.values.include?(set_value)
|
@@ -201,19 +202,19 @@ module CLabs::CaseGen
|
|
201
202
|
end
|
202
203
|
end
|
203
204
|
end
|
204
|
-
|
205
|
+
|
205
206
|
def length
|
206
207
|
@rules.length
|
207
208
|
end
|
208
|
-
|
209
|
+
|
209
210
|
def [](index)
|
210
211
|
return @rules[index]
|
211
212
|
end
|
212
|
-
|
213
|
+
|
213
214
|
def each(&block)
|
214
215
|
@rules.each(&block)
|
215
216
|
end
|
216
|
-
|
217
|
+
|
217
218
|
def combinations
|
218
219
|
return @combinations if !@combinations.nil?
|
219
220
|
if @agents[0].class == Sets
|
@@ -227,7 +228,7 @@ module CLabs::CaseGen
|
|
227
228
|
# combo_hash will have set names matched with set values
|
228
229
|
agent.set_titles.each do |title|
|
229
230
|
combo_hash[title] = combo[i]
|
230
|
-
i += 1
|
231
|
+
i += 1
|
231
232
|
end
|
232
233
|
@rules.each do |rule|
|
233
234
|
delete |= rule.criteria.match(combo_hash)
|
@@ -236,60 +237,36 @@ module CLabs::CaseGen
|
|
236
237
|
end
|
237
238
|
return @combinations
|
238
239
|
end
|
239
|
-
return []
|
240
|
+
return []
|
240
241
|
end
|
241
|
-
|
242
|
+
|
242
243
|
def titles
|
243
244
|
@agents[0].titles
|
244
245
|
end
|
245
|
-
|
246
|
+
|
246
247
|
def to_s
|
247
248
|
puts @agents[0].combinations.inspect if !@agents[0].nil?
|
248
249
|
puts
|
249
250
|
puts @rules.inspect
|
250
251
|
end
|
251
252
|
end
|
252
|
-
|
253
|
+
|
253
254
|
class ConsoleOutput < Agent
|
254
255
|
def ConsoleOutput.agent_id
|
255
256
|
"casegen:console"
|
256
257
|
end
|
257
|
-
|
258
|
-
def initialize(data, reference_agents)
|
258
|
+
|
259
|
+
def initialize(data, reference_agents, io=STDOUT)
|
259
260
|
@data = data
|
260
261
|
@agents = reference_agents
|
261
|
-
table =
|
262
|
-
table.
|
263
|
-
|
264
|
-
end
|
265
|
-
puts
|
262
|
+
table = [@agents[0].titles] + @agents[0].combinations
|
263
|
+
io.puts table.to_table.pretty_inspect
|
264
|
+
io.puts
|
266
265
|
@agents[0].each do |rule|
|
267
|
-
puts rule.data
|
268
|
-
puts
|
266
|
+
io.puts rule.data
|
267
|
+
io.puts
|
269
268
|
end if @agents[0].is_a?(Rules)
|
270
269
|
end
|
271
|
-
|
272
|
-
def formatted_table(combinations)
|
273
|
-
col_widths = []
|
274
|
-
formatted_tuples = []
|
275
|
-
combinations.each do |tuple|
|
276
|
-
col = 0
|
277
|
-
tuple.each do |item|
|
278
|
-
col_widths[col] = item.to_s.length if col_widths[col].to_i < item.to_s.length
|
279
|
-
col += 1
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
combinations.each do |tuple|
|
284
|
-
col = 0
|
285
|
-
formatted_tuples << tuple.collect { |item|
|
286
|
-
formatted = item.to_s.ljust(col_widths[col]) if !col_widths[col].nil?
|
287
|
-
col += 1
|
288
|
-
formatted
|
289
|
-
}
|
290
|
-
end
|
291
|
-
formatted_tuples
|
292
|
-
end
|
293
270
|
end
|
294
271
|
|
295
272
|
class RubyArrayOutput < Agent
|