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 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