origen_testers 0.5.7 → 0.6.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/config/shared_commands.rb +6 -0
  3. data/config/version.rb +2 -2
  4. data/lib/commands/run.rb +44 -0
  5. data/lib/origen_testers.rb +19 -1
  6. data/lib/origen_testers/flow.rb +382 -0
  7. data/lib/origen_testers/generator.rb +32 -29
  8. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -0
  9. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -0
  10. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -0
  11. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -0
  12. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -0
  13. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +97 -0
  14. data/lib/origen_testers/igxl_based_tester/base/flow.rb +390 -115
  15. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +4 -54
  16. data/lib/origen_testers/igxl_based_tester/base/generator.rb +257 -11
  17. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -0
  18. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -0
  19. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -0
  20. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +109 -0
  21. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -0
  22. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +33 -1
  23. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -0
  24. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +47 -0
  25. data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +2 -2
  26. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -0
  27. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +4 -0
  28. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -0
  29. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -0
  30. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -0
  31. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -0
  32. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -0
  33. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +137 -0
  34. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -0
  35. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -0
  36. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -0
  37. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -0
  38. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -0
  39. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +58 -0
  40. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +58 -0
  41. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +95 -0
  42. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +2 -2
  43. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +121 -0
  44. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +24 -0
  45. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +137 -0
  46. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +4 -0
  47. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -0
  48. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -0
  49. data/lib/origen_testers/interface.rb +41 -6
  50. data/lib/origen_testers/no_interface.rb +7 -0
  51. data/lib/origen_testers/origen_ext/application/runner.rb +25 -0
  52. data/lib/origen_testers/origen_ext/generator.rb +37 -0
  53. data/lib/origen_testers/origen_ext/generator/flow.rb +70 -0
  54. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -0
  55. data/lib/origen_testers/program_generators.rb +0 -1
  56. data/lib/origen_testers/smartest_based_tester/base/flow.rb +158 -134
  57. data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -3
  58. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +4 -0
  59. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +5 -6
  60. data/lib/origen_testers/test/dut.rb +5 -0
  61. data/lib/origen_testers/test/j750_base_interface.rb +0 -3
  62. data/lib/origen_testers/test/ultraflex_interface.rb +230 -4
  63. data/lib/origen_testers/test/v93k_interface.rb +5 -23
  64. data/program/components/_temp.rb +6 -0
  65. data/program/flow_control.rb +190 -62
  66. data/program/prb1.rb +13 -50
  67. data/program/prb2.rb +0 -16
  68. data/program/test.rb +12 -3
  69. data/program/uflex_resources.rb +159 -0
  70. metadata +66 -16
  71. data/lib/origen_testers/doc.rb +0 -224
  72. data/lib/origen_testers/doc/generator.rb +0 -124
  73. data/lib/origen_testers/doc/generator/flow.rb +0 -69
  74. data/lib/origen_testers/doc/generator/flow_line.rb +0 -201
  75. data/lib/origen_testers/doc/generator/test.rb +0 -66
  76. data/lib/origen_testers/doc/generator/test_group.rb +0 -64
  77. data/lib/origen_testers/doc/generator/tests.rb +0 -45
  78. data/lib/origen_testers/doc/model.rb +0 -160
  79. data/lib/origen_testers/generator/flow_control_api.rb +0 -611
  80. data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +0 -476
  81. data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a52647531345037e756ea1413fad9e55af38d5e
4
- data.tar.gz: d2f632b5f8fc173a407a367e44f76f11bff71a9a
3
+ metadata.gz: e3d1a042fabeba96ae6e0c3e49a4448412f5e086
4
+ data.tar.gz: 8afd5f06c2fdded1afb0158c10e416d39e5c1d17
5
5
  SHA512:
6
- metadata.gz: 37665c194131cff9784e4eb867750aa1d44dc1f50fe899348696f6872ed5f3d8d096ca1b636ade17aaaf5a268af3be0380e4be7882b51d915c9123982581e4fe
7
- data.tar.gz: 74af03290ef3057d9347294c75a028ff18d3784f9b1d9585e7c9ab5de6d93e6d508aa51b7e5a799ea5183aaf8d7d82bcfbd3eaf67ef12638fb68fc8a2ee8f747
6
+ metadata.gz: 854aaa61e835e0ef0753cac4572a0851cc036273fd7f9e7c7c246b6cf3ac3862a1c08f2416fd03b5d561589e112d39ce47e52d19898c559e5cef141bb648f1cb
7
+ data.tar.gz: 7087d2fcb8ffc06b0680bab06b20c7daa45329894573895630758377792f5686aaa30d5c542afab5a4f7ec4df104b37a2d2f491f4d73f266497e8c5c8b7661d1
@@ -41,7 +41,13 @@ case @command
41
41
  require "#{Origen.root!}/lib/commands/build"
42
42
  exit 0
43
43
 
44
+ when "testers:run"
45
+ require "#{Origen.root!}/lib/commands/run"
46
+ exit 0
47
+
48
+
44
49
  else
45
50
  @plugin_commands << " testers:build Build a test program from a collection of sub-programs"
51
+ @plugin_commands << " testers:run Run the last test program generated for the current target"
46
52
 
47
53
  end
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 5
4
- BUGFIX = 7
3
+ MINOR = 6
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -0,0 +1,44 @@
1
+ require 'optparse'
2
+ require 'pathname'
3
+
4
+ options = {}
5
+
6
+ opt_parser = OptionParser.new do |opts|
7
+ opts.banner = <<-EOT
8
+ Run (execute a flow) of the last test program generated for the given target.
9
+
10
+ Usage: origen testers:run FLOW [options]
11
+ EOT
12
+ opts.on('--enable FLAG,FLAG', Array, 'Comma-separated list of flow flags to enable') { |flags| options[:flow_flags] = flags }
13
+ opts.on('--job NAME', String, 'Job name to enable') { |job| options[:job] = job }
14
+ opts.on('--fail ID,ID', Array, 'Comma-separated list of test IDs to fail') { |ids| options[:failed_test_ids] = ids }
15
+ opts.on('-e', '--environment NAME', String, 'Override the default environment, NAME can be a full path or a fragment of an environment file name') { |e| options[:environment] = e }
16
+ opts.on('-t', '--target NAME', String, 'Override the default target, NAME can be a full path or a fragment of a target file name') { |t| options[:target] = t }
17
+ opts.on('-d', '--debugger', 'Enable the debugger') { options[:debugger] = true }
18
+ opts.on('-m', '--mode MODE', Origen::Mode::MODES, 'Force the Origen operating mode:', ' ' + Origen::Mode::MODES.join(', ')) { |_m| }
19
+ opts.separator ''
20
+ opts.on('-h', '--help', 'Show this message') { puts opts; exit 0 }
21
+ end
22
+
23
+ opt_parser.parse! ARGV
24
+
25
+ Origen.environment.temporary = options[:environment] if options[:environment]
26
+ Origen.target.temporary = options[:target] if options[:target]
27
+ # Origen.app.load_target!
28
+
29
+ program = OrigenTesters.program
30
+
31
+ unless program
32
+ puts 'Sorry, but there is no program model available for the current target, generate the program then retry'
33
+ exit 1
34
+ end
35
+
36
+ flow = ARGV.first
37
+
38
+ unless flow
39
+ puts 'You must supply the name of the flow to execute, the current program has these flows'
40
+ puts OrigenTesters.program.flows.keys
41
+ exit 1
42
+ end
43
+
44
+ OrigenTesters.program.flows[flow.to_sym].run(options)
@@ -1,9 +1,13 @@
1
1
  require 'origen'
2
2
  require 'active_support/concern'
3
3
  require 'require_all'
4
+ require 'atp'
5
+ require 'origen_testers/origen_ext/generator/flow'
6
+ require 'origen_testers/origen_ext/generator/resources'
7
+ require 'origen_testers/origen_ext/application/runner'
8
+ require 'origen_testers/origen_ext/generator'
4
9
 
5
10
  module OrigenTesters
6
- autoload :Doc, 'origen_testers/doc'
7
11
  autoload :CommandBasedTester, 'origen_testers/command_based_tester'
8
12
  autoload :VectorBasedTester, 'origen_testers/vector_based_tester'
9
13
  autoload :Vector, 'origen_testers/vector'
@@ -13,8 +17,22 @@ module OrigenTesters
13
17
  autoload :Parser, 'origen_testers/parser'
14
18
  autoload :BasicTestSetups, 'origen_testers/basic_test_setups'
15
19
  autoload :ProgramGenerators, 'origen_testers/program_generators'
