casegen 1.3.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.
@@ -0,0 +1,13 @@
1
+ sets
2
+ ----
3
+ first number: 0, 1
4
+ operator: +, -, *, /
5
+ second number: 0, 1
6
+
7
+ rules(sets)
8
+ -----------
9
+ exclude operator = / AND second number = 0
10
+ Divide by zero error
11
+
12
+ console(rules)
13
+ --------------
@@ -0,0 +1,33 @@
1
+ sets
2
+ ------------
3
+ payment: Credit, Check, Online Bank
4
+ amount: 100, 1,000, 10,000
5
+ shipping: Ground, Air
6
+ ship to country: US, Outside US
7
+ bill to country: US, Outside US
8
+
9
+
10
+ rules(sets)
11
+ ---------------------------
12
+ # Comments supported
13
+ exclude shipping = Ground AND ship to country = Outside US
14
+ Our ground shipper will only ship things within the US.
15
+
16
+ # Single or double equals sign supported - they're synonymous
17
+ exclude payment = Check AND bill to country == Outside US
18
+ Our bank will not accept checks written from banks outside the US.
19
+
20
+ #[Complex booleans not supported yet]
21
+ #exclude payment = Online Bank AND (amount == 1,000 OR amount = 10,000)
22
+ exclude payment = Online Bank AND amount == 1,000
23
+ exclude payment = Online Bank AND amount == 10,000
24
+ While the online bank will process amounts > $1,000, we've experienced
25
+ occasional problems with their services and have had to write off some
26
+ transactions, so we no longer allow this payment option for amounts greater
27
+ than $1,000
28
+
29
+ exclude ship to country = US AND bill to country = Outside US
30
+ If we're shipping to the US, billing party cannot be outside US
31
+
32
+ console(rules)
33
+ ----------
data/src/casegen.rb ADDED
@@ -0,0 +1,191 @@
1
+ require 'singleton'
2
+
3
+ class Fixnum
4
+ def even?
5
+ self.divmod(2)[1] == 0
6
+ end
7
+ end
8
+
9
+ class String
10
+ def outdent
11
+ a = $1 if match(/\A(\s*)(.*\n)(?:\1.*\n|\n)*\z/)
12
+ gsub(/^#{a}/, '')
13
+ end
14
+ end
15
+
16
+ module CLabs
17
+ module CaseGen
18
+ class AgentException < Exception
19
+ end
20
+
21
+ class Agent # base class
22
+ attr_reader :data, :reference_agents
23
+
24
+ def initialize(data, agents)
25
+ @data = data
26
+ @reference_agents = agents
27
+ end
28
+ end
29
+
30
+ class Agents
31
+ include Singleton
32
+
33
+ def initialize
34
+ clear
35
+ end
36
+
37
+ def register(agent)
38
+ if agent.class == Class && agent.ancestors.include?(Agent)
39
+ @agents << agent
40
+ else
41
+ raise AgentException.new("To register an agent, you must pass in a Class instance that's a subclass of Agent")
42
+ end
43
+ end
44
+
45
+ def method_missing(methid, *args, &block)
46
+ @agents.send(methid, *args, &block)
47
+ end
48
+
49
+ def get_agent_by_id(id)
50
+ @agents.each do |agent|
51
+ return agent if agent.agent_id =~ /#{id}/i
52
+ end
53
+ # rather than return nil and allow the client to get bumfuzzled if
54
+ # they forget to check for nil, let's blow up and tell them how to
55
+ # not let it happen again
56
+ raise AgentException.new("Requested an agent that does not exist. You can query for existance with .id_registered?")
57
+ end
58
+
59
+ def id_registered?(id)
60
+ begin
61
+ get_agent_by_id(id)
62
+ return true
63
+ rescue AgentException
64
+ return false
65
+ end
66
+ end
67
+
68
+ # removes all registered agents
69
+ def clear
70
+ @agents = []
71
+ end
72
+ end
73
+
74
+ class ParserException < Exception
75
+ end
76
+
77
+ class Parser
78
+ attr_reader :agents
79
+
80
+ def initialize(data)
81
+ @data = data
82
+ @agents = []
83
+ parse
84
+ end
85
+
86
+ def parse
87
+ lines = @data.split(/\n/)
88
+ while !lines.empty?
89
+ line = lines.shift
90
+ next if line.strip.empty?
91
+
92
+ data = nil
93
+ agent_class, reference_agents = parse_agent(line)
94
+
95
+ next_line = lines.shift
96
+ if next_line =~ /^-+/
97
+ data = parse_data(lines).join("\n")
98
+ else
99
+ raise ParserException.new("Expected hyphen line after the agent declaration for <#{agent_class}>")
100
+ end
101
+
102
+ @agents << agent_class.new(data, reference_agents)
103
+ end
104
+ end
105
+
106
+ def parse_data(lines)
107
+ end_index = -1
108
+ lines.each_with_index do |line, index|
109
+ if line =~ /^-+/
110
+ end_index = index - 2
111
+ return lines.slice!(0, end_index)
112
+ end
113
+ end
114
+ return lines.slice!(0, lines.length)
115
+ end
116
+
117
+ def parse_agent(line)
118
+ agent_name, *reference_agent_names = line.split(/(?=\()/)
119
+ raise ParserException.new("Nested agents ( e.g. a(b(c)) ) not supported yet") if reference_agent_names.length > 1
120
+ if reference_agent_names.length > 0
121
+ reference_agent_names = reference_agent_names[0].gsub(/\(|\)/, '').split(/,/)
122
+ reference_agent_names.collect! do |name|
123
+ name.strip
124
+ end
125
+ else
126
+ reference_agent_names = []
127
+ end
128
+
129
+ [agent_name, reference_agent_names].flatten.each do |a_name|
130
+ raise ParserException.new("Unregistered agent <#{a_name}> in agent name data <#{line}>") if !Agents.instance.id_registered?(a_name)
131
+ end
132
+
133
+ reference_agents = []
134
+ reference_agent_names.each do |ref_name|
135
+ @agents.each do |agent|
136
+ reference_agents << agent if agent.class.agent_id =~ /#{ref_name}/i
137
+ end
138
+ end
139
+ agent_class = Agents.instance.get_agent_by_id(agent_name)
140
+ [agent_class, reference_agents]
141
+ end
142
+ end
143
+
144
+ class CaseGen
145
+ def CaseGen.version
146
+ '1.3.0'
147
+ end
148
+
149
+ def initialize(data)
150
+ load_agents
151
+ Parser.new(data)
152
+ end
153
+
154
+ def load_agents
155
+ agent_dir = "#{File.dirname(__FILE__)}/agents"
156
+ agent_fns = Dir[File.join(agent_dir, '*.rb')]
157
+ agent_fns.each do |fn|
158
+ require fn
159
+ end
160
+ ObjectSpace.each_object(Class) do |klass|
161
+ if klass.ancestors.include?(Agent) && (klass != Agent)
162
+ Agents.instance.register(klass)
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ class Console
169
+ def initialize
170
+ put_banner
171
+
172
+ if ARGV[0].nil? || !File.exists?(ARGV[0])
173
+ puts "Case file required: #{File.basename($0)} [case filename]. For example:"
174
+ puts " #{File.basename($0)} cases.txt"
175
+ puts
176
+ exit
177
+ end
178
+
179
+ CaseGen.new(File.read(ARGV[0]))
180
+ end
181
+
182
+ def put_banner
183
+ $stderr.puts "cLabs Casegen #{CaseGen.version}"
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ if __FILE__ == $0
190
+ CLabs::CaseGen::Console.new
191
+ end
@@ -0,0 +1,20 @@
1
+ sets
2
+ ----
3
+ role: admin, standard
4
+ authorization code: none, invalid, valid
5
+ submit enabled: true, false
6
+
7
+ rules(sets)
8
+ -----------
9
+ exclude role = admin AND submit enabled = false
10
+ Admin role can always submit
11
+
12
+ exclude role = standard AND authorization code = none AND submit enabled = true
13
+ exclude role = standard AND authorization code = invalid AND submit enabled = true
14
+ exclude role = standard AND authorization code = valid AND submit enabled = false
15
+ Standard role can only submit when authorization code is valid
16
+
17
+
18
+ ruby_array(rules)
19
+ -------------
20
+ DataSubmitCase
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: casegen
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - chrismo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: chrismo@clabs.org
16
+ executables:
17
+ - casegen
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - src/agents/sets/enum/by.rb
22
+ - src/agents/sets/enum/cluster.rb
23
+ - src/agents/sets/enum/inject.rb
24
+ - src/agents/sets/enum/install.rb
25
+ - src/agents/sets/enum/nest.rb
26
+ - src/agents/sets/enum/op.rb
27
+ - src/agents/sets/enum/pipe.rb
28
+ - src/agents/sets/enum/tree.rb
29
+ - src/agents/sets.rb
30
+ - src/calc.sample.txt
31
+ - src/cart.sample.txt
32
+ - src/casegen.rb
33
+ - src/ruby_array.sample.txt
34
+ - bin/casegen
35
+ homepage: https://github.com/chrismo/casegen
36
+ licenses:
37
+ - BSD
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - src
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ segments:
49
+ - 0
50
+ hash: -3949454406001861969
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ segments:
58
+ - 0
59
+ hash: -3949454406001861969
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.23
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Simple Ruby DSL to generate use cases restricted by sets of rules
66
+ test_files: []