automation_object 0.7.6 → 0.8.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 +4 -4
- data/lib/automation_object/blue_print.rb +1 -0
- data/lib/automation_object/blue_print/composite/{automatic_onload_modal.rb → automatic_modal_change.rb} +3 -4
- data/lib/automation_object/blue_print/composite/base.rb +1 -0
- data/lib/automation_object/blue_print/composite/custom_method.rb +2 -3
- data/lib/automation_object/blue_print/composite/element.rb +2 -3
- data/lib/automation_object/blue_print/composite/element_array.rb +2 -3
- data/lib/automation_object/blue_print/composite/element_hash.rb +2 -3
- data/lib/automation_object/blue_print/composite/helpers/container_helper.rb +75 -0
- data/lib/automation_object/blue_print/composite/helpers/element_helper.rb +30 -1
- data/lib/automation_object/blue_print/composite/helpers/multiple_elements_helper.rb +1 -0
- data/lib/automation_object/blue_print/composite/hook.rb +18 -6
- data/lib/automation_object/blue_print/composite/hook_action.rb +3 -4
- data/lib/automation_object/blue_print/composite/hook_element_requirements.rb +3 -4
- data/lib/automation_object/blue_print/composite/modal.rb +12 -9
- data/lib/automation_object/blue_print/composite/screen.rb +17 -14
- data/lib/automation_object/blue_print/composite/top.rb +3 -2
- data/lib/automation_object/blue_print/composite/view.rb +8 -7
- data/lib/automation_object/blue_print/hash_adapter.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/{automatic_onload_modal.rb → automatic_modal_change.rb} +3 -2
- data/lib/automation_object/blue_print/hash_adapter/composite.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/custom_method.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/element.rb +2 -0
- data/lib/automation_object/blue_print/hash_adapter/element_array.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/element_hash.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/element_helper.rb +8 -2
- data/lib/automation_object/blue_print/hash_adapter/helpers/multiple_elements_helper.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validation_error.rb +2 -1
- data/lib/automation_object/blue_print/hash_adapter/helpers/validation_helper.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_allowed_keys.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_element_presence_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_instance_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_modal_presence_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_presence_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_screen_presence_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/helpers/validators/validate_view_presence_of.rb +1 -0
- data/lib/automation_object/blue_print/hash_adapter/hook.rb +2 -1
- data/lib/automation_object/blue_print/hash_adapter/hook_action.rb +4 -3
- data/lib/automation_object/blue_print/hash_adapter/hook_element_requirements.rb +2 -1
- data/lib/automation_object/blue_print/hash_adapter/modal.rb +2 -1
- data/lib/automation_object/blue_print/hash_adapter/screen.rb +14 -13
- data/lib/automation_object/blue_print/hash_adapter/top.rb +3 -2
- data/lib/automation_object/blue_print/hash_adapter/view.rb +12 -11
- data/lib/automation_object/blue_print/yaml_adapter.rb +1 -0
- data/lib/automation_object/driver.rb +1 -0
- data/lib/automation_object/driver/appium_adapter/driver.rb +2 -1
- data/lib/automation_object/driver/appium_adapter/element.rb +1 -0
- data/lib/automation_object/driver/base.rb +1 -0
- data/lib/automation_object/driver/common_selenium/driver.rb +1 -0
- data/lib/automation_object/driver/common_selenium/element.rb +1 -0
- data/lib/automation_object/driver/common_selenium/element_geometry.rb +1 -0
- data/lib/automation_object/driver/driver.rb +1 -0
- data/lib/automation_object/driver/element.rb +1 -0
- data/lib/automation_object/driver/nokogiri_adapter/driver.rb +5 -8
- data/lib/automation_object/driver/nokogiri_adapter/element.rb +9 -14
- data/lib/automation_object/driver/nokogiri_adapter/error.rb +1 -0
- data/lib/automation_object/driver/nokogiri_adapter/form.rb +1 -0
- data/lib/automation_object/driver/nokogiri_adapter/request.rb +1 -0
- data/lib/automation_object/driver/nokogiri_adapter/session.rb +1 -0
- data/lib/automation_object/driver/nokogiri_adapter/window.rb +1 -0
- data/lib/automation_object/driver/selenium_adapter/driver.rb +1 -0
- data/lib/automation_object/driver/selenium_adapter/element.rb +1 -0
- data/lib/automation_object/dsl.rb +4 -2
- data/lib/automation_object/dsl/_base.rb +11 -1
- data/lib/automation_object/dsl/_error.rb +71 -0
- data/lib/automation_object/dsl/_proxy.rb +1 -0
- data/lib/automation_object/dsl/element.rb +2 -2
- data/lib/automation_object/dsl/element_array.rb +2 -2
- data/lib/automation_object/dsl/element_hash.rb +2 -2
- data/lib/automation_object/dsl/modal.rb +47 -2
- data/lib/automation_object/dsl/screen.rb +67 -3
- data/lib/automation_object/dsl/top.rb +19 -0
- data/lib/automation_object/framework.rb +18 -1
- data/lib/automation_object/helpers/composite.rb +3 -1
- data/lib/automation_object/helpers/composite_hook.rb +1 -0
- data/lib/automation_object/helpers/file.rb +1 -0
- data/lib/automation_object/helpers/hash.rb +1 -0
- data/lib/automation_object/helpers/kernel.rb +1 -0
- data/lib/automation_object/helpers/reflection.rb +1 -0
- data/lib/automation_object/helpers/string.rb +1 -0
- data/lib/automation_object/proxy/mutex_proxy.rb +1 -0
- data/lib/automation_object/proxy/proxy.rb +1 -0
- data/lib/automation_object/proxy/throttle_proxy.rb +2 -1
- data/lib/automation_object/state.rb +5 -1
- data/lib/automation_object/state/_base.rb +2 -1
- data/lib/automation_object/state/_common_element.rb +5 -0
- data/lib/automation_object/state/_error.rb +1 -0
- data/lib/automation_object/state/automatic_modal_change.rb +13 -0
- data/lib/automation_object/state/automatic_screen_changes.rb +13 -0
- data/lib/automation_object/state/element.rb +2 -1
- data/lib/automation_object/state/element_array.rb +2 -1
- data/lib/automation_object/state/element_hash.rb +2 -1
- data/lib/automation_object/state/element_proxy.rb +1 -0
- data/lib/automation_object/state/helpers/automatic_routing.rb +96 -0
- data/lib/automation_object/state/helpers/container_helper.rb +46 -0
- data/lib/automation_object/state/hook.rb +1 -0
- data/lib/automation_object/state/hook_action.rb +1 -0
- data/lib/automation_object/state/hook_actions/action_loop.rb +1 -0
- data/lib/automation_object/state/hook_actions/change_screen.rb +1 -0
- data/lib/automation_object/state/hook_actions/change_to_previous_screen.rb +1 -0
- data/lib/automation_object/state/hook_actions/close_modal.rb +1 -0
- data/lib/automation_object/state/hook_actions/close_screen.rb +1 -0
- data/lib/automation_object/state/hook_actions/element_requirement.rb +1 -0
- data/lib/automation_object/state/hook_actions/new_screen.rb +1 -0
- data/lib/automation_object/state/hook_actions/possible_screen_changes.rb +1 -0
- data/lib/automation_object/state/hook_actions/reset_screen.rb +1 -0
- data/lib/automation_object/state/hook_actions/show_modal.rb +1 -0
- data/lib/automation_object/state/hook_actions/sleep.rb +1 -0
- data/lib/automation_object/state/hook_actions/wait_for_elements.rb +1 -0
- data/lib/automation_object/state/modal.rb +5 -14
- data/lib/automation_object/state/screen.rb +33 -19
- data/lib/automation_object/state/top.rb +17 -2
- data/lib/automation_object/step_definitions.rb +3 -4
- data/lib/automation_object/step_definitions/element.rb +22 -23
- data/lib/automation_object/step_definitions/element_array.rb +26 -27
- data/lib/automation_object/step_definitions/element_hash.rb +26 -27
- data/lib/automation_object/step_definitions/modal.rb +31 -0
- data/lib/automation_object/step_definitions/screen.rb +22 -10
- data/lib/automation_object/step_definitions/support/cache.rb +5 -2
- data/lib/automation_object/step_definitions/support/element_array.rb +1 -1
- data/lib/automation_object/step_definitions/support/parse.rb +1 -1
- data/lib/automation_object/version.rb +2 -1
- metadata +59 -39
- data/lib/automation_object/step_definitions/support/minitest.rb +0 -10
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'appium_lib'
|
3
4
|
|
4
5
|
require_relative '../../proxy/proxy'
|
@@ -85,7 +86,7 @@ module AutomationObject
|
|
85
86
|
|
86
87
|
# @return [Boolean] whether or not browser is being used
|
87
88
|
def browser?
|
88
|
-
return @browser
|
89
|
+
return @browser if defined? @browser
|
89
90
|
@browser = false
|
90
91
|
|
91
92
|
# Now we need to check Appium's contexts to see if WEBVIEW is in available_contexts
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'session'
|
3
4
|
|
4
5
|
require_relative '../element'
|
@@ -56,8 +57,7 @@ module AutomationObject
|
|
56
57
|
# Set timeout wait
|
57
58
|
# @param timeout [Integer] the timeout in seconds
|
58
59
|
# @return [void]
|
59
|
-
def wait(timeout = nil)
|
60
|
-
end
|
60
|
+
def wait(timeout = nil); end
|
61
61
|
|
62
62
|
# @param selector_type [Symbol] selector type, :css, :xpath, etc...
|
63
63
|
# @param selector_path [String] path to element
|
@@ -92,12 +92,10 @@ module AutomationObject
|
|
92
92
|
end
|
93
93
|
|
94
94
|
# Accept prompt either in browser or mobile
|
95
|
-
def accept_prompt
|
96
|
-
end
|
95
|
+
def accept_prompt; end
|
97
96
|
|
98
97
|
# Dismiss the prompt
|
99
|
-
def dismiss_prompt
|
100
|
-
end
|
98
|
+
def dismiss_prompt; end
|
101
99
|
|
102
100
|
# Check if browser, more useful for Appium but can be generic here
|
103
101
|
# @return [Boolean] whether or not browser is being used
|
@@ -131,8 +129,7 @@ module AutomationObject
|
|
131
129
|
|
132
130
|
# @param script [String] JS to run
|
133
131
|
# @return [Object, nil]
|
134
|
-
def execute_script(script)
|
135
|
-
end
|
132
|
+
def execute_script(script); end
|
136
133
|
|
137
134
|
# @return [Point] x,y scroll position
|
138
135
|
def scroll_position
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative '../driver'
|
3
4
|
require_relative 'error'
|
4
5
|
|
@@ -61,22 +62,18 @@ module AutomationObject
|
|
61
62
|
end
|
62
63
|
|
63
64
|
# @return [Boolean]
|
64
|
-
def visible
|
65
|
-
end
|
65
|
+
def visible?; end
|
66
66
|
|
67
67
|
# @return [Boolean]
|
68
|
-
def invisible
|
69
|
-
end
|
68
|
+
def invisible?; end
|
70
69
|
|
71
70
|
# Get the location
|
72
71
|
# @return [Point]
|
73
|
-
def location
|
74
|
-
end
|
72
|
+
def location; end
|
75
73
|
|
76
74
|
# Get the size of an element
|
77
75
|
# @return [Dimension]
|
78
|
-
def size
|
79
|
-
end
|
76
|
+
def size; end
|
80
77
|
|
81
78
|
# Perform a submit action on an element
|
82
79
|
# @return [void]
|
@@ -88,8 +85,7 @@ module AutomationObject
|
|
88
85
|
|
89
86
|
# Scroll the element into view
|
90
87
|
# @return [void]
|
91
|
-
def scroll_into_view
|
92
|
-
end
|
88
|
+
def scroll_into_view; end
|
93
89
|
|
94
90
|
# Perform a click action on the element
|
95
91
|
# @return [void]
|
@@ -130,8 +126,8 @@ module AutomationObject
|
|
130
126
|
BoxCoordinates.new(x1: 0, y1: 0, x2: 0, y2: 0)
|
131
127
|
end
|
132
128
|
|
133
|
-
# @param
|
134
|
-
# @param
|
129
|
+
# @param _second_element_object [Object] element to compare to
|
130
|
+
# @param _collision_tolerance [Numeric, FalseClass] pixel tolerance of collisions
|
135
131
|
# @return [Boolean] element collides with other
|
136
132
|
def collides_with_element?(_second_element_object, _collision_tolerance = false)
|
137
133
|
false
|
@@ -139,8 +135,7 @@ module AutomationObject
|
|
139
135
|
|
140
136
|
# Hover over element
|
141
137
|
# @return [void]
|
142
|
-
def hover
|
143
|
-
end
|
138
|
+
def hover; end
|
144
139
|
|
145
140
|
# Helper method to switch to this element's iframe
|
146
141
|
# @return [void]
|
@@ -1,13 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'dsl/top'
|
4
|
+
require_relative 'state/top'
|
3
5
|
|
4
6
|
module AutomationObject
|
5
7
|
# Dsl Port
|
6
8
|
module Dsl
|
7
9
|
module_function
|
8
10
|
|
9
|
-
# @param [AutomationObject::BluePrint::Composite::Top]
|
10
|
-
# @param [AutomationObject::State::
|
11
|
+
# @param blue_prints [AutomationObject::BluePrint::Composite::Top] top blue print
|
12
|
+
# @param state [AutomationObject::State::Top] top state
|
11
13
|
# @return [AutomationObject::Dsl::Top]
|
12
14
|
def create(blue_prints, state)
|
13
15
|
TopProxy.new(blue_prints, state, :top)
|
@@ -12,13 +12,23 @@ module AutomationObject
|
|
12
12
|
# Add attributes the call super
|
13
13
|
self.class.has_many_relationships.each do |name, composite_class|
|
14
14
|
blue_prints.send(name).each do |child_key, child_blue_prints|
|
15
|
-
|
15
|
+
child_state = state.send(name)[child_key]
|
16
|
+
ostruct_hash[child_key] = composite_class.new(child_blue_prints, child_state, child_key)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
20
|
super ostruct_hash
|
20
21
|
end
|
21
22
|
|
23
|
+
# @param [Symbol] method
|
24
|
+
# @param [Array, nil] args
|
25
|
+
# @param [Proc] block
|
26
|
+
def method_missing(method, *args, &block)
|
27
|
+
return super if to_h.key?(method)
|
28
|
+
|
29
|
+
raise NoMethodError.new("undefined method '#{method}'", method, args)
|
30
|
+
end
|
31
|
+
|
22
32
|
def to_s
|
23
33
|
inspect
|
24
34
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AutomationObject
|
4
|
+
module Dsl
|
5
|
+
# Errors related to interacting with the DSL
|
6
|
+
module Error
|
7
|
+
# Error for automatically reaching screen
|
8
|
+
class AutoReachScreenError < StandardError
|
9
|
+
# @param name [Symbol,String] screen name
|
10
|
+
def initialize(name)
|
11
|
+
message = "#{name}, unable to automatically reach screen"
|
12
|
+
super(message)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Error for automatically reaching modal
|
17
|
+
class AutoReachModalError < StandardError
|
18
|
+
# @param name [Symbol,String] screen name
|
19
|
+
def initialize(name)
|
20
|
+
message = "#{name}, unable to automatically reach modal"
|
21
|
+
super(message)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Error for non-existent screen
|
26
|
+
class ScreenDoesNotExistError < StandardError
|
27
|
+
# @param name [Symbol,String] screen name
|
28
|
+
def initialize(name)
|
29
|
+
message = "#{name} screen does not exist"
|
30
|
+
super(message)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Error for non-existent modal
|
35
|
+
class ModalDoesNotExistError < StandardError
|
36
|
+
# @param name [Symbol,String] modal name
|
37
|
+
def initialize(name)
|
38
|
+
message = "#{name} modal does not exist"
|
39
|
+
super(message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Error for non-existent element
|
44
|
+
class ElementDoesNotExistError < StandardError
|
45
|
+
# @param name [Symbol,String] element name
|
46
|
+
def initialize(name)
|
47
|
+
message = "#{name} element does not exist"
|
48
|
+
super(message)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Error for non-existent element hash
|
53
|
+
class ElementHashDoesNotExistError < StandardError
|
54
|
+
# @param name [Symbol,String] element hash name
|
55
|
+
def initialize(name)
|
56
|
+
message = "#{name} element hash does not exist"
|
57
|
+
super(message)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Error for non-existent element array
|
62
|
+
class ElementArrayDoesNotExistError < StandardError
|
63
|
+
# @param name [Symbol,String] element array name
|
64
|
+
def initialize(name)
|
65
|
+
message = "#{name} element array does not exist"
|
66
|
+
super(message)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative '_proxy'
|
3
4
|
|
4
5
|
module AutomationObject
|
@@ -13,8 +14,7 @@ module AutomationObject
|
|
13
14
|
# @param [AutomationObject::State::Modal, AutomationObject::State::Screen] state
|
14
15
|
# @param [Symbol] name
|
15
16
|
def initialize(blue_prints, state, name)
|
16
|
-
|
17
|
-
super Element, blue_prints, element_state, name
|
17
|
+
super Element, blue_prints, state, name
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param [Symbol] method
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative '_proxy'
|
3
4
|
|
4
5
|
module AutomationObject
|
@@ -13,8 +14,7 @@ module AutomationObject
|
|
13
14
|
# @param [AutomationObject::State::Modal, AutomationObject::State::Screen] state
|
14
15
|
# @param [Symbol] name
|
15
16
|
def initialize(blue_prints, state, name)
|
16
|
-
|
17
|
-
super ElementArray, blue_prints, element_array_state, name
|
17
|
+
super ElementArray, blue_prints, state, name
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param [Symbol] method
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative '_proxy'
|
3
4
|
|
4
5
|
module AutomationObject
|
@@ -13,8 +14,7 @@ module AutomationObject
|
|
13
14
|
# @param [AutomationObject::State::Modal, AutomationObject::State::Screen] state
|
14
15
|
# @param [Symbol] name
|
15
16
|
def initialize(blue_prints, state, name)
|
16
|
-
|
17
|
-
super ElementHash, blue_prints, element_hash_state, name
|
17
|
+
super ElementHash, blue_prints, state, name
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param [Symbol] method
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative '_base'
|
3
4
|
require_relative '_proxy'
|
5
|
+
require_relative '_error'
|
4
6
|
|
5
7
|
require_relative 'element'
|
6
8
|
require_relative 'element_array'
|
@@ -21,8 +23,7 @@ module AutomationObject
|
|
21
23
|
# @param [AutomationObject::State::Screen] state
|
22
24
|
# @param [Symbol] name
|
23
25
|
def initialize(blue_prints, state, name)
|
24
|
-
|
25
|
-
super Modal, blue_prints, modal_state, name
|
26
|
+
super Modal, blue_prints, state, name
|
26
27
|
end
|
27
28
|
|
28
29
|
# @param [Symbol] method
|
@@ -41,6 +42,50 @@ module AutomationObject
|
|
41
42
|
def active?
|
42
43
|
@state.active?
|
43
44
|
end
|
45
|
+
|
46
|
+
# Go to this modal
|
47
|
+
# Will try to automatically reach it, will throw error if it cannot
|
48
|
+
# @raise [AutomationObject::Dsl::Error::AutoReachModalError]
|
49
|
+
# @return [void]
|
50
|
+
def go
|
51
|
+
raise AutomationObject::Dsl::Error::AutoReachModalError, @name unless @state.go
|
52
|
+
end
|
53
|
+
|
54
|
+
# Retrieve element from composite
|
55
|
+
# @param name [String, Symbol] name of element
|
56
|
+
# @raise [AutomationObject::Dsl::Error::ElementDoesNotExistError]
|
57
|
+
# @return [AutomationObject::Dsl::ElementProxy]
|
58
|
+
def element(name)
|
59
|
+
name = name.to_sym
|
60
|
+
raise AutomationObject::Dsl::Error::ElementDoesNotExistError, name unless @subject.to_h.include?(name)
|
61
|
+
|
62
|
+
@state.utilize
|
63
|
+
@subject.send(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Retrieve element array from composite
|
67
|
+
# @param name [String, Symbol] name of element array
|
68
|
+
# @raise [AutomationObject::Dsl::Error::ElementArrayDoesNotExistError]
|
69
|
+
# @return [AutomationObject::Dsl::ElementArrayProxy]
|
70
|
+
def element_array(name)
|
71
|
+
name = name.to_sym
|
72
|
+
raise AutomationObject::Dsl::Error::ElementArrayDoesNotExistError, name unless @subject.to_h.include?(name)
|
73
|
+
|
74
|
+
@state.utilize
|
75
|
+
@subject.send(name)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Retrieve element hash from composite
|
79
|
+
# @param name [String, Symbol] name of element hash
|
80
|
+
# @raise [AutomationObject::Dsl::Error::ElementHashDoesNotExistError]
|
81
|
+
# @return [AutomationObject::Dsl::ElementHashProxy]
|
82
|
+
def element_hash(name)
|
83
|
+
name = name.to_sym
|
84
|
+
raise AutomationObject::Dsl::Error::ElementHashDoesNotExistError, name unless @subject.to_h.include?(name)
|
85
|
+
|
86
|
+
@state.utilize
|
87
|
+
@subject.send(name)
|
88
|
+
end
|
44
89
|
end
|
45
90
|
end
|
46
91
|
end
|