casegen 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []