atp 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ module ATP
2
+ module Processors
3
+ # Runs at the very end of a processor run, to do some final cleanup,
4
+ # e.g. to assign generated IDs to tests that don't have one
5
+ class PostCleaner < Processor
6
+ # Returns a hash containing the IDs of all tests that have
7
+ # been used
8
+ attr_reader :ids
9
+
10
+ # Extracts all ID values of tests within the given AST
11
+ class ExtractTestIDs < Processor
12
+ attr_reader :results
13
+
14
+ def on_test(node)
15
+ id = node.children.find { |n| n.type == :id }
16
+ if id
17
+ @results ||= {}
18
+ @results[id] = true
19
+ end
20
+ end
21
+ end
22
+
23
+ def process(node)
24
+ # On first call extract the test_result nodes from the given AST,
25
+ # then process as normal thereafter
26
+ if @first_call_done
27
+ result = super
28
+ else
29
+ @first_call_done = true
30
+ t = ExtractTestIDs.new
31
+ t.process(node)
32
+ @ids = t.results || {}
33
+ result = super
34
+ @first_call_done = false
35
+ end
36
+ result
37
+ end
38
+
39
+ def on_test(node)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ module ATP
2
+ module Processors
3
+ # Modifies the AST by performing some basic clean up, mainly to sanitize
4
+ # user input. For example it will ensure that all IDs are symbols, and that
5
+ # all names are lower-cased strings.
6
+ class PreCleaner < Processor
7
+ def initialize
8
+ @group_ids = []
9
+ end
10
+
11
+ def on_id(node)
12
+ id = node.to_a.first
13
+ id = id.to_s.downcase.to_sym
14
+ node.updated(nil, [id])
15
+ end
16
+
17
+ def on_group(node)
18
+ if id = node.children.find { |n| n.type == :id }
19
+ @group_ids << process(id).value
20
+ else
21
+ @group_ids << nil
22
+ end
23
+ group = node.updated(nil, process_all(node.children))
24
+ @group_ids.pop
25
+ group
26
+ end
27
+
28
+ def on_test(node)
29
+ # Remove IDs nodes from test nodes if they refer to the ID of a parent group
30
+ if @group_ids.last
31
+ children = node.children.reject do |n|
32
+ if n.type == :id
33
+ @group_ids.last == process(n).value
34
+ end
35
+ end
36
+ else
37
+ children = node.children
38
+ end
39
+ node.updated(nil, process_all(children))
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,154 @@
1
+ module ATP
2
+ module Processors
3
+ # This processor will apply the relationships between tests, e.g. if testB should only
4
+ # execute if testA passes, then this processor will update the AST to make testA set
5
+ # a flag on pass, and then update testB to only run if that flag is set.
6
+ class Relationship < Processor
7
+ # Returns a hash containing the IDs of all tests that have dependents
8
+ attr_reader :test_results
9
+
10
+ # Extracts all test-result nodes from the given AST
11
+ class ExtractTestResults < Processor
12
+ attr_reader :results
13
+
14
+ def on_test_result(node)
15
+ ids, state, *children = *node
16
+ unless ids.is_a?(Array)
17
+ ids = [ids]
18
+ end
19
+ ids.each do |id|
20
+ results[id] ||= {}
21
+ if state
22
+ results[id][:passed] = true
23
+ else
24
+ results[id][:failed] = true
25
+ end
26
+ end
27
+ process_all(children)
28
+ end
29
+
30
+ def on_test_executed(node)
31
+ id, state, *children = *node
32
+ id, state = *node
33
+ results[id] ||= {}
34
+ results[id][:executed] = true
35
+ process_all(children)
36
+ end
37
+
38
+ def results
39
+ @results ||= {}.with_indifferent_access
40
+ end
41
+ end
42
+
43
+ def process(node)
44
+ # On first call extract the test_result nodes from the given AST,
45
+ # then process as normal thereafter
46
+ if @first_call_done
47
+ result = super
48
+ else
49
+ @first_call_done = true
50
+ t = ExtractTestResults.new
51
+ t.process(node)
52
+ @test_results = t.results || {}
53
+ result = super
54
+ @first_call_done = false
55
+ end
56
+ result
57
+ end
58
+
59
+ def add_pass_flag(id, node)
60
+ node = node.ensure_node_present(:on_pass)
61
+ node = node.ensure_node_present(:on_fail)
62
+ node.updated(nil, node.children.map do |n|
63
+ if n.type == :on_pass
64
+ n = n.add n1(:set_run_flag, "#{id}_PASSED")
65
+ elsif n.type == :on_fail
66
+ n.ensure_node_present(:continue)
67
+ else
68
+ n
69
+ end
70
+ end)
71
+ end
72
+
73
+ def add_fail_flag(id, node)
74
+ node = node.ensure_node_present(:on_fail)
75
+ node.updated(nil, node.children.map do |n|
76
+ if n.type == :on_fail
77
+ n = n.add n1(:set_run_flag, "#{id}_FAILED")
78
+ n.ensure_node_present(:continue)
79
+ else
80
+ n
81
+ end
82
+ end)
83
+ end
84
+
85
+ def add_executed_flag(id, node)
86
+ node = node.ensure_node_present(:on_fail)
87
+ node = node.ensure_node_present(:on_pass)
88
+ node.updated(nil, node.children.map do |n|
89
+ if n.type == :on_pass || n.type == :on_fail
90
+ n = n.add n1(:set_run_flag, "#{id}_RAN")
91
+ else
92
+ n
93
+ end
94
+ end)
95
+ end
96
+
97
+ # Set flags depending on the result on tests which have dependents later
98
+ # in the flow
99
+ def on_test(node)
100
+ nid = id(node)
101
+ # If this test has a dependent
102
+ if test_results[nid]
103
+ node = add_pass_flag(nid, node) if test_results[nid][:passed]
104
+ node = add_fail_flag(nid, node) if test_results[nid][:failed]
105
+ node = add_executed_flag(nid, node) if test_results[nid][:executed]
106
+ end
107
+ if node.type == :group
108
+ node.updated(nil, process_all(node))
109
+ else
110
+ node
111
+ end
112
+ end
113
+ alias_method :on_group, :on_test
114
+
115
+ # Remove test_result nodes and replace with references to the flags set
116
+ # up stream by the parent node
117
+ def on_test_result(node)
118
+ children = node.children.dup
119
+ id = children.shift
120
+ state = children.shift
121
+ if state
122
+ n(:run_flag, [id_to_flag(id, 'PASSED'), true] + process_all(children))
123
+ else
124
+ n(:run_flag, [id_to_flag(id, 'FAILED'), true] + process_all(children))
125
+ end
126
+ end
127
+
128
+ # Remove test_result nodes and replace with references to the flags set
129
+ # up stream by the parent node
130
+ def on_test_executed(node)
131
+ children = node.children.dup
132
+ id = children.shift
133
+ state = children.shift
134
+ n(:run_flag, [id_to_flag(id, 'RAN'), state] + children)
135
+ end
136
+
137
+ # Returns the ID of the give test node (if any), caller is responsible
138
+ # for only passing test nodes
139
+ def id(node)
140
+ if n = node.children.find { |c| c.type == :id }
141
+ n.children.first
142
+ end
143
+ end
144
+
145
+ def id_to_flag(id, type)
146
+ if id.is_a?(Array)
147
+ id.map { |i| "#{i}_#{type}" }
148
+ else
149
+ "#{id}_#{type}"
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,27 @@
1
+ module ATP
2
+ # Program is the top-level container for a collection of test flows
3
+ class Program
4
+ def flow(name)
5
+ flows[name] ||= Flow.new(self)
6
+ end
7
+
8
+ def flows
9
+ @flows ||= {}
10
+ end
11
+
12
+ def respond_to?(*args)
13
+ flows.key?(args.first) || super
14
+ end
15
+
16
+ def method_missing(method, *args, &block) # :nodoc:
17
+ if f = flows[method]
18
+ define_singleton_method method do
19
+ f
20
+ end
21
+ f
22
+ else
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/atp/runner.rb ADDED
@@ -0,0 +1,53 @@
1
+ module ATP
2
+ # This class is responsible for executing the given test flow based on a given
3
+ # set of runtime conditions.
4
+ # A subset of the input AST will be returned containing only the nodes that would
5
+ # be hit when the flow is executed under the given conditions.
6
+ class Runner < Processor
7
+ def run(node, options = {})
8
+ @options = options
9
+ process(node)
10
+ end
11
+
12
+ def on_flow(node)
13
+ @flow = []
14
+ process_all(node.children)
15
+ node.updated(nil, @flow)
16
+ end
17
+
18
+ def on_flow_flag(node)
19
+ flag, enabled, *nodes = *node
20
+ if (enabled && flow_flags.include?(flag)) ||
21
+ (!enabled && !flow_flags.include?(flag))
22
+ process_all(nodes)
23
+ end
24
+ end
25
+
26
+ def on_test(node)
27
+ if id = node.find(:id)
28
+ id = id.to_a[0]
29
+ if failed_test_ids.include?(id)
30
+ node = node.add(n0(:failed))
31
+ end
32
+ end
33
+ @flow << node
34
+ end
35
+
36
+ def on_test_result(node)
37
+ id, passed, *nodes = *node
38
+ if (passed && !failed_test_ids.include?(id)) ||
39
+ (!passed && failed_test_ids.include?(id))
40
+ process_all(nodes)
41
+ end
42
+ end
43
+
44
+ def failed_test_ids
45
+ @failed_test_ids ||= [@options[:failed_test_id] || @options[:failed_test_ids]].flatten.compact
46
+ end
47
+
48
+ # Returns an array of enabled flow flags
49
+ def flow_flags
50
+ @flow_flags ||= [@options[:flow_flag] || @options[:flow_flags]].flatten.compact
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,4 @@
1
+ module ATP
2
+ module Validators
3
+ end
4
+ 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.1.0
4
+ version: 0.2.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: 2015-07-07 00:00:00.000000000 Z
11
+ date: 2016-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.6
19
+ version: 0.2.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.6
26
+ version: 0.2.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: ast
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sexpistol
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.0'
27
55
  description:
