atp 0.3.3 → 0.4.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: d20477f1e1e9f17a369fd66bab80a6d281ba14aa
4
- data.tar.gz: a1e3578e7ce467f355d3d977a8892dba404602bb
3
+ metadata.gz: 7f64914b7c8843db8db3ad65544769c34244a2be
4
+ data.tar.gz: 69ad71f98a175f843a851863d00937aa93c6d52a
5
5
  SHA512:
6
- metadata.gz: 24ef6ffa11c6694d9d35c9919c824dab356a60626d44e5ea24fc66eab5838c169407bd0d15d3903830a1ceee49a26f5962eedda59da0cd3e0399367e3ed9f5f2
7
- data.tar.gz: 2eb38eebf9358bb09fd17b1f08e67aecf30a1d21f3831bc06361e0bd81f942aedaa7e9e23a0c1523954ae989bc8d858b0186d3eb0957561b662137fcef6bed7e
6
+ metadata.gz: 22d183c262e97d8218ebd96db88c0c2b5a5b3dc1131240243e56e729ba358b08730fdce8db67b116ecc1a8e21934806cf8bbda95339a5a2934f14fd50e00f00a
7
+ data.tar.gz: 3659a5efe9ee71d5f4cad2df39b5c72e3d13523fff03602087d2dcdb19f8ba74e62c2931619085904cbfdd72ef7c574a627d996c89b8d61e70acbdb818599b92
@@ -1,7 +1,7 @@
1
1
  module ATP
2
2
  MAJOR = 0
3
- MINOR = 3
4
- BUGFIX = 3
3
+ MINOR = 4
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
data/lib/atp.rb CHANGED
@@ -27,6 +27,7 @@ module ATP
27
27
  autoload :PostCleaner, 'atp/processors/post_cleaner'
28
28
  autoload :Marshal, 'atp/processors/marshal'
29
29
  autoload :AddIDs, 'atp/processors/add_ids'
30
+ autoload :AddSetResult, 'atp/processors/add_set_result'
30
31
  autoload :FlowID, 'atp/processors/flow_id'
31
32
  end
32
33
 
@@ -10,8 +10,8 @@ module ATP
10
10
  @context = { conditions: [] }
11
11
  end
12
12
 
13
- def flow
14
- n0(:flow)
13
+ def flow(str)
14
+ n(:flow, name(str))
15
15
  end
16
16
 
17
17
  def name(str)
@@ -81,7 +81,7 @@ module ATP
81
81
  children << on_fail(options[:on_fail]) if options[:on_fail]
82
82
  children << on_pass(options[:on_pass]) if options[:on_pass]
83
83
 
84
- children << n(:members, *nodes)
84
+ children += nodes
85
85
  group = n(:group, *children)
86
86
 
87
87
  if options[:conditions]
@@ -29,11 +29,16 @@ module ATP
29
29
 
30
30
  # Adds an empty node of the given type to the children unless another
31
31
  # node of the same type is already present
32
- def ensure_node_present(type)
32
+ def ensure_node_present(type, child_nodes = nil)
33
33
  if children.any? { |n| n.type == type }
34
34
  self
35
35
  else
36
- updated(nil, children + [n0(type)])
36
+ if child_nodes
37
+ node = n(type, *child_nodes)
38
+ else
39
+ node = n0(type)
40
+ end
41
+ updated(nil, children + [node])
37
42
  end
38
43
  end
39
44
 
@@ -58,6 +63,11 @@ module ATP
58
63
  updated(nil, children + nodes)
59
64
  end
60
65
 
66
+ # Remove the given nodes from the children
67
+ def remove(*nodes)
68
+ updated(nil, children - nodes)
69
+ end
70
+
61
71
  # Returns the first child node of the given type that is found
62
72
  def find(type)
63
73
  children.find { |c| c.try(:type) == type }
@@ -7,10 +7,12 @@ module ATP
7
7
  attr_reader :raw
8
8
  attr_accessor :id
9
9
 
10
- def initialize(program, name = nil)
10
+ def initialize(program, name = nil, options = {})
11
+ name, options = nil, name if name.is_a?(Hash)
12
+ extract_meta!(options)
11
13
  @program = program
12
14
  @name = name