20
+ autoload :Flow, 'origen_testers/flow'
21
+ autoload :NoInterface, 'origen_testers/no_interface'
16
22
 
17
23
  # not yet autoload :Time, 'origen_testers/time'
24
+
25
+ # The documentation tester model has been removed, but this keeps some
26
+ # legacy code working e.g. $tester.is_a?(OrigenTesters::Doc)
27
+ class Doc
28
+ end
29
+
30
+ def self.program
31
+ f = "#{Flow::PROGRAM_MODELS_DIR}/#{Origen.target.name}"
32
+ if File.exist?(f)
33
+ ATP::Program.load(f)
34
+ end
35
+ end
18
36
  end
19
37
 
20
38
  require 'origen_testers/igxl_based_tester'
@@ -0,0 +1,382 @@
1
+ require 'digest/md5'
2
+ module OrigenTesters
3
+ # Provides a common API to add tests to a flow that is supported by all testers.
4
+ #
5
+ # This builds up a flow model using the Abstract Test Program (ATP) gem, which
6
+ # now deals with implementing the flow control API.
7
+ #
8
+ # Individual tester drivers in this plugin are then responsible at the end to
9
+ # render the abstract flow to their specific format and conventions.
10
+ module Flow
11
+ include OrigenTesters::Generator
12
+
13
+ PROGRAM_MODELS_DIR = "#{Origen.root}/tmp/program_models"
14
+
15
+ def self.callstack
16
+ @callstack ||= []
17
+ end
18
+
19
+ def self.comment_stack
20
+ @comment_stack ||= []
21
+ end
22
+
23
+ def self.flow_comments
24
+ @flow_comments
25
+ end
26
+
27
+ def self.flow_comments=(val)
28
+ @flow_comments = val
29
+ end
30
+
31
+ def self.unique_ids
32
+ @unique_ids
33
+ end
34
+
35
+ def self.unique_ids=(val)
36
+ @unique_ids = val
37
+ end
38
+
39
+ def lines
40
+ @lines
41
+ end
42
+
43
+ # Returns the abstract test program model, this is shared by all
44
+ # flow created together in a generation run
45
+ def program
46
+ @@program ||= ATP::Program.new
47
+ end
48
+
49
+ def save_program
50
+ FileUtils.mkdir_p(PROGRAM_MODELS_DIR) unless File.exist?(PROGRAM_MODELS_DIR)
51
+ program.save("#{PROGRAM_MODELS_DIR}/#{Origen.target.name}")
52
+ end
53
+
54
+ def model
55
+ if Origen.interface.resources_mode?
56
+ @throwaway ||= ATP::Flow.new(self)
57
+ else
58
+ @model ||= begin
59
+ f = program.flow(id, description: OrigenTesters::Flow.flow_comments)
60
+ @sig = flow_sig(id)
61
+ f.id = @sig if OrigenTesters::Flow.unique_ids
62
+ f
63
+ end
64
+ end
65
+ end
66
+
67
+ def enable(var, options = {})
68
+ add_meta!(options)
69
+ model.enable(var, clean_options(options))
70
+ end
71
+
72
+ def disable(var, options = {})
73
+ add_meta!(options)
74
+ model.disable(var, clean_options(options))
75
+ end
76
+
77
+ def bin(number, options = {})
78
+ options[:bin_description] ||= options.delete(:description)
79
+ if number.is_a?(Hash)
80
+ fail 'The bin number must be passed as the first argument'
81
+ end
82
+ add_meta!(options)
83
+ options[:type] ||= :fail
84
+ model.bin(number, clean_options(options))
85
+ end
86
+
87
+ def pass(number, options = {})
88
+ if number.is_a?(Hash)
89
+ fail 'The bin number must be passed as the first argument'
90
+ end
91
+ options[:type] = :pass
92
+ bin(number, clean_options(options))
93
+ end
94
+
95
+ def test(instance, options = {})
96
+ add_meta_and_description!(options)
97
+ model.test(instance, clean_options(options))
98
+ end
99
+
100
+ def render(file, options = {})
101
+ add_meta!(options)
102
+ begin
103
+ text = super
104
+ rescue
105
+ text = file
106
+ end
107
+ model.render(text)
108
+ end
109
+
110
+ def cz(instance, cz_setup, options = {})
111
+ add_meta_and_description!(options)
112
+ model.cz(instance, cz_setup, clean_options(options))
113
+ end
114
+ alias_method :characterize, :cz
115
+
116
+ def log(message, options = {})
117
+ add_meta!(options)
118
+ model.log(message, clean_options(options))
119
+ end
120
+ alias_method :logprint, :log
121
+
122
+ def group(name, options = {})
123
+ add_meta!(options)
124
+ model.group(name, clean_options(options)) do
125
+ yield
126
+ end
127
+ end
128
+
129
+ def nop(options = {})
130
+ end
131
+
132
+ # @api private
133
+ # This fires between target loads
134
+ def at_run_start
135
+ @@program = nil
136
+ end
137
+
138
+ # @api private
139
+ # This fires between flows
140
+ def at_flow_start
141
+ @labels = {}
142
+ end
143
+
144
+ def if_job(*jobs)
145
+ options = jobs.last.is_a?(Hash) ? jobs.pop : {}
146
+ options[:if_job] = jobs.flatten
147
+ add_meta!(options)
148
+ model.with_conditions(options) do
149
+ yield
150
+ end
151
+ end
152
+ alias_method :if_jobs, :if_job
153
+
154
+ def unless_job(*jobs)
155
+ options = jobs.last.is_a?(Hash) ? jobs.pop : {}
156
+ options[:unless_job] = jobs.flatten
157
+ add_meta!(options)
158
+ model.with_conditions(options) do
159
+ yield
160
+ end
161
+ end
162
+ alias_method :unless_jobs, :unless_job
163
+
164
+ def if_enable(word, options = {})
165
+ if options[:or]
166
+ yield
167
+ else
168
+ options = { enable: word }
169
+ add_meta!(options)
170
+ model.with_conditions(options) do
171
+ yield
172
+ end
173
+ end
174
+ end
175
+ alias_method :if_enabled, :if_enable
176
+
177
+ def unless_enable(word, options = {})
178
+ if options[:or]
179
+ yield
180
+ else
181
+ options = { unless_enable: word }
182
+ add_meta!(options)
183
+ model.with_conditions(options) do
184
+ yield
185
+ end
186
+ end
187
+ end
188
+ alias_method :unless_enabled, :unless_enable
189
+
190
+ def if_passed(test_id, options = {})
191
+ if test_id.is_a?(Array)
192
+ fail 'if_passed only accepts one ID, use if_any_passed or if_all_passed for multiple IDs'
193
+ end
194
+ options = { if_passed: test_id }
195
+ add_meta!(options)
196
+ model.with_conditions(options) do
197
+ yield
198
+ end
199
+ end
200
+ alias_method :unless_failed, :if_passed
201
+
202
+ def if_failed(test_id, options = {})
203
+ if test_id.is_a?(Array)
204
+ fail 'if_failed only accepts one ID, use if_any_failed or if_all_failed for multiple IDs'
205
+ end
206
+ options = { if_failed: test_id }
207
+ add_meta!(options)
208
+ model.with_conditions(options) do
209
+ yield
210
+ end
211
+ end
212
+ alias_method :unless_passed, :if_failed
213
+
214
+ def if_ran(test_id, options = {})
215
+ options = { if_ran: test_id }
216
+ add_meta!(options)
217
+ model.with_conditions(options) do
218
+ yield
219
+ end
220
+ end
221
+
222
+ def unless_ran(test_id, options = {})
223
+ options = { unless_ran: test_id }
224
+ add_meta!(options)
225
+ model.with_conditions(options) do
226
+ yield
227
+ end
228
+ end
229
+
230
+ def if_any_failed(*ids)
231
+ options = ids.last.is_a?(Hash) ? ids.pop : {}
232
+ options[:if_any_failed] = ids.flatten
233
+ add_meta!(options)
234
+ model.with_conditions(options) do
235
+ yield
236
+ end
237
+ end
238
+
239
+ def if_all_failed(*ids)
240
+ options = ids.last.is_a?(Hash) ? ids.pop : {}
241
+ options[:if_all_failed] = ids.flatten
242
+ add_meta!(options)
243
+ model.with_conditions(options) do
244
+ yield
245
+ end
246
+ end
247
+
248
+ def if_any_passed(*ids)
249
+ options = ids.last.is_a?(Hash) ? ids.pop : {}
250
+ options[:if_any_passed] = ids.flatten
251
+ add_meta!(options)
252
+ model.with_conditions(options) do
253
+ yield
254
+ end
255
+ end
256
+
257
+ def if_all_passed(*ids)
258
+ options = ids.last.is_a?(Hash) ? ids.pop : {}
259
+ options[:if_all_passed] = ids.flatten
260
+ add_meta!(options)
261
+ model.with_conditions(options) do
262
+ yield
263
+ end
264
+ end
265
+
266
+ def if_flag(flag, options = {})
267
+ options = { if_flag: flag }
268
+ add_meta!(options)
269
+ model.with_conditions(options) do
270
+ yield
271
+ end
272
+ end
273
+
274
+ def unless_flag(flag, options = {})
275
+ options = { unless_flag: flag }
276
+ add_meta!(options)
277
+ model.with_conditions(options) do
278
+ yield
279
+ end
280
+ end
281
+
282
+ # @api private
283
+ def is_the_flow?
284
+ true
285
+ end
286
+
287
+ # Returns true if the test context generated from the supplied options + existing condition
288
+ # wrappers is different from that which was applied to the previous test.
289
+ def context_changed?(options)
290
+ options = clean_options(options)
291
+ model.context_changed?(options)
292
+ end
293
+
294
+ def generate_unique_label(name = nil)
295
+ name = 'label' if !name || name == ''
296
+ name.gsub!(' ', '_')
297
+ name.upcase!
298
+ @labels ||= {}
299
+ @labels[name] ||= 0
300
+ @labels[name] += 1
301
+ "#{name}_#{@labels[name]}_#{sig}"
302
+ end
303
+
304
+ # Returns a unique signature that has been generated for the current flow, this can be appended
305
+ # to named references to avoid naming collisions with any other flow
306
+ def sig
307
+ @sig
308
+ end
309
+ alias_method :signature, :sig
310
+
311
+ private
312
+
313
+ # Make a unique signature for the flow based on the flow name and the name of
314
+ # the plugin/app that owns it
315
+ def flow_sig(id)
316
+ s = Digest::MD5.new
317
+ # These guarantee uniqueness within a plugin/app
318
+ s << id.to_s
319
+ s << filename
320
+ # This will add the required plugin uniqueness in the case of a top-level app
321
+ # that has multiple plugins that can generate test program snippets
322
+ if file = OrigenTesters::Flow.callstack.first
323
+ s << get_app(file).name.to_s
324
+ end
325
+ s.to_s[0..6].upcase
326
+ end
327
+
328
+ def get_app(file)
329
+ path = Pathname.new(file).dirname
330
+ until File.exist?(File.join(path, 'config/application.rb')) || path.root?
331
+ path = path.parent
332
+ end
333
+ if path.root?
334
+ fail 'Something went wrong resoving the app root in OrigenTesters'
335
+ end
336
+ Origen.find_app_by_root(path)
337
+ end
338
+
339
+ def add_meta!(options)
340
+ flow_file = OrigenTesters::Flow.callstack.last
341
+ called_from = caller.find { |l| l =~ /^#{flow_file}:.*/ }
342
+ if called_from
343
+ called_from = called_from.split(':')
344
+ options[:source_file] = called_from[0]
345
+ options[:source_line_number] = called_from[1].to_i
346
+ end
347
+ end
348
+
349
+ def add_meta_and_description!(options)
350
+ add_meta!(options)
351
+ # Can be useful if an app generates additional tests on the fly for a single test in the flow,
352
+ # e.g. a POR, in that case they will not want the description to be attached to the POR, but to
353
+ # the test that follows it
354
+ unless options[:inhibit_description_consumption]
355
+ comments = OrigenTesters::Flow.comment_stack.last
356
+ if options[:source_line_number]
357
+ while comments.first && comments.first.first < options[:source_line_number]
358
+ options[:description] ||= []
359
+ c = comments.shift
360
+ if c[0] + c[1].size == options[:source_line_number]
361
+ options[:description] += c[1]
362
+ end
363
+ end
364
+ end
365
+ end
366
+ end
367
+
368
+ def clean_options(options)
369
+ ATP::AST::Builder::CONDITION_KEYS.each do |key|
370
+ if v = options.delete(key)
371
+ options[:conditions] ||= {}
372
+ if options[:conditions][key]
373
+ fail "Multiple values assigned to flow condition #{key}"
374
+ else
375
+ options[:conditions][key] = v
376
+ end
377
+ end
378
+ end
379
+ options
380
+ end
381
+ end
382
+ end