origen_testers 0.53.0 → 0.54.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
  SHA256:
3
- metadata.gz: bd70a31c286817288ecefd2da59f6e353a7352e68b7fda835d003863bb31b335
4
- data.tar.gz: 15a7415efb5843bf6de77749d322fe58d83c90ed7d6f33a55493b720602f53b1
3
+ metadata.gz: 38a51e599ac6dfccc090e03554f2931094af5834be2b72a9ea64a3a1b3f5f013
4
+ data.tar.gz: d0355b74097a788f4f9255f02d795f676e31c63698b13d2e03e3abb322e89d91
5
5
  SHA512:
6
- metadata.gz: b63efbe6a34c23da197eb95b35631b37fe143b4a998c391a920acf6edd664eff512de5241915cd491578ae869f8d721bd7be4be4e51580037e5a0a7b83e5862a
7
- data.tar.gz: 9992f1ee5387bcef67571ae85b59aedb20578d98fa7218f7c36a1281e35aba80571288d861405ae3f2936b2d6f4f7f1e64c405ce75feeec2295936c152097c67
6
+ metadata.gz: 7132a0000a8fff568498a299ac9e5de0cf9258be9fd5a3a5c0980a11ff89e6f0ddb9af44270016c876da8d6ae085e844b018f95d140ed8e986ab1f7a4ca94d3c
7
+ data.tar.gz: 239b6fc0eedaf76e12115c3cb541f3a079f863a5740c72ad7b72efff3801b8deaedd8ccb1352e8c34f3ff8a8eaa074215b72e46c29cca8290b89fd6cbf96812d
data/config/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
- MINOR = 53
3
+ MINOR = 54
4
4
  BUGFIX = 0
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -203,23 +203,16 @@ module OrigenTesters
203
203
  alias_method :signature, :sig
204
204
 
205
205
  def active_description
