atp 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/version.rb +2 -2
- data/lib/atp.rb +3 -3
- data/lib/atp/ast/builder.rb +20 -24
- data/lib/atp/ast/node.rb +3 -12
- data/lib/atp/flow.rb +101 -5
- data/lib/atp/formatters/basic.rb +1 -1
- data/lib/atp/formatters/datalog.rb +45 -5
- data/lib/atp/processors/add_ids.rb +23 -0
- data/lib/atp/processors/condition.rb +2 -2
- data/lib/atp/processors/condition_extractor.rb +1 -1
- data/lib/atp/processors/marshal.rb +14 -0
- data/lib/atp/program.rb +16 -0
- data/lib/atp/runner.rb +106 -4
- data/lib/atp/validator.rb +11 -1
- data/lib/atp/validators/jobs.rb +53 -0
- metadata +5 -5
- data/lib/atp/and.rb +0 -11
- data/lib/atp/not.rb +0 -13
- data/lib/atp/or.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cdbd30f66efb6b3795073de37ccdf0623377b7b
|
4
|
+
data.tar.gz: 4b3deec7a4e80eaa56dfd1b14934790a044ab611
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5309d2a1ddef3772ae949e47d3ce750a3eee0236498741cc0d752e3a7973fca9a016186ff17c02d54095055af51676b03eb2af8d6a23ebf695d7273096b5a406
|
7
|
+
data.tar.gz: b391e87fa09e223a717b6f11842ca2af604b33849ade223a657f8acaa5202dc90153070a89c4117b6a99fdb8e36bfa2dbef633b22957032c274aba6332eeffae
|
data/config/version.rb
CHANGED
data/lib/atp.rb
CHANGED
@@ -9,9 +9,6 @@ module ATP
|
|
9
9
|
autoload :Runner, 'atp/runner'
|
10
10
|
autoload :Formatter, 'atp/formatter'
|
11
11
|
autoload :Parser, 'atp/parser'
|
12
|
-
autoload :AND, 'atp/and'
|
13
|
-
autoload :OR, 'atp/or'
|
14
|
-
autoload :NOT, 'atp/not'
|
15
12
|
|
16
13
|
module AST
|
17
14
|
autoload :Node, 'atp/ast/node'
|
@@ -28,6 +25,8 @@ module ATP
|
|
28
25
|
autoload :Relationship, 'atp/processors/relationship'
|
29
26
|
autoload :PreCleaner, 'atp/processors/pre_cleaner'
|
30
27
|
autoload :PostCleaner, 'atp/processors/post_cleaner'
|
28
|
+
autoload :Marshal, 'atp/processors/marshal'
|
29
|
+
autoload :AddIDs, 'atp/processors/add_ids'
|
31
30
|
end
|
32
31
|
|
33
32
|
# Summarizers extract summary data from the given AST
|
@@ -40,6 +39,7 @@ module ATP
|
|
40
39
|
autoload :DuplicateIDs, 'atp/validators/duplicate_ids'
|
41
40
|
autoload :MissingIDs, 'atp/validators/missing_ids'
|
42
41
|
autoload :Condition, 'atp/validators/condition'
|
42
|
+
autoload :Jobs, 'atp/validators/jobs'
|
43
43
|
end
|
44
44
|
|
45
45
|
# Formatters are run on the processed AST to display the flow or to render
|
data/lib/atp/ast/builder.rb
CHANGED
@@ -47,6 +47,10 @@ module ATP
|
|
47
47
|
n(:test_executed, id, executed, node)
|
48
48
|
end
|
49
49
|
|
50
|
+
def job(id, enabled, node)
|
51
|
+
n(:job, id, enabled, node)
|
52
|
+
end
|
53
|
+
|
50
54
|
def enable_flow_flag(var, options = {})
|
51
55
|
test = n(:enable_flow_flag, var)
|
52
56
|
if options[:conditions]
|
@@ -93,7 +97,7 @@ module ATP
|
|
93
97
|
end
|
94
98
|
|
95
99
|
def new_context
|
96
|
-
@context = { conditions:
|
100
|
+
@context = { conditions: [] }
|
97
101
|
yield if block_given?
|
98
102
|
@context
|
99
103
|
end
|
@@ -115,8 +119,20 @@ module ATP
|
|
115
119
|
|
116
120
|
def apply_conditions(node, conditions)
|
117
121
|
conditions.each do |key, value|
|
122
|
+
# Sometimes conditions can be an array (in the case of the current context
|
123
|
+
# being re-used), so rectify that now
|
124
|
+
if key.is_a?(Hash)
|
125
|
+
fail 'Something has gone wrong applying the test conditions' if key.size > 1
|
126
|
+
key, value = key.first[0], key.first[1]
|
127
|
+
end
|
118
128
|
key = key.to_s.downcase.to_sym
|
119
|
-
|
129
|
+
# Represent all condition values as lower cased strings internally
|
130
|
+
if value.is_a?(Array)
|
131
|
+
value = value.map { |v| v.to_s.downcase }
|
132
|
+
else
|
133
|
+
value = value.to_s.downcase
|
134
|
+
end
|
135
|
+
context[:conditions] << { key => value }
|
120
136
|
case key
|
121
137
|
when :if_enabled, :enabled, :enable_flag, :enable, :if_enable
|
122
138
|
node = flow_flag(value, true, node)
|
@@ -149,17 +165,9 @@ module ATP
|
|
149
165
|
when :unless_ran, :unless_executed
|
150
166
|
node = test_executed(value, false, node)
|
151
167
|
when :job, :jobs, :if_job, :if_jobs
|
152
|
-
|
153
|
-
unless value.is_a?(OR)
|
154
|
-
value = ATP.or(value)
|
155
|
-
end
|
156
|
-
node = n(:job, apply_boolean(value), node)
|
168
|
+
node = job(value, true, node)
|
157
169
|
when :unless_job, :unless_jobs
|
158
|
-
|
159
|
-
unless value.is_a?(OR)
|
160
|
-
value = ATP.or(value)
|
161
|
-
end
|
162
|
-
node = n(:job, apply_boolean(ATP.not(value)), node)
|
170
|
+
node = job(value, false, node)
|
163
171
|
else
|
164
172
|
fail "Unknown test condition attribute - #{key} (#{value})"
|
165
173
|
end
|
@@ -167,18 +175,6 @@ module ATP
|
|
167
175
|
node
|
168
176
|
end
|
169
177
|
|
170
|
-
def apply_boolean(value)
|
171
|
-
if value.is_a?(OR)
|
172
|
-
n(:or, *value.map { |v| apply_boolean(v) })
|
173
|
-
elsif value.is_a?(AND)
|
174
|
-
n(:and, *value.map { |v| apply_boolean(v) })
|
175
|
-
elsif value.is_a?(NOT)
|
176
|
-
n(:not, apply_boolean(value.value))
|
177
|
-
else
|
178
|
-
value
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
178
|
def test(object, options = {})
|
183
179
|
children = [n(:object, object)]
|
184
180
|
|
data/lib/atp/ast/node.rb
CHANGED
@@ -4,7 +4,7 @@ module ATP
|
|
4
4
|
class Node < ::AST::Node
|
5
5
|
include Factories
|
6
6
|
|
7
|
-
attr_reader :file, :line_number
|
7
|
+
attr_reader :file, :line_number, :description
|
8
8
|
|
9
9
|
def initialize(type, children = [], properties = {})
|
10
10
|
# Always use strings instead of symbols in the AST, makes serializing
|
@@ -60,21 +60,12 @@ module ATP
|
|
60
60
|
|
61
61
|
# Returns the first child node of the given type that is found
|
62
62
|
def find(type)
|
63
|
-
|
64
|
-
nodes.first
|
63
|
+
children.find { |c| c.try(:type) == type }
|
65
64
|
end
|
66
65
|
|
67
66
|
# Returns an array containing all child nodes of the given type(s)
|
68
67
|
def find_all(*types)
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
def to_h
|
73
|
-
h = {}
|
74
|
-
children.each do |node|
|
75
|
-
h[node.type] = node.children.map { |n| n.is_a?(AST::Node) ? n.to_h : n }
|
76
|
-
end
|
77
|
-
h
|
68
|
+
children.select { |c| types.include?(c.try(:type)) }
|
78
69
|
end
|
79
70
|
end
|
80
71
|
end
|
data/lib/atp/flow.rb
CHANGED
@@ -9,10 +9,19 @@ module ATP
|
|
9
9
|
def initialize(program, name = nil)
|
10
10
|
@program = program
|
11
11
|
@name = name
|
12
|
-
@builder = AST::Builder.new
|
13
12
|
@raw = builder.flow
|
14
13
|
end
|
15
14
|
|
15
|
+
# @api private
|
16
|
+
def marshal_dump
|
17
|
+
[@name, @program, Processors::Marshal.new.process(@raw)]
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def marshal_load(array)
|
22
|
+
@name, @program, @raw = array
|
23
|
+
end
|
24
|
+
|
16
25
|
# Returns a processed/optimized AST, this is the one that should be
|
17
26
|
# used to build and represent the given test flow
|
18
27
|
def ast
|
@@ -22,6 +31,8 @@ module ATP
|
|
22
31
|
ast = Processors::Condition.new.process(ast)
|
23
32
|
ast = Processors::Relationship.new.process(ast)
|
24
33
|
ast = Processors::PostCleaner.new.process(ast)
|
34
|
+
Validators::Jobs.new(self).process(ast)
|
35
|
+
ast
|
25
36
|
end
|
26
37
|
|
27
38
|
# Group all tests generated within the given block
|
@@ -139,8 +150,97 @@ module ATP
|
|
139
150
|
nil
|
140
151
|
end
|
141
152
|
|
153
|
+
# Returns true if the test context generated from the supplied options + existing condition
|
154
|
+
# wrappers, is different from that which was applied to the previous test.
|
155
|
+
def context_changed?(options)
|
156
|
+
a = context[:conditions]
|
157
|
+
b = build_context(options)[:conditions]
|
158
|
+
!conditions_equal?(a, b)
|
159
|
+
end
|
160
|
+
|
161
|
+
def context
|
162
|
+
builder.context
|
163
|
+
end
|
164
|
+
|
142
165
|
private
|
143
166
|
|
167
|
+
def conditions_equal?(a, b)
|
168
|
+
if a.size == b.size
|
169
|
+
a = clean_condition(a)
|
170
|
+
b = clean_condition(b)
|
171
|
+
if a.keys.sort == b.keys.sort
|
172
|
+
a.all? do |key, value|
|
173
|
+
value.flatten.uniq.sort == b[key].flatten.uniq.sort
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def clean_condition(h)
|
180
|
+
c = {}
|
181
|
+
h.each do |hash|
|
182
|
+
key, value = hash.first[0], hash.first[1]
|
183
|
+
key = clean_key(key)
|
184
|
+
value = clean_value(value)
|
185
|
+
c[key] ||= []
|
186
|
+
c[key] << value unless c[key].include?(value)
|
187
|
+
end
|
188
|
+
c
|
189
|
+
end
|
190
|
+
|
191
|
+
def clean_value(value)
|
192
|
+
if value.is_a?(Array)
|
193
|
+
value.map { |v| v.to_s.downcase }.sort
|
194
|
+
else
|
195
|
+
value.to_s.downcase
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def clean_key(key)
|
200
|
+
case key.to_sym
|
201
|
+
when :if_enabled, :enabled, :enable_flag, :enable, :if_enable
|
202
|
+
:if_enable
|
203
|
+
when :unless_enabled, :not_enabled, :disabled, :disable, :unless_enable
|
204
|
+
:unless_enable
|
205
|
+
when :if_failed, :unless_passed, :failed
|
206
|
+
:if_failed
|
207
|
+
when :if_passed, :unless_failed, :passed
|
208
|
+
:if_passed
|
209
|
+
when :if_any_failed, :unless_all_passed
|
210
|
+
:if_any_failed
|
211
|
+
when :if_all_failed, :unless_any_passed
|
212
|
+
:if_all_failed
|
213
|
+
when :if_any_passed, :unless_all_failed
|
214
|
+
:if_any_passed
|
215
|
+
when :if_all_passed, :unless_any_failed
|
216
|
+
:if_all_passed
|
217
|
+
when :if_ran, :if_executed
|
218
|
+
:if_ran
|
219
|
+
when :unless_ran, :unless_executed
|
220
|
+
:unless_ran
|
221
|
+
when :job, :jobs, :if_job, :if_jobs
|
222
|
+
:if_job
|
223
|
+
when :unless_job, :unless_jobs
|
224
|
+
:unless_job
|
225
|
+
else
|
226
|
+
fail "Unknown test condition attribute - #{key}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def build_context(options)
|
231
|
+
c = open_conditions.dup
|
232
|
+
if options[:conditions]
|
233
|
+
options[:conditions].each do |key, value|
|
234
|
+
c << { key => value }
|
235
|
+
end
|
236
|
+
end
|
237
|
+
{ conditions: c }
|
238
|
+
end
|
239
|
+
|
240
|
+
def builder
|
241
|
+
@builder ||= AST::Builder.new
|
242
|
+
end
|
243
|
+
|
144
244
|
def apply_open_conditions(options)
|
145
245
|
if options[:context] == :current
|
146
246
|
options[:conditions] = builder.context[:conditions]
|
@@ -180,9 +280,5 @@ module ATP
|
|
180
280
|
open_groups.last << node
|
181
281
|
end
|
182
282
|
end
|
183
|
-
|
184
|
-
def builder
|
185
|
-
@builder
|
186
|
-
end
|
187
283
|
end
|
188
284
|
end
|
data/lib/atp/formatters/basic.rb
CHANGED
@@ -1,20 +1,60 @@
|
|
1
|
+
require 'colored'
|
1
2
|
module ATP
|
2
3
|
module Formatters
|
3
4
|
# Outputs the given AST to something resembling an ATE datalog,
|
4
5
|
# this can optionally be rendered to a file or the console (the default).
|
5
6
|
class Datalog < Formatter
|
6
7
|
def on_flow(node)
|
7
|
-
|
8
|
+
str = 'Number'.ljust(15)
|
9
|
+
str += 'Result'.ljust(9)
|
10
|
+
str += 'Name'.ljust(55)
|
11
|
+
str += 'Test'.ljust(55)
|
12
|
+
str += 'ID'
|
13
|
+
puts str
|
8
14
|
process_all(node.children)
|
9
15
|
end
|
10
16
|
|
11
17
|
def on_test(node)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
str = "#{node.find(:number).try(:value)}".ljust(15)
|
19
|
+
if node.find(:failed)
|
20
|
+
str += 'FAIL'.ljust(9).red
|
21
|
+
else
|
22
|
+
str += 'PASS'.ljust(9)
|
23
|
+
end
|
24
|
+
str += "#{node.find(:name).value}".ljust(55)
|
25
|
+
str += "#{node.find(:object).value}".ljust(55)
|
26
|
+
str += "#{node.find(:id).value}"
|
16
27
|
puts str
|
17
28
|
end
|
29
|
+
|
30
|
+
def on_render(node)
|
31
|
+
puts '************ Directly rendered flow snippet ************'
|
32
|
+
puts node.value
|
33
|
+
puts '********************************************************'
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_log(node)
|
37
|
+
puts "// #{node.value}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_set_result(node)
|
41
|
+
bin = node.find(:bin).try(:value)
|
42
|
+
sbin = node.find(:softbin).try(:value)
|
43
|
+
desc = node.find(:description).try(:value)
|
44
|
+
|
45
|
+
if node.to_a[0] == 'pass'
|
46
|
+
str = " PASS #{bin} #{sbin}"
|
47
|
+
color = :green
|
48
|
+
else
|
49
|
+
str = " FAIL #{bin} #{sbin}"
|
50
|
+
color = :red
|
51
|
+
end
|
52
|
+
str += " (#{desc})" if desc
|
53
|
+
|
54
|
+
puts '---------------------------------------------------------------------------------------------------------------------------------------------------------'
|
55
|
+
puts str.send(color)
|
56
|
+
puts '---------------------------------------------------------------------------------------------------------------------------------------------------------'
|
57
|
+
end
|
18
58
|
end
|
19
59
|
end
|
20
60
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ATP
|
2
|
+
module Processors
|
3
|
+
# Assigns an ID to all test nodes that don't have one
|
4
|
+
class AddIDs < Processor
|
5
|
+
def run(node)
|
6
|
+
@i = 0
|
7
|
+
process(node)
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_test(node)
|
11
|
+
@i += 1
|
12
|
+
node = node.ensure_node_present(:id)
|
13
|
+
node.updated(nil, process_all(node))
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_id(node)
|
17
|
+
unless node.value
|
18
|
+
node.updated(nil, ["t#{@i}"])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -77,6 +77,7 @@ module ATP
|
|
77
77
|
alias_method :on_flow_flag, :on_boolean_condition
|
78
78
|
alias_method :on_test_result, :on_boolean_condition
|
79
79
|
alias_method :on_test_executed, :on_boolean_condition
|
80
|
+
alias_method :on_job, :on_boolean_condition
|
80
81
|
|
81
82
|
def on_condition(node)
|
82
83
|
children = node.children.dup
|
@@ -91,7 +92,6 @@ module ATP
|
|
91
92
|
end
|
92
93
|
end
|
93
94
|
alias_method :on_group, :on_condition
|
94
|
-
alias_method :on_job, :on_condition
|
95
95
|
|
96
96
|
# Returns true if the given node contains the given condition within
|
97
97
|
# its immediate children
|
@@ -109,7 +109,7 @@ module ATP
|
|
109
109
|
|
110
110
|
def equal_conditions?(node1, node2)
|
111
111
|
if node1.type == node2.type
|
112
|
-
if node1.type == :group
|
112
|
+
if node1.type == :group
|
113
113
|
node1.to_a.take(1) == node2.to_a.take(1)
|
114
114
|
else
|
115
115
|
node1.to_a.take(2) == node2.to_a.take(2)
|
@@ -21,6 +21,7 @@ module ATP
|
|
21
21
|
alias_method :on_flow_flag, :on_boolean_condition
|
22
22
|
alias_method :on_test_result, :on_boolean_condition
|
23
23
|
alias_method :on_test_executed, :on_boolean_condition
|
24
|
+
alias_method :on_job, :on_boolean_condition
|
24
25
|
|
25
26
|
def on_condition(node)
|
26
27
|
children = node.children.dup
|
@@ -29,7 +30,6 @@ module ATP
|
|
29
30
|
process_all(children)
|
30
31
|
conditions.pop
|
31
32
|
end
|
32
|
-
alias_method :on_job, :on_condition
|
33
33
|
|
34
34
|
def on_test(node)
|
35
35
|
results << [conditions.uniq, node]
|
data/lib/atp/program.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
module ATP
|
2
2
|
# Program is the top-level container for a collection of test flows
|
3
3
|
class Program
|
4
|
+
# Load a program from a previously saved file
|
5
|
+
def self.load(file)
|
6
|
+
p = nil
|
7
|
+
File.open(file) do |f|
|
8
|
+
p = Marshal.load(f)
|
9
|
+
end
|
10
|
+
p
|
11
|
+
end
|
12
|
+
|
4
13
|
def flow(name)
|
5
14
|
flows[name] ||= Flow.new(self, name)
|
6
15
|
end
|
@@ -9,6 +18,13 @@ module ATP
|
|
9
18
|
@flows ||= {}
|
10
19
|
end
|
11
20
|
|
21
|
+
# Save the program to a file
|
22
|
+
def save(file)
|
23
|
+
File.open(file, 'w') do |f|
|
24
|
+
Marshal.dump(self, f)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
12
28
|
def respond_to?(*args)
|
13
29
|
flows.key?(args.first) || super
|
14
30
|
end
|
data/lib/atp/runner.rb
CHANGED
@@ -6,7 +6,9 @@ module ATP
|
|
6
6
|
class Runner < Processor
|
7
7
|
def run(node, options = {})
|
8
8
|
@options = options
|
9
|
-
|
9
|
+
@completed = false
|
10
|
+
@groups = []
|
11
|
+
process(Processors::AddIDs.new.run(node))
|
10
12
|
end
|
11
13
|
|
12
14
|
def on_flow(node)
|
@@ -17,8 +19,18 @@ module ATP
|
|
17
19
|
|
18
20
|
def on_flow_flag(node)
|
19
21
|
flag, enabled, *nodes = *node
|
20
|
-
|
21
|
-
|
22
|
+
flag = [flag].flatten
|
23
|
+
active = flag.any? { |f| flow_flags.include?(f) }
|
24
|
+
if (enabled && active) || (!enabled && !active)
|
25
|
+
process_all(nodes)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_run_flag(node)
|
30
|
+
flag, enabled, *nodes = *node
|
31
|
+
flag = [flag].flatten
|
32
|
+
active = flag.any? { |f| run_flags.include?(f) }
|
33
|
+
if (enabled && active) || (!enabled && !active)
|
22
34
|
process_all(nodes)
|
23
35
|
end
|
24
36
|
end
|
@@ -28,9 +40,46 @@ module ATP
|
|
28
40
|
id = id.to_a[0]
|
29
41
|
if failed_test_ids.include?(id)
|
30
42
|
node = node.add(n0(:failed))
|
43
|
+
failed = true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@flow << node unless completed?
|
47
|
+
if failed
|
48
|
+
# Give indication to the parent group that at least one test within it failed
|
49
|
+
if @groups.last
|
50
|
+
@groups.pop
|
51
|
+
@groups << false
|
52
|
+
end
|
53
|
+
if n = node.find(:on_fail)
|
54
|
+
@continue = !!n.find(:continue)
|
55
|
+
process_all(n)
|
56
|
+
@continue = false
|
57
|
+
end
|
58
|
+
else
|
59
|
+
if n = node.find(:on_pass)
|
60
|
+
process_all(n)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def on_group(node)
|
66
|
+
@groups << true # This will be set to false by any tests that fail within the group
|
67
|
+
process_all(node.find(:members))
|
68
|
+
if !@groups.pop # If failed
|
69
|
+
if n = node.find(:on_fail)
|
70
|
+
@continue = !!n.find(:continue)
|
71
|
+
process_all(n)
|
72
|
+
@continue = false
|
73
|
+
end
|
74
|
+
else
|
75
|
+
if n = node.find(:on_pass)
|
76
|
+
process_all(n)
|
31
77
|
end
|
32
78
|
end
|
33
|
-
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_members(node)
|
82
|
+
# Do nothing, will be processed directly by the on_group handler
|
34
83
|
end
|
35
84
|
|
36
85
|
def on_test_result(node)
|
@@ -41,13 +90,66 @@ module ATP
|
|
41
90
|
end
|
42
91
|
end
|
43
92
|
|
93
|
+
def on_set_result(node)
|
94
|
+
unless @continue
|
95
|
+
@flow << node unless completed?
|
96
|
+
@completed = true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_set_run_flag(node)
|
101
|
+
run_flags << node.to_a[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
def on_enable_flow_flag(node)
|
105
|
+
flow_flags << node.value unless flow_flags.include?(node.value)
|
106
|
+
end
|
107
|
+
|
108
|
+
def on_disable_flow_flag(node)
|
109
|
+
flow_flags.delete(node.value)
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_log(node)
|
113
|
+
@flow << node unless completed?
|
114
|
+
end
|
115
|
+
alias_method :on_render, :on_log
|
116
|
+
|
117
|
+
def on_job(node)
|
118
|
+
jobs, state, *nodes = *node
|
119
|
+
jobs = clean_job(jobs)
|
120
|
+
unless job
|
121
|
+
fail 'Flow contains JOB-based conditions and no current JOB has been given!'
|
122
|
+
end
|
123
|
+
if state
|
124
|
+
process_all(node) if jobs.include?(job)
|
125
|
+
else
|
126
|
+
process_all(node) unless jobs.include?(job)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def clean_job(job)
|
131
|
+
[job].flatten.map { |j| j.to_s.upcase }
|
132
|
+
end
|
133
|
+
|
134
|
+
def job
|
135
|
+
@options[:job].to_s.upcase if @options[:job]
|
136
|
+
end
|
137
|
+
|
44
138
|
def failed_test_ids
|
45
139
|
@failed_test_ids ||= [@options[:failed_test_id] || @options[:failed_test_ids]].flatten.compact
|
46
140
|
end
|
47
141
|
|
142
|
+
def run_flags
|
143
|
+
@run_flags ||= []
|
144
|
+
end
|
145
|
+
|
48
146
|
# Returns an array of enabled flow flags
|
49
147
|
def flow_flags
|
50
148
|
@flow_flags ||= [@options[:flow_flag] || @options[:flow_flags]].flatten.compact
|
51
149
|
end
|
150
|
+
|
151
|
+
def completed?
|
152
|
+
@completed
|
153
|
+
end
|
52
154
|
end
|
53
155
|
end
|
data/lib/atp/validator.rb
CHANGED
@@ -14,10 +14,20 @@ module ATP
|
|
14
14
|
@top_level_called = true
|
15
15
|
setup
|
16
16
|
super(node)
|
17
|
-
|
17
|
+
unless @testing
|
18
|
+
exit 1 if on_completion
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
23
|
+
# For test purposes, returns true if validation failed rather
|
24
|
+
# than exiting the process
|
25
|
+
def test_process(node)
|
26
|
+
@testing = true
|
27
|
+
process(node)
|
28
|
+
on_completion
|
29
|
+
end
|
30
|
+
|
21
31
|
def setup
|
22
32
|
end
|
23
33
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ATP
|
2
|
+
module Validators
|
3
|
+
class Jobs < Validator
|
4
|
+
def setup
|
5
|
+
@conflicting = []
|
6
|
+
@negative = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def on_completion
|
10
|
+
failed = false
|
11
|
+
unless @conflicting.empty?
|
12
|
+
Origen.log.error 'if_job and unless_job conditions cannot both be applied to the same tests'
|
13
|
+
Origen.log.error "The following conflicts were found in flow #{flow.name}:"
|
14
|
+
@conflicting.each do |a, b|
|
15
|
+
a_condition = a.to_a[1] ? 'if_job: ' : 'unless_job:'
|
16
|
+
b_condition = b.to_a[1] ? 'if_job: ' : 'unless_job:'
|
17
|
+
Origen.log.error " #{a_condition} #{a.source}"
|
18
|
+
Origen.log.error " #{b_condition} #{b.source}"
|
19
|
+
Origen.log.error ''
|
20
|
+
end
|
21
|
+
failed = true
|
22
|
+
end
|
23
|
+
|
24
|
+
unless @negative.empty?
|
25
|
+
Origen.log.error 'Job names should not be negated, use unless_job if you want to specify !JOB'
|
26
|
+
Origen.log.error "The following negative job names were found in flow #{flow.name}:"
|
27
|
+
@negative.each do |node|
|
28
|
+
Origen.log.error " #{node.to_a[0]} #{node.source}"
|
29
|
+
end
|
30
|
+
failed = true
|
31
|
+
end
|
32
|
+
|
33
|
+
failed
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_job(node)
|
37
|
+
jobs, state, *nodes = *node
|
38
|
+
jobs = [jobs].flatten
|
39
|
+
if jobs.any? { |j| j.to_s =~ /^(!|~)/ }
|
40
|
+
@negative << node
|
41
|
+
end
|
42
|
+
@stack ||= []
|
43
|
+
if !@stack.empty? && @stack.last[1] != state
|
44
|
+
@conflicting << [@stack.last[0], node]
|
45
|
+
else
|
46
|
+
@stack << [node, state]
|
47
|
+
process_all(node)
|
48
|
+
@stack.pop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -64,7 +64,6 @@ files:
|
|
64
64
|
- config/commands.rb
|
65
65
|
- config/version.rb
|
66
66
|
- lib/atp.rb
|
67
|
-
- lib/atp/and.rb
|
68
67
|
- lib/atp/ast/builder.rb
|
69
68
|
- lib/atp/ast/extractor.rb
|
70
69
|
- lib/atp/ast/factories.rb
|
@@ -73,12 +72,12 @@ files:
|
|
73
72
|
- lib/atp/formatter.rb
|
74
73
|
- lib/atp/formatters/basic.rb
|
75
74
|
- lib/atp/formatters/datalog.rb
|
76
|
-
- lib/atp/not.rb
|
77
|
-
- lib/atp/or.rb
|
78
75
|
- lib/atp/parser.rb
|
79
76
|
- lib/atp/processor.rb
|
77
|
+
- lib/atp/processors/add_ids.rb
|
80
78
|
- lib/atp/processors/condition.rb
|
81
79
|
- lib/atp/processors/condition_extractor.rb
|
80
|
+
- lib/atp/processors/marshal.rb
|
82
81
|
- lib/atp/processors/post_cleaner.rb
|
83
82
|
- lib/atp/processors/pre_cleaner.rb
|
84
83
|
- lib/atp/processors/relationship.rb
|
@@ -87,6 +86,7 @@ files:
|
|
87
86
|
- lib/atp/validator.rb
|
88
87
|
- lib/atp/validators/condition.rb
|
89
88
|
- lib/atp/validators/duplicate_ids.rb
|
89
|
+
- lib/atp/validators/jobs.rb
|
90
90
|
- lib/atp/validators/missing_ids.rb
|
91
91
|
- lib/tasks/atp.rake
|
92
92
|
- templates/web/archive.md.erb
|
data/lib/atp/and.rb
DELETED
data/lib/atp/not.rb
DELETED