atp 0.2.1 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0318ad5ca67b39da3b87b038434eaa85b1ee2a1d
4
- data.tar.gz: 63bdc11c210bba2219097d14b3c5aa55678a8c8f
3
+ metadata.gz: 7cdbd30f66efb6b3795073de37ccdf0623377b7b
4
+ data.tar.gz: 4b3deec7a4e80eaa56dfd1b14934790a044ab611
5
5
  SHA512:
6
- metadata.gz: ae4da77cd22cc197e3ecf80af390de270b71c6a00cfcae3c49345156b9840c5f6429520707c29c36dffb89d54ec50b8af710257c93f23b872d44b5a10fb8aad6
7
- data.tar.gz: 6ee881a43ee9cf5015860b50719d6d07c461f545180d967319d8ada891a36cd47adf8ac48a5ef277c79494bfbc0a54dfdddb77d1bbaac77a70dc8a6d67b63f24
6
+ metadata.gz: 5309d2a1ddef3772ae949e47d3ce750a3eee0236498741cc0d752e3a7973fca9a016186ff17c02d54095055af51676b03eb2af8d6a23ebf695d7273096b5a406
7
+ data.tar.gz: b391e87fa09e223a717b6f11842ca2af604b33849ade223a657f8acaa5202dc90153070a89c4117b6a99fdb8e36bfa2dbef633b22957032c274aba6332eeffae
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module ATP
2
2
  MAJOR = 0
3
- MINOR = 2
4
- BUGFIX = 1
3
+ MINOR = 3
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
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
@@ -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
- context[:conditions][key] = value
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
- # Make sure these are wrapped by an OR, AND jobs doesn't make sense anyway
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
- # Make sure these are wrapped by an OR, AND jobs doesn't make sense anyway
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
- nodes = find_all(type)
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
- Extractor.new.process(self, types)
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
@@ -10,7 +10,7 @@ module ATP
10
10
  end
11
11
 
12
12
  def on_test(node)
13
- @output += node.to_h[:name][0]
13
+ @output += node.find(:name).value
14
14
  @output += "\n"
15
15
  end
16
16
  end
@@ -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
- puts 'Number Result Test Name Pin Channel Low Measured High Force Loc'
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
- t = node.to_h
13
- str = "#{t[:number]}".ljust(11)
14
- str += "#{t[:failed] ? 'FAIL' : 'PASS'}".ljust(9)
15
- str += "#{t[:name][0]}".ljust(20)
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 || node1.type == :job
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]
@@ -0,0 +1,14 @@
1
+ module ATP
2
+ module Processors
3
+ # Makes the AST safe for Marshaling
4
+ class Marshal < Processor
5
+ def on_object(node)
6
+ if node.value.is_a?(String)
7
+ node
8
+ else
9
+ node.updated(nil, [node.value.name])
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
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
- process(node)
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
- if (enabled && flow_flags.include?(flag)) ||
21
- (!enabled && !flow_flags.include?(flag))
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
- @flow << node
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
- exit 1 if on_completion
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.2.1
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-01-27 00:00:00.000000000 Z
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
@@ -1,11 +0,0 @@
1
- module ATP
2
- class AND < ::Array
3
- def initialize(*vals)
4
- vals.flatten.each { |v| self << v }
5
- end
6
-
7
- def inspect
8
- "AND#{super}"
9
- end
10
- end
11
- end
data/lib/atp/not.rb DELETED
@@ -1,13 +0,0 @@
1
- module ATP
2
- class NOT
3
- attr_reader :value
4
-
5
- def initialize(value)
6
- @value = value
7
- end
8
-
9
- def inspect
10
- "NOT[#{value}]"
11
- end
12
- end
13
- end
data/lib/atp/or.rb DELETED
@@ -1,11 +0,0 @@
1
- module ATP
2
- class OR < ::Array
3
- def initialize(*vals)
4
- vals.flatten.each { |v| self << v }
5
- end
6
-
7
- def inspect
8
- "OR#{super}"
9
- end
10
- end
11
- end