13
- @raw = builder.flow
15
+ @raw = builder.flow(name)
14
16
  end
15
17
 
16
18
  # @api private
@@ -49,6 +51,7 @@ module ATP
49
51
  def group(name, options = {})
50
52
  open_groups.push([])
51
53
  yield
54
+ extract_meta!(options)
52
55
  append builder.group(name, open_groups.pop, options)
53
56
  end
54
57
 
@@ -268,9 +271,9 @@ module ATP
268
271
  end
269
272
 
270
273
  def extract_meta!(options)
271
- builder.source_file = options.delete(:source_file) if options[:source_file]
272
- builder.source_line_number = options.delete(:source_line_number) if options[:source_line_number]
273
- builder.description = options.delete(:description) if options[:description]
274
+ builder.source_file = options.delete(:source_file)
275
+ builder.source_line_number = options.delete(:source_line_number)
276
+ builder.description = options.delete(:description)
274
277
  end
275
278
 
276
279
  # For testing
@@ -21,8 +21,13 @@ module ATP
21
21
  else
22
22
  str += 'PASS'.ljust(9)
23
23
  end
24
- str += "#{node.find(:name).value}".ljust(55)
25
- str += "#{node.find(:object).value}".ljust(55)
24
+ if n = node.find(:name)
25
+ name = n.value
26
+ else
27
+ name = node.find(:object).value['Test']
28
+ end
29
+ str += "#{name}".ljust(55)
30
+ str += "#{node.find(:object).value['Test']}".ljust(55)
26
31
  str += "#{node.find(:id).value}"
27
32
  puts str
28
33
  end
@@ -4,20 +4,41 @@ module ATP
4
4
  class AddIDs < Processor
5
5
  def run(node)
6
6
  @i = 0
7
+ @existing_ids = []
8
+ @add_ids = false
9
+ # First collect all existing IDs, this is required to make sure
10
+ # that a generated ID does not clash with an existing one
11
+ process(node)
12
+ # Now run again to fill in the blanks
13
+ @add_ids = true
7
14
  process(node)
8
15
  end
9
16
 
10
17
  def on_test(node)
11
- @i += 1
12
- node = node.ensure_node_present(:id)
13
- node.updated(nil, process_all(node))
18
+ if @add_ids
19
+ node = node.ensure_node_present(:id)
20
+ node.updated(nil, process_all(node))
21
+ else
22
+ if id = node.find(:id)
23
+ @existing_ids << id.value
24
+ end
25
+ process_all(node)
26
+ end
14
27
  end
15
28
 
16
29
  def on_id(node)
17
- unless node.value
18
- node.updated(nil, ["t#{@i}"])
30
+ if @add_ids
31
+ unless node.value
32
+ node.updated(nil, [next_id])
33
+ end
19
34
  end
20
35
  end
36
+
37
+ def next_id
38
+ @i += 1
39
+ @i += 1 while @existing_ids.include?("t#{@i}")
40
+ "t#{@i}"
41
+ end
21
42
  end
22
43
  end
23
44
  end
@@ -0,0 +1,22 @@
1
+ module ATP
2
+ module Processors
3
+ # Makes sure every test node has an on_fail/set_result node,
4
+ class AddSetResult < Processor
5
+ def run(node)
6
+ process(node)
7
+ end
8
+
9
+ def on_test(node)
10
+ node = node.ensure_node_present(:on_fail)
11
+ node.updated(nil, process_all(node))
12
+ end
13
+
14
+ def on_on_fail(node)
15
+ unless node.find(:continue)
16
+ node = node.ensure_node_present(:set_result, 'fail')
17
+ end
18
+ node.updated(nil, process_all(node))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -7,14 +7,16 @@ module ATP
7
7
  # For example this AST:
8
8
  #
9
9
  # (flow
10
- # (group "g1"
10
+ # (group
11
+ # (name "g1")
11
12
  # (test
12
13
  # (name "test1"))
13
14
  # (flow-flag "bitmap" true
14
15
  # (test
15
16
  # (name "test2"))))
16
17
  # (flow-flag "bitmap" true
17
- # (group "g1"
18
+ # (group
19
+ # (name "g1")
18
20
  # (flow-flag "x" true
19
21
  # (test
20
22
  # (name "test3")))
