casegen 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
File without changes
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ ---Enumerable#inject
5
+ ---Enumerable#sum [block]
6
+
7
+ Code adapted from Pickaxe book, p.102.
8
+ See source file for examples.
9
+
10
+ ==version
11
+
12
+ Enumerable tools 1.6
13
+
14
+ =end
15
+
16
+ # module Enumerable
17
+ #
18
+ # def inject n
19
+ # each { |i|
20
+ # n = yield n, i
21
+ # }
22
+ # n
23
+ # end
24
+ # alias :accumulate :inject
25
+ #
26
+ # def sum
27
+ # if block_given?
28
+ # inject(0) { |n, i| n + yield(i) }
29
+ # else
30
+ # inject(0) { |n, i| n + i }
31
+ # end
32
+ # end
33
+ #
34
+ # def product
35
+ # if block_given?
36
+ # inject(1) { |n, i| n * yield(i) }
37
+ # else
38
+ # inject(1) { |n, i| n * i }
39
+ # end
40
+ # end
41
+ #
42
+ # end
43
+
44
+ if __FILE__ == $0
45
+
46
+ x = (0..9).collect { |i| [i, i*i] }
47
+ p x
48
+ p x.sum { |v| v[1] }
49
+
50
+ end
File without changes
File without changes
File without changes
File without changes
@@ -1,11 +1,5 @@
1
1
  require 'singleton'
2
2
 
3
- class Fixnum
4
- def even?
5
- self.divmod(2)[1] == 0
6
- end
7
- end
8
-
9
3
  class String
10
4
  def outdent
11
5
  a = $1 if match(/\A(\s*)(.*\n)(?:\1.*\n|\n)*\z/)
@@ -143,7 +137,7 @@ module CLabs
143
137
 
144
138
  class CaseGen
145
139
  def CaseGen.version
146
- '1.3.0'
140
+ '2.0.0'
147
141
  end
148
142
 
149
143
  def initialize(data)