28
56
  email:
29
57
  - stephen.f.mcginty@gmail.com
@@ -32,13 +60,30 @@ extensions: []
32
60
  extra_rdoc_files: []
33
61
  files:
34
62
  - config/application.rb
63
+ - config/boot.rb
35
64
  - config/commands.rb
36
- - config/development.rb
37
- - config/environment.rb
38
- - config/users.rb
39
65
  - config/version.rb
40
66
  - lib/atp.rb
41
- - lib/atp/top_level.rb
67
+ - lib/atp/and.rb
68
+ - lib/atp/ast/builder.rb
69
+ - lib/atp/ast/extractor.rb
70
+ - lib/atp/ast/factories.rb
71
+ - lib/atp/ast/node.rb
72
+ - lib/atp/flow.rb
73
+ - lib/atp/formatter.rb
74
+ - lib/atp/formatters/basic.rb
75
+ - lib/atp/formatters/datalog.rb
76
+ - lib/atp/not.rb
77
+ - lib/atp/or.rb
78
+ - lib/atp/parser.rb
79
+ - lib/atp/processor.rb
80
+ - lib/atp/processors/condition.rb
81
+ - lib/atp/processors/post_cleaner.rb
82
+ - lib/atp/processors/pre_cleaner.rb
83
+ - lib/atp/processors/relationship.rb
84
+ - lib/atp/program.rb
85
+ - lib/atp/runner.rb
86
+ - lib/atp/validators/condition.rb
42
87
  - lib/tasks/atp.rake