@@ -26,7 +28,8 @@ module ATP
26
28
  # Will be optimized to this:
27
29
  #
28
30
  # (flow
29
- # (group "g1"
31
+ # (group
32
+ # (name "g1")
30
33
  # (test
31
34
  # (name "test1"))
32
35
  # (flow-flag "bitmap" true
@@ -66,7 +69,7 @@ module ATP
66
69
  name = children.shift
67
70
  state = children.shift
68
71
  remove_condition << node
69
- children = optimize_siblings(n(:temp, children))
72
+ children = extract_common_embedded_conditions(n(:temp, children))
70
73
  remove_condition.pop
71
74
  if condition_to_be_removed?(node)
72
75
  process_all(children)
@@ -79,11 +82,11 @@ module ATP
79
82
  alias_method :on_test_executed, :on_boolean_condition
80
83
  alias_method :on_job, :on_boolean_condition
81
84
 
82
- def on_condition(node)
85
+ def on_group(node)
83
86
  children = node.children.dup
84
87
  name = children.shift
85
88
  remove_condition << node
86
- children = optimize_siblings(n(:temp, children))
89
+ children = extract_common_embedded_conditions(n(:temp, children))
87
90
  remove_condition.pop
88
91
  if condition_to_be_removed?(node)
89
92
  process_all(children)
@@ -91,7 +94,6 @@ module ATP
91
94
  node.updated(nil, [name] + process_all(children))
92
95
  end
93
96
  end
94
- alias_method :on_group, :on_condition
95
97
 
96
98
  # Returns true if the given node contains the given condition within
97
99
  # its immediate children
@@ -122,58 +124,9 @@ module ATP
122
124
  end
123
125
 
124
126
  def on_flow(node)
125
- # The extract_common_embedded_conditions method can probably do the whole job,
126
- # but it might get a little complicated with regards to optimizing adjacent groups,
127
- # so have left the original logic to have the first crack and deal with the groups
128
- # for now.
129
- nodes = optimize_siblings(node)
127
+ name, *nodes = *node
130
128
  nodes = extract_common_embedded_conditions(nodes)
131
- node.updated(nil, nodes)
132
- end
133
-
134
- def on_members(node)
135
- node.updated(nil, extract_common_embedded_conditions(optimize_siblings(node)))
136
- end
137
-
138
- def optimize_siblings(top_node)
139
- children = []
140
- unprocessed_children = []
141
- current = nil
142
- last = top_node.children.size - 1
143
- top_node.to_a.each_with_index do |node, i|
144
- # If a condition has been identified in a previous node
145
- if current
146
- process_nodes = false
147
- # If this node has the current condition, then buffer it for later processing
148
- # and continue to the next node
149
- if has_condition?(current, node)
150
- unprocessed_children << node
151
- node = nil
152
- else
153
- process_nodes = true
154
- end
155
- if process_nodes || i == last
156
- remove_condition << current
157
- current_children = current.children + [process_all(unprocessed_children)].flatten
158
- unprocessed_children = []
159
- remove_condition.pop
160
- children << process(current.updated(nil, current_children))
161
- if node && (!condition?(node) || i == last)
162
- current = nil
163
- children << process(node)
164
- else
165
- current = node
166
- end
167
- end
168
- else
169
- if condition?(node) && i != last
170
- current = node
171
- else
172
- children << process(node)
173
- end
174
- end
175
- end
176
- children.flatten
129
+ node.updated(nil, [name] + nodes)
177
130
  end
178
131
 
179
132
  def extract_common_embedded_conditions(nodes)
@@ -23,18 +23,17 @@ module ATP
23
23
  alias_method :on_test_executed, :on_boolean_condition
24
24
  alias_method :on_job, :on_boolean_condition
25
25
 
26
- def on_condition(node)
26
+ def on_group(node)
27
+ sig = node.children.select { |n| [:id, :name, :on_fail, :on_pass].include?(n.try(:type)) }
27
28
  children = node.children.dup
28
- name = children.shift
29
- conditions << node.updated(nil, [name])
30
- process_all(children)
29
+ conditions << node.updated(nil, sig)
30
+ process_all(children - sig)
31
31
  conditions.pop
32
32
  end
33
33
 
34
34
  def on_test(node)