206
- flow_file = OrigenTesters::Flow.callstack.last
207
- called_from = caller.find { |l| l =~ /^#{flow_file}:.*/ }
208
- # Windows fix - prevent the drive letter in the file name from changing the index of the line_no below
209
- called_from.gsub!(flow_file, '')
206
+ line_no = active_flow_source_line
210
207
  desc = nil
211
- if called_from
212
- called_from = called_from.split(':')
213
- line_no = called_from[1].to_i
208
+ if line_no
214
209
  ht_coms = OrigenTesters::Flow.ht_comments
215
210
  cc_coms = OrigenTesters::Flow.cc_comments
216
- if line_no
217
- if ht_coms[line_no]
218
- desc = ht_coms[line_no].join(' ')
219
- end
220
- if cc_coms[line_no] && cc_coms[line_no].first
221
- desc = [cc_coms[line_no].shift].join(' ')
222
- end
211
+ if ht_coms[line_no]
212
+ desc = ht_coms[line_no].join(' ')
213
+ end
214
+ if cc_coms[line_no] && cc_coms[line_no].first
215
+ desc = [cc_coms[line_no].shift].join(' ')
223
216
  end
224
217
  end
225
218
  desc
@@ -256,14 +249,23 @@ module OrigenTesters
256
249
  # to the generated node
257
250
  def add_meta!(options)
258
251
  flow_file = OrigenTesters::Flow.callstack.last
259
- called_from = caller.find { |l| l =~ /^#{flow_file}:.*/ }
260
- if called_from
261
- # Splitting on ':' when file names are included will yield a different index for everything in Windows
262
- called_from.gsub!(flow_file, '')
263
- called_from = called_from.split(':')
264
- options[:source_file] = flow_file # called_from[0]
265
- options[:source_line_number] = called_from[1].to_i
252
+ if line_no = active_flow_source_line
253
+ options[:source_file] = flow_file
254
+ options[:source_line_number] = line_no
255
+ end
256
+ end
257
+
258
+ # Find the application flow frame without materializing and parsing the full
259
+ # caller stack as strings. This runs for every generated flow node.
260
+ def active_flow_source_line
261
+ flow_file = OrigenTesters::Flow.callstack.last
262
+ return unless flow_file
263
+
264
+ flow_file = flow_file.to_s
265
+ location = caller_locations.find do |frame|
266
+ frame.path == flow_file || frame.absolute_path == flow_file
266
267
  end
268
+ location.lineno if location
267
269
  end
268
270
 
269
271
  # This gets called by ATP for all flow generation methods to add the description information
@@ -33,6 +33,14 @@ module OrigenTesters
33
33
  tester.smt8?
34
34
  end
35
35
 
36
+ def qualified_name
37
+ @qualified_name ||= if parent
38
+ "#{parent.qualified_name}.#{name}"
39
+ else
40
+ name.to_s
41
+ end
42
+ end
43
+
36
44
  def var_filename # rubocop:disable Lint/DuplicateMethods
37
45
  @var_filename || 'global'
38
46
  end
@@ -4,6 +4,22 @@ module OrigenTesters
4
4
  class TestMethod
5
5
  FORMAT_TYPES = [:current, :voltage, :time, :frequency, :string, :integer, :double, :boolean, :class, :list_strings, :list_classes]
6
6
 
7
+ def self.parameter_sort_keys
8
+ @@parameter_sort_keys ||= {}
9
+ end
10
+
11
+ def self.installed_dynamic_methods
12
+ @installed_dynamic_methods ||= {}
13
+ end
14
+
15
+ def self.underscored_parameter_names
16
+ @@underscored_parameter_names ||= {}
17
+ end
18
+
19
+ def self.underscore_parameter_name(name)
20
+ underscored_parameter_names[name] ||= name.underscore
21
+ end
22
+
7
23
  # Returns the object representing the test method library that the
8
24
  # given test method is defined in
9
25
  attr_reader :library
@@ -38,8 +54,11 @@ module OrigenTesters
38
54
  unless method_name == :finalize
39
55
  var_name = "@#{method_name}".gsub(/=|\?/, '_')
40
56
  instance_variable_set(var_name, function)
41
- define_singleton_method method_name do |*args|
42
- instance_variable_get(var_name).call(self, *args)
57
+ unless self.class.installed_dynamic_methods[method_name]
58
+ self.class.send(:define_method, method_name) do |*args|
59
+ instance_variable_get(var_name).call(self, *args)
60
+ end
61
+ self.class.installed_dynamic_methods[method_name] = true
43
62
  end
44
63
  end
45
64
  end
@@ -54,19 +73,28 @@ module OrigenTesters
54
73
  allowed = type_default[2]
55
74
  @parameters[attr] = type
56
75
  aliases = [clean_attr]
57
- aliases << clean_attr.underscore if clean_attr.underscore != clean_attr
76
+ underscored_attr = self.class.underscore_parameter_name(clean_attr)
77
+ aliases << underscored_attr if underscored_attr != clean_attr
58
78
  aliases.each do |alias_|
59
- define_singleton_method("#{alias_}=") do |v|
60
- v = v.to_s if v.is_a?(Symbol)
61
- if allowed
62
- unless allowed.include?(v)
63
- fail "Cannot set #{alias_} to #{v}, valid values are: #{allowed.join(', ')}"
79
+ setter = :"#{alias_}="
80
+ unless self.class.installed_dynamic_methods[setter]
81
+ self.class.send(:define_method, setter) do |v|
82
+ v = v.to_s if v.is_a?(Symbol)
83
+ if allowed
84
+ unless allowed.include?(v)
85
+ fail "Cannot set #{alias_} to #{v}, valid values are: #{allowed.join(', ')}"
86
+ end
64
87
  end
88
+ instance_variable_set("@#{clean_attr}", v)
65
89
  end
66
- instance_variable_set("@#{clean_attr}", v)
90
+ self.class.installed_dynamic_methods[setter] = true
67
91
  end
68
- define_singleton_method(alias_) do
69
- instance_variable_get("@#{clean_attr}")
92
+ alias_name = alias_.to_sym
93
+ unless self.class.installed_dynamic_methods[alias_name]
94
+ self.class.send(:define_method, alias_name) do
95
+ instance_variable_get("@#{clean_attr}")
96
+ end
97
+ self.class.installed_dynamic_methods[alias_name] = true
70
98
  end
71
99
  end
72
100
  send("#{clean_attr}=", default)
@@ -75,11 +103,19 @@ module OrigenTesters
75
103
  if options[:methods][:aliases]
76
104
  options[:methods][:aliases].each do |alias_, attr|
77
105
  clean_attr = clean_attr_name(attr)
78
- define_singleton_method("#{alias_}=") do |v|
79
- send("#{clean_attr}=", v)
106
+ setter = :"#{alias_}="
107
+ unless self.class.installed_dynamic_methods[setter]
108
+ self.class.send(:define_method, setter) do |v|
109
+ send("#{clean_attr}=", v)
110
+ end
111
+ self.class.installed_dynamic_methods[setter] = true
80
112
  end
81
- define_singleton_method(alias_) do
82
- send(clean_attr)
113
+ alias_name = alias_.to_sym
114
+ unless self.class.installed_dynamic_methods[alias_name]
115
+ self.class.send(:define_method, alias_name) do
116
+ send(clean_attr)
117
+ end
118
+ self.class.installed_dynamic_methods[alias_name] = true
83
119
  end
84
120
  end
85
121
  end
@@ -89,7 +125,7 @@ module OrigenTesters
89
125
  if respond_to?(accessor)
90
126
  send(accessor, v)
91
127
  else
92
- accessor = "#{k.to_s.underscore}="
128
+ accessor = "#{self.class.underscore_parameter_name(k.to_s)}="
93
129
  send(accessor, v) if respond_to?(accessor)
94
130
  end
95
131
  end
@@ -192,15 +228,13 @@ module OrigenTesters
192
228
 
193
229
  def sorted_parameters
194
230
  @parameters.sort_by do |name|
195
- if name.is_a?(String)
196
- name
197
- else
198
- if name.to_s[0] == '_'
199
- name.to_s.camelize(:upper)
200
- else
201
- name.to_s.camelize(:lower)
202
- end
203
- end
231
+ self.class.parameter_sort_keys[name] ||= if name.is_a?(String)
232
+ name
233
+ elsif name.to_s[0] == '_'
234
+ name.to_s.camelize(:upper)
235
+ else
236
+ name.to_s.camelize(:lower)
237
+ end
204
238
  end
205
239
  end
206
240
 
@@ -4,6 +4,10 @@ module OrigenTesters
4
4
  class TestMethods
5
5
  # Base class of all test method libraries
6
6
  class BaseTml
7
+ def self.test_method_classes
8
+ @test_method_classes ||= {}
9
+ end
10
+
7
11
  # Returns the test_methods object for the current flow
8
12
  attr_reader :test_methods
9
13
 
@@ -35,10 +39,20 @@ module OrigenTesters
35
39
  private
36
40
 
37
41
  def instantiate_test_method(method, args)
38
- m = platform::TestMethod.new methods: definitions[method].dup,
39
- attrs: (args.first || {}),
40
- type: method,
41
- library: self
42
+ definition = definitions[method]
43
+ base_class = platform::TestMethod
44
+ cache_key = [base_class, definition.object_id]
45
+ klass = BaseTml.test_method_classes[cache_key] ||= begin
46
+ generated_class = Class.new(base_class)
47
+ # Retain the definition so its object ID cannot be recycled while
48
+ # this generated class remains cached.
49
+ generated_class.instance_variable_set(:@test_method_definition, definition)
50
+ generated_class
51
+ end
52
+ m = klass.new methods: definition.dup,
53
+ attrs: (args.first || {}),
54
+ type: method,
55
+ library: self
42
56
  test_methods.add(m)
43
57
  m
44
58
  end
@@ -87,22 +87,23 @@ module OrigenTesters
87
87
  unless name.is_a?(String)
88
88
  name = name.to_s[0] == '_' ? name.to_s.camelize(:upper) : name.to_s.camelize(:lower)
89
89
  end
90
+ formatted_value = test_method.format(param.last.is_a?(Hash) ? name : param[0])
90
91
  if param.last.is_a? Hash
91
- if !test_method.format(name).nil? && !test_method.format(name).is_a?(Hash)
92
- fail "#{name} parameter structure requires a Hash but value provided is #{test_method.format(name).class}"
93
- elsif test_method.format(name).nil? && tester.print_all_params
92
+ if !formatted_value.nil? && !formatted_value.is_a?(Hash)
93
+ fail "#{name} parameter structure requires a Hash but value provided is #{formatted_value.class}"
94
+ elsif formatted_value.nil? && tester.print_all_params
94
95
  l = add_nested_params(l, name, 'param0', {}, param.last, 1)
95
- elsif test_method.format(name).nil?
96
+ elsif formatted_value.nil?
96
97
  # Do nothing
97
98
  else
98
- test_method.format(name).each do |key, meta_hash|
99
+ formatted_value.each do |key, meta_hash|
99
100
  l = add_nested_params(l, name, key, meta_hash, param.last, 1)
100
101
  end
101
102
  end
102
- elsif NO_STRING_TYPES.include?(param.last) && test_method.format(param[0]).is_a?(String) && !test_method.format(param[0]).empty?
103
- l << " #{name} = #{test_method.format(param[0])};"
103
+ elsif NO_STRING_TYPES.include?(param.last) && formatted_value.is_a?(String) && !formatted_value.empty?
104
+ l << " #{name} = #{formatted_value};"
104
105
  else
105
- l << " #{name} = #{wrap_if_string(test_method.format(param[0]))};"
106
+ l << " #{name} = #{wrap_if_string(formatted_value)};"
106
107
  end
107
108
  end
108
109
  l << '}'
@@ -111,8 +112,8 @@ module OrigenTesters
111
112
 
112
113
  # rubocop:disable Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters.
113
114
  def add_nested_params(l, name, key, value_hash, nested_params, nested_loop_count)
114
- nested_params_accepted_keys = []
115
- skip_keys = []
115
+ nested_params_accepted_keys = {}
116
+ skip_keys = {}
116
117
  unless value_hash.nil?
117
118
  unless value_hash.is_a?(Hash)
118
119
  fail "Provided value to nested params was not a Hash. Instead the value was #{value_hash.class}"
@@ -120,14 +121,16 @@ module OrigenTesters
120
121
 
121
122
  dynamic_spacing = ' ' * (4 * nested_loop_count)
122
123
  l << "#{dynamic_spacing}#{name}[#{key}] = {" unless name.nil?
124
+ # Normalize once per hash rather than once per accepted parameter.
125
+ value_hash = value_hash.transform_keys(&:to_sym)
126
+ @nested_parameter_keys ||= {}
123
127
  nested_params.each do |nested_param|
124
- # Guarentee hash is using all symbol keys
125
- # Since we cannot guarentee ruby version is greater than 2.5, we have to use an older syntax to
126
- value_hash = value_hash.transform_keys(&:to_sym)
127
- nested_key = nested_param.first.to_s.gsub('.', '_').to_sym
128
- nested_key_underscore = nested_key.to_s.underscore.to_sym
129
- nested_params_accepted_keys << nested_key
130
- nested_params_accepted_keys << nested_key_underscore
128
+ nested_key, nested_key_underscore = @nested_parameter_keys[nested_param.first] ||= begin
129
+ key_name = nested_param.first.to_s.gsub('.', '_').to_sym
130
+ [key_name, key_name.to_s.underscore.to_sym]
131
+ end
132
+ nested_params_accepted_keys[nested_key] = true
133
+ nested_params_accepted_keys[nested_key_underscore] = true
131
134
  # We cannot create nested member functions with aliases
132
135
  # Requirement for hash parameter passing is to pass one of the key types and not both
133
136
  if value_hash.keys.include?(nested_key) &&
@@ -139,26 +142,26 @@ module OrigenTesters
139
142
  if nested_param.last.first.is_a?(Hash) && value_hash[nested_key].is_a?(Hash)
140
143
  value_hash[nested_key].each do |inner_key, inner_meta_hash|
141
144
  l = add_nested_params(l, nested_param.first, inner_key, value_hash.dig(nested_key, inner_key), nested_param.last.first, nested_loop_count + 1)
142
- skip_keys << nested_key
145
+ skip_keys[nested_key] = true
143
146
  end
144
147
  elsif nested_param.last.first.is_a?(Hash) && tester.print_all_params
145
148
  l = add_nested_params(l, nested_param.first, 'param0', {}, nested_param.last.first, nested_loop_count + 1)
146
149
  end
147
150
  type = nested_param.last.first
148
- if NO_STRING_TYPES.include?(nested_param.last.first) && value_hash[nested_key] && !skip_keys.include?(nested_key)
151
+ if NO_STRING_TYPES.include?(nested_param.last.first) && value_hash[nested_key] && !skip_keys.key?(nested_key)
149
152
  l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(value_hash[nested_key], type, nested_param.first)};"
150
- elsif value_hash[nested_key] && !skip_keys.include?(nested_key)
153
+ elsif value_hash[nested_key] && !skip_keys.key?(nested_key)
151
154
  l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(value_hash[nested_key], type, nested_param.first))};"