@@ -0,0 +1,27 @@
1
+ require_relative '../test_helper'
2
+ require_relative '../../lib/agents/sets.rb'
3
+
4
+ FakeAgent = Struct.new(:titles, :combinations)
5
+
6
+ include CLabs::CaseGen
7
+
8
+ class TestConsoleOutput < Minitest::Test
9
+ def test_simple_output
10
+ data = nil
11
+ agents = [
12
+ FakeAgent.new(["col a", "col b"], [[1, 2], [3, 4]])
13
+ ]
14
+ sio = StringIO.new
15
+ ConsoleOutput.new(data, agents, sio)
16
+ expected = <<~_
17
+ +-------+-------+
18
+ | col a | col b |
19
+ +-------+-------+
20
+ | 1 | 2 |
21
+ | 3 | 4 |
22
+ +-------+-------+
23
+
24
+ _
25
+ assert_equal expected, sio.string
26
+ end
27
+ end
@@ -0,0 +1,227 @@
1
+ $LOAD_PATH << "#{__dir__}/../../lib/agents"
2
+ require 'minitest/autorun'
3
+ require 'sets'
4
+
5
+ include CLabs::CaseGen
6
+
7
+ class TestParsing < Minitest::Test
8
+ def test_sets_default
9
+ data = <<~CASEDATA
10
+ bar: 1, 2, 3,456.98
11
+ foo list:a, b, c
12
+ CASEDATA
13
+ cases = Sets.new(data)
14
+ assert_equal(2, cases.sets.length)
15
+
16
+ assert_equal("bar", cases.sets[0].name)
17
+ assert_equal(["1", "2", "3,456.98"], cases.sets[0].data)
18
+
19
+ assert_equal("foo list", cases.sets[1].name)
20
+ assert_equal(["a", "b", "c"], cases.sets[1].data)
21
+ end
22
+
23
+ def test_set_by_name_matching
24
+ # may seem obvious, but the regex matching used at one point would get confused when a name was reused in sets
25
+ sets = Sets.new("foo bar: 1, 2\nbar quux: 3, 4")
26
+ set = sets.set_by_name('bar quux')
27
+ assert_equal 'bar quux', set.name
28
+ end
29
+ end
30
+
31
+ class TestCombinations < Minitest::Test
32
+ def test_combos_2_by_2
33
+ sets = Sets.new("a: 1, 2\nb:3, 4")
34
+ assert_equal([['1', '3'], ['1', '4'], ['2', '3'], ['2', '4']], sets.combinations)
35
+ assert_equal(['a', 'b'], sets.titles)
36
+ end
37
+
38
+ def test_combos_2_by_3
39
+ sets = Sets.new("a: 1, 2\nb:3, 4, 5")
40
+ assert_equal([['1', '3'], ['1', '4'], ['1', '5'],
41
+ ['2', '3'], ['2', '4'], ['2', '5']], sets.combinations)
42
+ assert_equal(['a', 'b'], sets.titles)
43
+ end
44
+ end
45
+
46
+ class TestRulesParsing < Minitest::Test
47
+ def test_rules_single
48
+ data = <<~RULES
49
+ exclude foo = bar
50
+ RULES
51
+ rules = Rules.new(data)
52
+ assert_equal(1, rules.length)
53
+ assert_equal(ExcludeRule, rules[0].class)
54
+ assert_equal("foo = bar", rules[0].criteria.to_s)
55
+ assert_equal("", rules[0].description)
56
+ end
57
+
58
+ def test_rules_two
59
+ data = <<~RULES
60
+ exclude foo = bar
61
+ should foo equal bar, we want to exclude that combination
62
+
63
+ exclude bar = foo
64
+ as well, if bar equals foo,
65
+ that case has got to go
66
+ RULES
67
+ rules = Rules.new(data)
68
+ assert_equal(2, rules.length)
69
+ assert_equal(ExcludeRule, rules[0].class)
70
+ assert_equal("foo = bar", rules[0].criteria.to_s)
71
+ assert_equal("should foo equal bar, we want to exclude that combination", rules[0].description)
72
+
73
+ assert_equal(ExcludeRule, rules[1].class)
74
+ assert_equal("bar = foo", rules[1].criteria.to_s)
75
+ assert_equal("as well, if bar equals foo,\nthat case has got to go", rules[1].description)
76
+ end
77
+
78
+ def test_exclude_rule_parsing
79
+ data = <<~RULES
80
+ exclude foo = bar
81
+ should foo equal bar, we want to exclude that combination
82
+ RULES
83
+ rule = ExcludeRule.new(data)
84
+ assert_equal("foo = bar", rule.criteria.to_s)
85
+ assert_equal(["foo"], rule.criteria.set_names)
86
+ assert_equal(["bar"], rule.criteria.set_values)
87
+ assert_equal("should foo equal bar, we want to exclude that combination", rule.description)
88
+
89
+ end
90
+
91
+ def test_rules_set_name_not_found
92
+ sets = Sets.new("set.a: foo, bar\nset.b: fu, bahr")
93
+ data = <<~RULES
94
+ exclude set_a = bar AND set_b = barh
95
+ should foo equal bar, we want to exclude that combination
96
+ RULES
97
+ begin
98
+ Rules.new(data, [sets])
99
+ fail('should throw')
100
+ rescue ParserException => e
101
+ assert_equal("Invalid set name <set_a> in rule <set_a = bar AND set_b = barh>. Valid set names are <set.a, set.b>.", e.message)
102
+ end
103
+ end
104
+
105
+ def test_rules_set_value_not_found
106
+ sets = Sets.new("set a: foo, bar\nset b: fu, bahr")
107
+ data = <<~RULES
108
+ exclude set a = bar AND set b = barh
109
+ should foo equal bar, we want to exclude that combination
110
+ RULES
111
+ begin
112
+ Rules.new(data, [sets])
113
+ fail('should throw')
114
+ rescue ParserException => e
115
+ assert_equal("Invalid set value <barh> in rule <set a = bar AND set b = barh>. Valid set values for <set b> are <fu, bahr>.", e.message)
116
+ end
117
+ end
118
+
119
+ class TestCriteria < Minitest::Test
120
+ def test_simple_equality
121
+ crit = Criteria.new("a = b")
122
+ assert_equal(['a'], crit.set_names)
123
+ assert_equal(['b'], crit.set_values)
124
+ assert_equal(true, crit.match({'a' => 'b'}))
125
+ assert_equal(false, crit.match({'a' => 'c'}))
126
+ assert_equal(false, crit.match({'b' => 'a'}))
127
+ assert_equal(true, crit.match({'a' => 'b', 'f' => 'g'}))
128
+ end
129
+
130
+ def test_boolean_and
131
+ crit = Criteria.new("a = b AND c == d")
132
+ assert_equal(['a', 'c'], crit.set_names)
133
+ assert_equal(['b', 'd'], crit.set_values)
134
+ assert_equal(true, crit.match({'a' => 'b', 'c' => 'd'}))
135
+ assert_equal(false, crit.match({'a' => 'd', 'c' => 'b'}))
136
+ assert_equal(true, crit.match({'c' => 'd', 'a' => 'b'}))
137
+ assert_equal(false, crit.match({'a' => 'b'}))
138
+ assert_equal(false, crit.match({'c' => 'd'}))
139
+ assert_equal(false, crit.match({'a' => 'b', 'd' => 'c'}))
140
+ assert_equal(false, crit.match({'c' => 'd', 'b' => 'a'}))
141
+
142
+ # not case sensitive
143
+ assert_equal(false, crit.match({'A' => 'b', 'c' => 'd'}))
144
+ assert_equal(false, crit.match({'a' => 'B', 'c' => 'd'}))
145
+ assert_equal(false, crit.match({'a' => 'b', 'C' => 'd'}))
146
+ assert_equal(false, crit.match({'a' => 'b', 'c' => 'D'}))
147
+ end
148
+
149
+ def test_invalid_boolean_and
150
+ begin
151
+ Criteria.new("a = b AND a = d")
152
+ fail("should throw")
153
+ rescue ParserException => e
154
+ assert_equal("Rule cannot have the same set <a> equal to different values <b, d>", e.message)
155
+ end
156
+
157
+ begin
158
+ Criteria.new("a = b AND a = d AND a = c")
159
+ fail("should throw")
160
+ rescue ParserException => e
161
+ # in this case, the exception is figured out before the a = c can be parsed
162
+ assert_equal("Rule cannot have the same set <a> equal to different values <b, d>", e.message)
163
+ end
164
+ end
165
+ end
166
+
167
+ class TestRulesOnSets < Minitest::Test
168
+ def test_simple
169
+ sets = Sets.new("a: 1, 2\nb: 3, 4")
170
+ rules = Rules.new("exclude a = 1\nexclude b=4", [sets])
171
+ assert_equal([['2', '3']], rules.combinations)
172
+ assert_equal(['a', 'b'], rules.titles)
173
+ end
174
+ end
175
+
176
+ class TestRubyCaseArray < Minitest::Test
177
+ def test_default_case_name
178
+ sets = Sets.new("a: 1, 2\nb:3, 4")
179
+ out = MockStdOut.new
180
+ RubyArrayOutput.new("", [sets], out)
181
+ expected = <<~TEXT
182
+ Case = Struct.new(:a, :b)
183
+
184
+ cases = [Case.new("1", "3"),
185
+ Case.new("1", "4"),
186
+ Case.new("2", "3"),
187
+ Case.new("2", "4")]
188
+ TEXT
189
+ assert_equal(expected, out.to_s)
190
+ end
191
+
192
+ def test_specified_case_name
193
+ sets = Sets.new("a: 1, 2\nb:3, 4")
194
+ out = MockStdOut.new
195
+ RubyArrayOutput.new("DataSubmitCase", [sets], out)
196
+ expected = <<~TEXT
197
+ DataSubmitCase = Struct.new(:a, :b)
198
+
199
+ cases = [DataSubmitCase.new("1", "3"),
200
+ DataSubmitCase.new("1", "4"),
201
+ DataSubmitCase.new("2", "3"),
202
+ DataSubmitCase.new("2", "4")]
203
+ TEXT
204
+ assert_equal(expected, out.to_s)
205
+ end
206
+ end
207
+
208
+ class MockStdOut
209
+ def initialize
210
+ @s = ''
211
+ end
212
+
213
+ def puts(s)
214
+ @s << s << "\n"
215
+ end
216
+
217
+ def print(s)
218
+ @s << s
219
+ end
220
+
221
+ def to_s
222
+ @s
223
+ end
224
+ end
225
+ end
226
+
227
+
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH << "#{__dir__}/../lib"
2
+ require 'minitest/autorun'
3
+ require 'casegen'
4
+
5
+ include CLabs::CaseGen
6
+
7
+ class TestAgents < Minitest::Test
8
+ def setup
9
+ Agents.instance.clear
10
+ end
11
+
12
+ def teardown
13
+ Agents.instance.clear
14
+ end
15
+
16
+ def test_register
17
+ assert_equal(0, Agents.instance.length)
18
+ begin
19
+ Agents.instance.register("phil")
20
+ fail("should have thrown")
21
+ rescue AgentException
22
+ # expected -- can't register a non subclass
23
+ end
24
+
25
+ Agents.instance.register(SampleAgent)
26
+ assert_equal(1, Agents.instance.length)
27
+ Agents.instance.each do |ag| assert_equal(SampleAgent, ag) end
28
+ end
29
+
30
+ def test_get_agent_by_id
31
+ Agents.instance.register(SampleAgent)
32
+ result = Agents.instance.get_agent_by_id("sample")
33
+ assert_equal(SampleAgent, result)
34
+ end
35
+
36
+ def test_id_registered
37
+ assert_equal(false, Agents.instance.id_registered?(SampleAgent.agent_id))
38
+ Agents.instance.register(SampleAgent)
39
+ assert_equal(true, Agents.instance.id_registered?(SampleAgent.agent_id))
40
+ end
41
+ end
File without changes
@@ -0,0 +1,163 @@
1
+ $LOAD_PATH << "#{__dir__}/../lib"
2
+ require 'minitest/autorun'
3
+ require 'casegen'
4
+
5
+ include CLabs::CaseGen
6
+
7
+ class SampleAgent < Agent
8
+ def SampleAgent.agent_id
9
+ "sample"
10
+ end
11
+ end
12
+
13
+ class Foo < Agent
14
+ def Foo.agent_id
15
+ "foo"
16
+ end
17
+ end
18
+
19
+ class TestParser < Minitest::Test
20
+ def setup
21
+ Agents.instance.register(SampleAgent)
22
+ Agents.instance.register(Foo)
23
+ end
24
+
25
+ def test_parse
26
+ data = <<~CASEDATA
27
+ sample
28
+ ------
29
+ sample_data
30
+
31
+ foo
32
+ ---
33
+ sample_data
34
+
35
+ sample(foo, sample)
36
+ ------------
37
+ sample_data
38
+ plus
39
+ some extra
40
+ CASEDATA
41
+
42
+ parser = Parser.new(data)
43
+ assert_equal(3, parser.agents.length)
44
+
45
+ sample_a = parser.agents[0]
46
+ foo = parser.agents[1]
47
+ sample_b = parser.agents[2]
48
+ assert_equal(SampleAgent, sample_a.class)
49
+ assert_equal("sample_data", sample_a.data)
50
+ assert_equal([], sample_a.reference_agents)
51
+
52
+ assert_equal(Foo, foo.class)
53
+ assert_equal("sample_data", foo.data)
54
+ assert_equal([], foo.reference_agents)
55
+
56
+ assert_equal(SampleAgent, sample_b.class)
57
+ assert_equal("sample_data\nplus\n some extra", sample_b.data)
58
+ assert_equal([foo, sample_a], sample_b.reference_agents)
59
+ end
60
+
61
+ def test_parse_no_sets
62
+ data = <<~CASEDATA
63
+ CASEDATA
64
+
65
+ parser = Parser.new(data)
66
+ assert_equal(0, parser.agents.length)
67
+ end
68
+
69
+ def test_parse_agent_with_missing_hyphen_line
70
+ data = <<~CASEDATA
71
+ sample
72
+
73
+ sample_data
74
+ CASEDATA
75
+
76
+ Parser.new(data)
77
+ fail("should have thrown")
78
+ rescue ParserException => e
79
+ assert_equal("Expected hyphen line after the agent declaration for <SampleAgent>", e.message)
80
+ end
81
+
82
+ def test_parse_agent_name_without_dash_delimiter
83
+ data = <<~CASEDATA
84
+ sample
85
+ CASEDATA
86
+
87
+ Parser.new(data)
88
+ fail("should have thrown")
89
+ rescue ParserException => e
90
+ assert_equal("Expected hyphen line after the agent declaration for <SampleAgent>", e.message)
91
+ end
92
+
93
+ def test_parse_agent_name_without_dash_delimiter_and_empty_line_to_start
94
+ data = <<~CASEDATA
95
+
96
+ sample
97
+ CASEDATA
98
+
99
+ Parser.new(data)
100
+ fail("should have thrown")
101
+ rescue ParserException => e
102
+ assert_equal("Expected hyphen line after the agent declaration for <SampleAgent>", e.message)
103
+ end
104
+
105
+ def test_parse_just_agent_with_underline
106
+ data = <<~CASEDATA
107
+ sample
108
+ -
109
+ CASEDATA
110
+
111
+ parser = Parser.new(data)
112
+ assert_equal(1, parser.agents.length)
113
+ sample = parser.agents[0]
114
+ assert_equal(SampleAgent, sample.class)
115
+ assert_equal("", sample.data)
116
+ assert_equal([], sample.reference_agents)
117
+ end
118
+
119
+ def test_parse_just_agent_with_empty_data
120
+ data = <<~CASEDATA
121
+ sample
122
+ -
123
+
124
+ CASEDATA
125
+
126
+ parser = Parser.new(data)
127
+ assert_equal(1, parser.agents.length)
128
+ sample = parser.agents[0]
129
+ assert_equal(SampleAgent, sample.class)
130
+ assert_equal("", sample.data)
131
+ assert_equal([], sample.reference_agents)
132
+ end
133
+
134
+ def test_parse_invalid_agent
135
+ data = <<~CASEDATA
136
+ sermple
137
+ ------
138
+ sample_data
139
+ CASEDATA
140
+
141
+ begin
142
+ Parser.new(data)
143
+ fail("should throw")
144
+ rescue ParserException
145
+ # expected
146
+ end
147
+ end
148
+
149
+ def test_parse_invalid_referenced_agent
150
+ data = <<~CASEDATA
151
+ sample(fu)
152
+ ------
153
+ sample_data
154
+ CASEDATA
155
+
156
+ begin
157
+ Parser.new(data)
158
+ fail("should throw")
159
+ rescue ParserException
160
+ # expected
161
+ end
162
+ end
163
+ end