35
35
  results << [conditions.uniq, node]
36
36
  end
37
- alias_method :on_group, :on_test
38
37
  alias_method :on_log, :on_test
39
38
  alias_method :on_enable_flow_flag, :on_test
40
39
  alias_method :on_disable_flow_flag, :on_test
@@ -3,10 +3,12 @@ module ATP
3
3
  # Makes the AST safe for Marshaling
4
4
  class Marshal < Processor
5
5
  def on_object(node)
6
- if node.value.is_a?(String)
7
- node
6
+ if node.value.is_a?(String) || node.value.is_a?(Hash)
7
+ node.updated(nil, [{ 'Test' => node.value }])
8
+ elsif node.value.respond_to?(:to_meta)
9
+ node.updated(nil, [node.value.to_meta])
8
10
  else
9
- node.updated(nil, [node.value.name])
11
+ node.updated(nil, [{ 'Test' => node.value.name }])
10
12
  end
11
13
  end
12
14
  end
@@ -10,8 +10,8 @@ module ATP
10
10
  p
11
11
  end
12
12
 
13
- def flow(name)
14
- flows[name] ||= Flow.new(self, name)
13
+ def flow(name, options = {})
14
+ flows[name] ||= Flow.new(self, name, options)
15
15
  end
16
16
 
17
17
  def flows
@@ -5,32 +5,70 @@ module ATP
5
5
  # be hit when the flow is executed under the given conditions.
6
6
  class Runner < Processor
7
7
  def run(node, options = {})
8
+ options = {
9
+ evaluate_flow_flags: true,
10
+ evaluate_run_flags: true,
11
+ evaluate_set_result: true
12
+ }.merge(options)
8
13
  @options = options
9
14
  @completed = false
10
15
  @groups = []
11
- process(Processors::AddIDs.new.run(node))
16
+ @groups_on_fail = []
17
+ @groups_on_pass = []
18
+ node = Processors::AddIDs.new.run(node)
19
+ node = Processors::AddSetResult.new.run(node)
20
+ process(node)
12
21
  end
13
22
 
14
23
  def on_flow(node)
15
- @flow = []
16
- process_all(node.children)
17
- node.updated(nil, @flow)
24
+ c = open_container do
25
+ process_all(node.children)
26
+ end
27
+ node.updated(nil, c)
28
+ end
29
+
30
+ def on_name(node)
31
+ container << node
18
32
  end
19
33
 
20
34
  def on_flow_flag(node)
21
- flag, enabled, *nodes = *node
22
- flag = [flag].flatten
23
- active = flag.any? { |f| flow_flags.include?(f) }
24
- if (enabled && active) || (!enabled && !active)
25
- process_all(nodes)
35
+ if @options[:evaluate_flow_flags]
36
+ flag, enabled, *nodes = *node
37
+ flag = [flag].flatten
38
+ active = flag.any? { |f| flow_flags.include?(f) }
39
+ if (enabled && active) || (!enabled && !active)
40
+ process_all(nodes)
41
+ end
42
+ else
43
+ c = open_container do
44
+ process_all(node.children)
45
+ end
46
+ container << node.updated(nil, node.children.take(2) + c)
26
47
  end
27
48
  end
28
49
 
29
50
  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)
51
+ if @options[:evaluate_run_flags]
52
+ flag, enabled, *nodes = *node
53
+ flag = [flag].flatten
54
+ active = flag.any? { |f| run_flags.include?(f) }
55
+ if (enabled && active) || (!enabled && !active)
56
+ process_all(nodes)
57
+ end
58
+ else
59
+ c = open_container do
60
+ process_all(node.children)
61
+ end
62
+ container << node.updated(nil, node.children.take(2) + c)
63
+ end
64
+ end
65
+
66
+ # Not sure why this method is here, all test_result nodes should have been
67
+ # converted to run_flag nodes by now
68
+ def on_test_result(node)
69
+ id, passed, *nodes = *node
70
+ if (passed && !failed_test_ids.include?(id)) ||
71
+ (!passed && failed_test_ids.include?(id))
34
72
  process_all(nodes)
35
73
  end
36
74
  end
@@ -43,7 +81,19 @@ module ATP
43
81
  failed = true
44
82
  end