152
- elsif NO_STRING_TYPES.include?(nested_param.last.first) && !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
155
+ elsif NO_STRING_TYPES.include?(nested_param.last.first) && !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.key?(nested_key)
153
156
  l << " #{dynamic_spacing}#{nested_param.first} = #{test_method.handle_val_type(nested_param.last.last, type, nested_param.first)};"
154
- elsif !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.include?(nested_key)
157
+ elsif !nested_param.last.last.is_a?(Hash) && tester.print_all_params && !skip_keys.key?(nested_key)
155
158
  l << " #{dynamic_spacing}#{nested_param.first} = #{wrap_if_string(test_method.handle_val_type(nested_param.last.last, type, nested_param.first))};"
156
159
  end
157
160
  end
158
161
  l << "#{dynamic_spacing}};" unless name.nil?
159
162
  # Sanity check there are not overpassed parameters
160
163
  value_hash.keys.each do |nested_key|
161
- unless nested_params_accepted_keys.include?(nested_key.to_sym)
164
+ unless nested_params_accepted_keys.key?(nested_key.to_sym)
162
165
  fail "You provided a parameter \'#{nested_key}\' that was not an accepted parameter to the hash parameter \'#{name}\'"
163
166
  end
164
167
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_testers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.53.0
4
+ version: 0.54.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  - Priyavadan Kumar
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 1980-01-02 00:00:00.000000000 Z
12
+ date: 2026-08-06 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: dentaku
@@ -156,6 +157,7 @@ dependencies:
156
157
  - - ">="
157
158
  - !ruby/object:Gem::Version
158
159
  version: '1.24'
160
+ description:
159
161
  email:
160
162
  - stephen.f.mcginty@gmail.com
161
163
  - priyavadan@gmail.com
@@ -591,6 +593,7 @@ files:
591
593
  homepage: http://origen-sdk.org/testers
592
594
  licenses: []
593
595
  metadata: {}
596
+ post_install_message:
594
597
  rdoc_options: []
595
598
  require_paths:
596
599
  - lib
@@ -605,7 +608,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
605
608
  - !ruby/object:Gem::Version
606
609
  version: '0'
607
610
  requirements: []
608
- rubygems_version: 4.0.3
611
+ rubygems_version: 3.2.3
612
+ signing_key:
609
613
  specification_version: 4
610
614
  summary: This plugin provides Origen tester models to drive ATE type testers like
611
615
  the J750, UltraFLEX, V93K,...