43
88
  - templates/web/archive.md.erb
44
89
  - templates/web/contact.md.erb
@@ -46,7 +91,7 @@ files:
46
91
  - templates/web/layouts/_basic.html.erb
47
92
  - templates/web/partials/_navbar.html.erb
48
93
  - templates/web/release_notes.md.erb
49
- homepage: http://origen.freescale.net/atp
94
+ homepage: http://origen-sdk.org/atp
50
95
  licenses: []
51
96
  metadata: {}
52
97
  post_install_message:
@@ -65,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
110
  version: 1.8.11
66
111
  requirements: []
67
112
  rubyforge_project:
68
- rubygems_version: 2.4.8
113
+ rubygems_version: 2.2.2
69
114
  signing_key:
70
115
  specification_version: 4
71
116
  summary: An abstract test program model for Origen
@@ -1,12 +0,0 @@
1
- # This file is similar to environment.rb and will be loaded
2
- # automatically at the start of each invocation of Origen.
3
- #
4
- # However the major difference is that it will not be loaded
5
- # if the application is imported by a 3rd party app - in that
6
- # case only environment.rb is loaded.
7
- #
8
- # Therefore this file should be used to load anything you need
9
- # to setup a development environment for this app, normally
10
- # this would be used to load some dummy classes to instantiate
11
- # your objects so that they can be tested and/or interacted with
12
- # in the console.