45
83
  end
46
- @flow << node unless completed?
84
+ # If there is a group on_fail, then remove any test specific one as that
85
+ # will be overridden
86
+ if @groups_on_fail.last
87
+ if n_on_fail = node.find(:on_fail)
88
+ node = node.remove(n_on_fail)
89
+ end
90
+ end
91
+ if @groups_on_pass.last
92
+ if n_on_pass = node.find(:on_pass)
93
+ node = node.remove(n_on_pass)
94
+ end
95
+ end
96
+ container << node unless completed?
47
97
  if failed
48
98
  # Give indication to the parent group that at least one test within it failed
49
99
  if @groups.last
@@ -51,9 +101,11 @@ module ATP
51
101
  @groups << false
52
102
  end
53
103
  if n = node.find(:on_fail)
54
- @continue = !!n.find(:continue)
104
+ # If it has been set by a parent group, don't clear it
105
+ orig = @continue
106
+ @continue ||= !!n.find(:continue)
55
107
  process_all(n)
56
- @continue = false
108
+ @continue = orig
57
109
  end
58
110
  else
59
111
  if n = node.find(:on_pass)
@@ -63,37 +115,41 @@ module ATP
63
115
  end
64
116
 
65
117
  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
118
+ on_fail = node.find(:on_fail)
119
+ on_pass = node.find(:on_pass)
120
+ c = open_container do
121
+ @groups << true # This will be set to false by any tests that fail within the group
122
+ @groups_on_fail << on_fail
123
+ @groups_on_pass << on_pass
124
+ if on_fail
125
+ orig = @continue
126
+ @continue = !!on_fail.find(:continue)
127
+ process_all(node.children - [on_fail, on_pass])
128
+ @continue = orig
129
+ else
130
+ process_all(node.children - [on_fail, on_pass])
73
131
  end
74
- else
75
- if n = node.find(:on_pass)
76
- process_all(n)
132
+ if !@groups.pop # If failed
133
+ if on_fail
134
+ @continue = !!on_fail.find(:continue)
135
+ process_all(on_fail)
136
+ @continue = false
137
+ end
138
+ else
139
+ if on_pass
140
+ process_all(on_pass)
141
+ end
77
142
  end
143
+ @groups_on_fail.pop
144
+ @groups_on_pass.pop
78
145
  end
79
- end
80
-
81
- def on_members(node)
82
- # Do nothing, will be processed directly by the on_group handler
83
- end
84
-
85
- def on_test_result(node)
86
- id, passed, *nodes = *node
87
- if (passed && !failed_test_ids.include?(id)) ||
88
- (!passed && failed_test_ids.include?(id))
89
- process_all(nodes)
90
- end
146
+ container << node.updated(nil, c + [on_fail, on_pass])
91
147
  end
92
148
 
93
149
  def on_set_result(node)
94
150
  unless @continue
95
- @flow << node unless completed?
96
- @completed = true
151
+ container << node unless completed?
152
+ @completed = true if @options[:evaluate_set_result]
97
153
  end
98
154
  end
99
155
 
@@ -110,7 +166,7 @@ module ATP
110
166
  end
111
167
 
112
168
  def on_log(node)
113
- @flow << node unless completed?
169
+ container << node unless completed?
114
170
  end
115
171
  alias_method :on_render, :on_log
116
172
 
@@ -151,5 +207,16 @@ module ATP
151
207
  def completed?
152
208
  @completed
153
209
  end
210
+
211
+ def open_container(c = [])
212
+ @containers ||= []
213
+ @containers << c
214
+ yield
215
+ @containers.pop
216
+ end
217
+
218
+ def container
219
+ @containers.last
220
+ end
154
221
  end
155
222
  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.3.3
4
+ version: 0.4.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-02-11 00:00:00.000000000 Z
11
+ date: 2016-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -75,6 +75,7 @@ files:
75
75
  - lib/atp/parser.rb
76
76
  - lib/atp/processor.rb
77
77
  - lib/atp/processors/add_ids.rb
78
+ - lib/atp/processors/add_set_result.rb
78
79
  - lib/atp/processors/condition.rb
79
80
  - lib/atp/processors/condition_extractor.rb
80
81
  - lib/atp/processors/flow_id.rb