AXElements 0.6.0beta2 → 0.7.5
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.
- data/.yardopts +1 -2
- data/README.markdown +152 -88
- data/Rakefile +8 -103
- data/docs/Debugging.markdown +9 -2
- data/docs/KeyboardEvents.markdown +114 -49
- data/docs/Setting.markdown +1 -0
- data/docs/images/next_version.png +0 -0
- data/ext/accessibility/key_coder/extconf.rb +22 -0
- data/ext/accessibility/key_coder/key_coder.c +113 -0
- data/lib/AXElements.rb +2 -0
- data/lib/accessibility/core.rb +897 -0
- data/lib/accessibility/debug.rb +168 -0
- data/lib/accessibility/dsl.rb +697 -0
- data/lib/accessibility/enumerators.rb +104 -0
- data/lib/accessibility/errors.rb +32 -0
- data/lib/accessibility/factory.rb +153 -0
- data/lib/accessibility/graph.rb +150 -0
- data/lib/{ax_elements/inspector.rb → accessibility/pp_inspector.rb} +39 -28
- data/lib/accessibility/qualifier.rb +158 -0
- data/lib/accessibility/string.rb +494 -0
- data/lib/accessibility/translator.rb +178 -0
- data/lib/accessibility/version.rb +7 -0
- data/lib/accessibility.rb +79 -0
- data/lib/ax/application.rb +234 -0
- data/lib/{ax_elements/elements → ax}/button.rb +2 -0
- data/lib/ax/element.rb +518 -0
- data/lib/{ax_elements/elements → ax}/radio_button.rb +2 -0
- data/lib/ax/row.rb +37 -0
- data/lib/{ax_elements/elements → ax}/static_text.rb +2 -0
- data/lib/ax/systemwide.rb +86 -0
- data/lib/ax_elements/awesome_print.rb +25 -0
- data/lib/ax_elements/exception_workaround.rb +8 -0
- data/lib/ax_elements/nsarray_compat.rb +64 -0
- data/lib/ax_elements/vendor/inflection_data.rb +65 -0
- data/lib/ax_elements/vendor/inflections.rb +172 -0
- data/lib/ax_elements/vendor/inflector.rb +306 -0
- data/lib/ax_elements.rb +14 -25
- data/lib/minitest/ax_elements.rb +112 -12
- data/lib/mouse.rb +72 -46
- data/lib/rspec/expectations/ax_elements.rb +133 -6
- data/rakelib/doc.rake +13 -0
- data/rakelib/ext.rake +61 -0
- data/rakelib/gem.rake +28 -0
- data/rakelib/test.rake +53 -0
- data/test/helper.rb +11 -97
- data/test/integration/accessibility/test_core.rb +18 -0
- data/test/integration/accessibility/test_debug.rb +44 -0
- data/test/integration/accessibility/test_dsl.rb +225 -0
- data/test/integration/accessibility/test_enumerators.rb +122 -0
- data/test/integration/accessibility/test_errors.rb +38 -0
- data/test/integration/accessibility/test_notifications.rb +22 -0
- data/test/integration/accessibility/test_qualifier.rb +148 -0
- data/test/integration/ax/test_application.rb +56 -0
- data/test/integration/ax/test_element.rb +46 -0
- data/test/integration/ax/test_row.rb +23 -0
- data/test/integration/ax_elements/test_nsarray_compat.rb +43 -0
- data/test/integration/minitest/test_ax_elements.rb +98 -0
- data/test/integration/rspec/expectations/test_ax_elements.rb +58 -0
- data/test/integration/test_mouse.rb +35 -0
- data/test/sanity/accessibility/test_core.rb +553 -0
- data/test/sanity/accessibility/test_debug.rb +63 -0
- data/test/sanity/accessibility/test_dsl.rb +75 -0
- data/test/sanity/accessibility/test_errors.rb +10 -0
- data/test/sanity/accessibility/test_factory.rb +88 -0
- data/test/sanity/accessibility/test_pp_inspector.rb +110 -0
- data/test/sanity/accessibility/test_qualifier.rb +13 -0
- data/test/sanity/accessibility/test_string.rb +238 -0
- data/test/sanity/accessibility/test_translator.rb +145 -0
- data/test/sanity/ax/test_application.rb +90 -0
- data/test/sanity/ax/test_element.rb +80 -0
- data/test/sanity/ax/test_systemwide.rb +66 -0
- data/test/sanity/ax_elements/test_nsarray_compat.rb +16 -0
- data/test/sanity/ax_elements/test_nsobject_inspect.rb +11 -0
- data/test/sanity/minitest/test_ax_elements.rb +15 -0
- data/test/sanity/rspec/expectations/test_ax_elements.rb +12 -0
- data/test/sanity/test_ax_elements.rb +10 -0
- data/test/sanity/test_mouse.rb +19 -0
- metadata +111 -93
- data/LICENSE.txt +0 -25
- data/ext/key_coder/extconf.rb +0 -6
- data/ext/key_coder/key_coder.m +0 -77
- data/lib/ax_elements/accessibility/enumerators.rb +0 -104
- data/lib/ax_elements/accessibility/graph.rb +0 -118
- data/lib/ax_elements/accessibility/language.rb +0 -347
- data/lib/ax_elements/accessibility/qualifier.rb +0 -73
- data/lib/ax_elements/accessibility.rb +0 -166
- data/lib/ax_elements/core.rb +0 -541
- data/lib/ax_elements/element.rb +0 -593
- data/lib/ax_elements/elements/application.rb +0 -88
- data/lib/ax_elements/elements/row.rb +0 -30
- data/lib/ax_elements/elements/systemwide.rb +0 -46
- data/lib/ax_elements/macruby_extensions.rb +0 -255
- data/lib/ax_elements/notification.rb +0 -37
- data/lib/ax_elements/version.rb +0 -9
- data/test/elements/test_application.rb +0 -72
- data/test/elements/test_row.rb +0 -27
- data/test/elements/test_systemwide.rb +0 -38
- data/test/test_accessibility.rb +0 -127
- data/test/test_blankness.rb +0 -26
- data/test/test_core.rb +0 -448
- data/test/test_element.rb +0 -939
- data/test/test_enumerators.rb +0 -81
- data/test/test_inspector.rb +0 -130
- data/test/test_language.rb +0 -157
- data/test/test_macruby_extensions.rb +0 -303
- data/test/test_mouse.rb +0 -5
- data/test/test_search_semantics.rb +0 -143
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'test/helper'
|
|
2
|
+
require 'accessibility/factory'
|
|
3
|
+
require 'ax/element'
|
|
4
|
+
require 'ax/application'
|
|
5
|
+
|
|
6
|
+
# Just pretend that you didn't see this
|
|
7
|
+
class AX::Element
|
|
8
|
+
attr_reader :ref
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class TestAccessibilityFactory < MiniTest::Unit::TestCase
|
|
12
|
+
include Accessibility::Factory
|
|
13
|
+
|
|
14
|
+
def window
|
|
15
|
+
REF.children.find { |x| x.role == KAXWindowRole }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def scroll_area
|
|
19
|
+
window.children.find { |x|
|
|
20
|
+
x.attributes.include?(KAXDescriptionAttribute) &&
|
|
21
|
+
x.attribute(KAXDescriptionAttribute) == 'Test Web Area'
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def web_area
|
|
26
|
+
scroll_area.children.find { |x| x.role == 'AXWebArea' }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def close_button
|
|
30
|
+
window.children.find { |x|
|
|
31
|
+
x.attributes.include?(KAXSubroleAttribute) &&
|
|
32
|
+
x.attribute(KAXSubroleAttribute) == KAXCloseButtonSubrole
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_processing_element_refs
|
|
37
|
+
assert_equal REF, process(REF).ref
|
|
38
|
+
|
|
39
|
+
o = process(web_area)
|
|
40
|
+
assert_instance_of AX::WebArea, o
|
|
41
|
+
|
|
42
|
+
# intentionally done a second time to see if the
|
|
43
|
+
# created class is used again; this guarantees
|
|
44
|
+
# that the class can be created properly and then
|
|
45
|
+
# used again when needed
|
|
46
|
+
2.times do
|
|
47
|
+
o = process window
|
|
48
|
+
assert_instance_of AX::StandardWindow, o
|
|
49
|
+
o = process close_button
|
|
50
|
+
assert_instance_of AX::CloseButton, o
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
2.times do
|
|
54
|
+
o = process REF
|
|
55
|
+
assert_instance_of AX::Application, o
|
|
56
|
+
o = process scroll_area
|
|
57
|
+
assert_instance_of AX::ScrollArea, o
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_processing_arrays
|
|
62
|
+
assert_equal [], process_array([])
|
|
63
|
+
assert_equal [1], process_array([1])
|
|
64
|
+
|
|
65
|
+
expected = [AX::Application.new(REF)]
|
|
66
|
+
assert_equal expected, process_array([REF])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_processing_arbitrary_objects
|
|
70
|
+
assert_equal 'test', process('test')
|
|
71
|
+
assert_equal 42, process(42)
|
|
72
|
+
|
|
73
|
+
now = Time.now
|
|
74
|
+
assert_equal now, process(now)
|
|
75
|
+
|
|
76
|
+
string = NSAttributedString.alloc.initWithString 'hi'
|
|
77
|
+
assert_equal string, process(string)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_processing_nil
|
|
81
|
+
assert_nil process(nil)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def bench_process
|
|
85
|
+
skip 'This is important when we get to optimizing'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
class TestAccessibilityPPInspector < MiniTest::Unit::TestCase
|
|
4
|
+
include Accessibility::PPInspector
|
|
5
|
+
|
|
6
|
+
# expected API for PPInspector module
|
|
7
|
+
attr_reader :attributes
|
|
8
|
+
def attribute attr; @attribute; end
|
|
9
|
+
def size_of attr; @size_of; end
|
|
10
|
+
|
|
11
|
+
def test_identifier_using_value
|
|
12
|
+
@attributes = [:value]
|
|
13
|
+
|
|
14
|
+
@attribute = 'cake'
|
|
15
|
+
assert_match /"cake"/, pp_identifier
|
|
16
|
+
|
|
17
|
+
@attribute = 3.14
|
|
18
|
+
assert_match /value=3.14/, pp_identifier
|
|
19
|
+
|
|
20
|
+
@attribute = ''
|
|
21
|
+
assert_match EMPTY_STRING, pp_identifier
|
|
22
|
+
|
|
23
|
+
@attribute = nil
|
|
24
|
+
assert_match EMPTY_STRING, pp_identifier
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_identifier_using_title
|
|
28
|
+
@attributes = [:title]
|
|
29
|
+
@attribute = 'My Title'
|
|
30
|
+
assert_match /"My Title"/, pp_identifier
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_identifier_using_title_ui_element
|
|
34
|
+
@attributes = [:title_ui_element]
|
|
35
|
+
@attribute = 'hey'
|
|
36
|
+
assert_match /"hey"/, pp_identifier
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# hmmm...
|
|
40
|
+
def test_identifier_using_description
|
|
41
|
+
@attributes = [:description]
|
|
42
|
+
|
|
43
|
+
@attribute = 'roflcopter'
|
|
44
|
+
assert_match /roflcopter/, pp_identifier
|
|
45
|
+
|
|
46
|
+
@attribute = NSString.string
|
|
47
|
+
assert_equal EMPTY_STRING, pp_identifier
|
|
48
|
+
|
|
49
|
+
@attribute = 26
|
|
50
|
+
assert_match /26/, pp_identifier
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_identifier_using_identifier
|
|
54
|
+
@attributes = [:identifier]
|
|
55
|
+
|
|
56
|
+
@attribute = '_NS:151'
|
|
57
|
+
assert_match /id=_NS:151/, pp_identifier
|
|
58
|
+
|
|
59
|
+
@attribute = 'contact table'
|
|
60
|
+
assert_match /id=contact table/, pp_identifier
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_identifier_empty_string_as_final_fallback
|
|
64
|
+
@attributes = NSArray.array
|
|
65
|
+
assert_equal EMPTY_STRING, pp_identifier
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_position
|
|
69
|
+
@attribute = CGPointZero
|
|
70
|
+
assert_match /\(0\.0, 0\.0\)/, pp_position
|
|
71
|
+
|
|
72
|
+
@attribute = CGPoint.new(3.14, -5)
|
|
73
|
+
assert_match /\(3\.14, -5\.0\)/, pp_position
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# this sometimes happens, even though it shouldn't
|
|
77
|
+
def test_position_is_nil
|
|
78
|
+
@attribute = nil
|
|
79
|
+
assert_equal EMPTY_STRING, pp_position
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_children_pluralizes_properly
|
|
83
|
+
[[2, /2 children/ ],
|
|
84
|
+
[9001, /9001 children/],
|
|
85
|
+
[3.14, /3.14 children/],
|
|
86
|
+
[1, /1 child/ ],
|
|
87
|
+
[0, EMPTY_STRING ]
|
|
88
|
+
].each do |size, matcher|
|
|
89
|
+
@size_of = size
|
|
90
|
+
assert_match matcher, pp_children
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_checkbox
|
|
95
|
+
@attribute = true
|
|
96
|
+
assert_match /thing\[✔\]/, pp_checkbox(:thing)
|
|
97
|
+
@attribute = false
|
|
98
|
+
assert_match /thing\[✘\]/, pp_checkbox(:thing)
|
|
99
|
+
@attribute = nil
|
|
100
|
+
assert_match /thing\[✘\]/, pp_checkbox(:thing)
|
|
101
|
+
|
|
102
|
+
@attribute = true
|
|
103
|
+
assert_match /some attr\[✔\]/, pp_checkbox('some attr')
|
|
104
|
+
@attribute = false
|
|
105
|
+
assert_match /some attr\[✘\]/, pp_checkbox('some attr')
|
|
106
|
+
@attribute = nil
|
|
107
|
+
assert_match /some attr\[✘\]/, pp_checkbox('some attr')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'test/runner'
|
|
2
|
+
require 'accessibility/qualifier'
|
|
3
|
+
|
|
4
|
+
class TestNSDictionaryExtensions < MiniTest::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def test_ax_pp
|
|
7
|
+
assert_equal '', {}.ax_pp
|
|
8
|
+
assert_equal '(title: "Hey, listen!")', {title: 'Hey, listen!'}.ax_pp
|
|
9
|
+
assert_equal '(a: 42, b: [3.14])', {a: 42, b: [3.14]}.ax_pp
|
|
10
|
+
assert_equal '(c(d: ":("))', {c: {d:':('} }.ax_pp
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'test/runner'
|
|
4
|
+
require 'accessibility/string'
|
|
5
|
+
|
|
6
|
+
class TestAccessibilityStringLexer < MiniTest::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
def lex string
|
|
9
|
+
Accessibility::String::Lexer.new(string).lex
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_lex_simple_string
|
|
13
|
+
assert_equal [], lex('')
|
|
14
|
+
assert_equal ['"',"J","u","s","t"," ","W","o","r","k","s",'"',"™"], lex('"Just Works"™')
|
|
15
|
+
assert_equal ["M","i","l","k",","," ","s","h","a","k","e","."], lex("Milk, shake.")
|
|
16
|
+
assert_equal ["D","B","7"], lex("DB7")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_lex_single_custom_escape
|
|
20
|
+
assert_equal [["\\CMD"]], lex("\\CMD")
|
|
21
|
+
assert_equal [["\\1"]], lex("\\1")
|
|
22
|
+
assert_equal [["\\F1"]], lex("\\F1")
|
|
23
|
+
assert_equal [["\\*"]], lex("\\*")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_lex_hotkey_custom_escape
|
|
27
|
+
assert_equal [["\\COMMAND",[","]]], lex("\\COMMAND+,")
|
|
28
|
+
assert_equal [["\\COMMAND",["\\SHIFT",["s"]]]], lex("\\COMMAND+\\SHIFT+s")
|
|
29
|
+
assert_equal [["\\COMMAND",["\\+"]]], lex("\\COMMAND+\\+")
|
|
30
|
+
assert_equal [["\\FN",["\\F10"]]], lex("\\FN+\\F10")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_lex_ruby_escapes
|
|
34
|
+
assert_equal ["\n","\r","\t","\b"], lex("\n\r\t\b")
|
|
35
|
+
assert_equal ["O","n","e","\n","T","w","o"], lex("One\nTwo")
|
|
36
|
+
assert_equal ["L","i","e","\b","\b","\b","d","e","l","i","s","h"], lex("Lie\b\b\bdelish")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_lex_complex_string
|
|
40
|
+
assert_equal ["T","e","s","t",["\\CMD",["s"]]], lex("Test\\CMD+s")
|
|
41
|
+
assert_equal ["Z","O","M","G"," ","1","3","3","7","!","!","1"], lex("ZOMG 1337!!1")
|
|
42
|
+
assert_equal ["F","u","u","!","@","#","%",["\\CMD",["a"]],"\b"], lex("Fuu!@#%\\CMD+a \b")
|
|
43
|
+
assert_equal [["\\CMD",["a"]],"\b","A","l","l"," ","g","o","n","e","!"], lex("\\CMD+a \bAll gone!")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_lex_backslash # make sure we handle these edge cases predictably
|
|
47
|
+
assert_equal ["\\"], lex("\\")
|
|
48
|
+
assert_equal ["\\"," "], lex("\\ ")
|
|
49
|
+
assert_equal ["\\","h","m","m"], lex("\\hmm")
|
|
50
|
+
assert_equal [["\\HMM"]], lex("\\HMM") # the one missed case
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_lex_plus_escape
|
|
54
|
+
assert_equal [["\\+"]], lex("\\+")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_lex_bad_custom_escape_sequence
|
|
58
|
+
assert_raises ArgumentError do
|
|
59
|
+
lex("\\COMMAND+")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class TestAccessibilityStringEventGenerator < MiniTest::Unit::TestCase
|
|
67
|
+
|
|
68
|
+
def gen tokens
|
|
69
|
+
Accessibility::String::EventGenerator.new(tokens).generate
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def map; @@map ||= KeyCoder.dynamic_mapping; end
|
|
73
|
+
|
|
74
|
+
def t; true; end
|
|
75
|
+
def f; false; end
|
|
76
|
+
|
|
77
|
+
def a; @@a ||= map['a']; end
|
|
78
|
+
def c; @@c ||= map['c']; end
|
|
79
|
+
def e; @@e ||= map['e']; end
|
|
80
|
+
def h; @@h ||= map['h']; end
|
|
81
|
+
def i; @@i ||= map['i']; end
|
|
82
|
+
def k; @@k ||= map['k']; end
|
|
83
|
+
def m; @@m ||= map["m"]; end
|
|
84
|
+
|
|
85
|
+
def two; @@two ||= map['2']; end
|
|
86
|
+
def four; @@four ||= map['4']; end
|
|
87
|
+
|
|
88
|
+
def retern; @@retern ||= map["\r"]; end
|
|
89
|
+
def tab; @@tab ||= map["\t"]; end
|
|
90
|
+
def space; @@space ||= map["\s"]; end
|
|
91
|
+
|
|
92
|
+
def dash; @@dash ||= map["-"]; end
|
|
93
|
+
def comma; @@comma ||= map[","]; end
|
|
94
|
+
def apos; @@apos ||= map["'"]; end
|
|
95
|
+
def at; @@at ||= map["2"]; end
|
|
96
|
+
def paren; @@paren ||= map["9"]; end
|
|
97
|
+
def chev; @@chev ||= map["."]; end
|
|
98
|
+
|
|
99
|
+
def sigma; @@sigma ||= map["w"]; end
|
|
100
|
+
def tm; @@tm ||= map["2"]; end
|
|
101
|
+
def gbp; @@gbp ||= map["3"]; end
|
|
102
|
+
def omega; @@omega ||= map["z"]; end
|
|
103
|
+
|
|
104
|
+
def bslash; @@blash ||= map["\\"]; end
|
|
105
|
+
|
|
106
|
+
# key code for the left shift key
|
|
107
|
+
def sd; [56,t]; end
|
|
108
|
+
def su; [56,f]; end
|
|
109
|
+
|
|
110
|
+
# key code for the left option key
|
|
111
|
+
def od; [58,t]; end
|
|
112
|
+
def ou; [58,f]; end
|
|
113
|
+
|
|
114
|
+
# key code for the left command key
|
|
115
|
+
def cd; [0x37,t]; end
|
|
116
|
+
def cu; [0x37,f]; end
|
|
117
|
+
|
|
118
|
+
# key code for right arrow key
|
|
119
|
+
def rd; [0x7c,t]; end
|
|
120
|
+
def ru; [0x7c,f]; end
|
|
121
|
+
|
|
122
|
+
# key code for left control key
|
|
123
|
+
def ctrld; [0x3B,t]; end
|
|
124
|
+
def ctrlu; [0x3B,f]; end
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_generate_lowercase
|
|
128
|
+
assert_equal [[a,t],[a,f]], gen(['a'])
|
|
129
|
+
assert_equal [[c,t],[c,f],[k,t],[k,f]], gen(['c','k'])
|
|
130
|
+
assert_equal [[e,t],[e,f],[e,t],[e,f]], gen(['e','e'])
|
|
131
|
+
assert_equal [[c,t],[c,f],[a,t],[a,f],[k,t],[k,f],[e,t],[e,f]], gen(['c','a','k','e'])
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_generate_uppercase
|
|
135
|
+
assert_equal [sd,[a,t],[a,f],su], gen(['A'])
|
|
136
|
+
assert_equal [sd,[c,t],[c,f],[k,t],[k,f],su], gen(['C','K'])
|
|
137
|
+
assert_equal [sd,[e,t],[e,f],[e,t],[e,f],su], gen(['E','E'])
|
|
138
|
+
assert_equal [sd,[c,t],[c,f],[a,t],[a,f],[k,t],[k,f],su], gen(['C','A','K'])
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_generate_numbers
|
|
142
|
+
assert_equal [[two,t],[two,f]], gen(['2'])
|
|
143
|
+
assert_equal [[four,t],[four,f],[two,t],[two,f]], gen(['4','2'])
|
|
144
|
+
assert_equal [[two,t],[two,f],[two,t],[two,f]], gen(['2','2'])
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_generate_ruby_escapes
|
|
148
|
+
assert_equal [[retern,t],[retern,f]], gen(["\r"])
|
|
149
|
+
assert_equal [[retern,t],[retern,f]], gen(["\n"])
|
|
150
|
+
assert_equal [[tab,t],[tab,f]], gen(["\t"])
|
|
151
|
+
assert_equal [[space,t],[space,f]], gen(["\s"])
|
|
152
|
+
assert_equal [[space,t],[space,f]], gen([" "])
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_generate_symbols
|
|
156
|
+
assert_equal [[dash,t],[dash,f]], gen(["-"])
|
|
157
|
+
assert_equal [[comma,t],[comma,f]], gen([","])
|
|
158
|
+
assert_equal [[apos,t],[apos,f]], gen(["'"])
|
|
159
|
+
assert_equal [sd,[at,t],[at,f],su], gen(["@"])
|
|
160
|
+
assert_equal [sd,[paren,t],[paren,f],su], gen(["("])
|
|
161
|
+
assert_equal [sd,[chev,t],[chev,f],su], gen([">"])
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def test_generate_unicode # holding option
|
|
165
|
+
assert_equal [od,[sigma,t],[sigma,f],ou], gen(["∑"])
|
|
166
|
+
assert_equal [od,[tm,t],[tm,f],ou], gen(["™"])
|
|
167
|
+
assert_equal [od,[gbp,t],[gbp,f],ou], gen(["£"])
|
|
168
|
+
assert_equal [od,[omega,t],[omega,f],ou], gen(["Ω"])
|
|
169
|
+
assert_equal [od,[tm,t],[tm,f],[gbp,t],[gbp,f],ou], gen(["™","£"])
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_generate_backslashes
|
|
173
|
+
assert_equal [[bslash,t],[bslash,f]], gen(["\\"])
|
|
174
|
+
assert_equal [[bslash,t],[bslash,f],[space,t],[space,f]], gen(["\\"," "])
|
|
175
|
+
assert_equal [[bslash,t],[bslash,f],[h,t],[h,f],[m,t],[m,f]], gen(["\\",'h','m'])
|
|
176
|
+
# is this the job of the parser or the lexer?
|
|
177
|
+
assert_equal [[bslash,t],[bslash,f],sd,[h,t],[h,f],[m,t],[m,f],su], gen([["\\HM"]])
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_generate_a_custom_escape
|
|
181
|
+
assert_equal [cd,cu], gen([["\\COMMAND"]])
|
|
182
|
+
assert_equal [cd,cu], gen([["\\CMD"]])
|
|
183
|
+
assert_equal [ctrld,ctrlu], gen([["\\CONTROL"]])
|
|
184
|
+
assert_equal [ctrld,ctrlu], gen([["\\CTRL"]])
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_generate_hotkey
|
|
188
|
+
assert_equal [ctrld,[a,t],[a,f],ctrlu], gen([["\\CONTROL",["a"]]])
|
|
189
|
+
assert_equal [cd,sd,rd,ru,su,cu], gen([["\\COMMAND",['\SHIFT',['\->']]]])
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def test_generate_real_use # a regression
|
|
193
|
+
assert_equal [ctrld,[a,t],[a,f],ctrlu,[h,t],[h,f]], gen([["\\CTRL",["a"]],"h"])
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_bails_for_unmapped_token
|
|
197
|
+
# cannot generate snowmen :(
|
|
198
|
+
e = assert_raises(ArgumentError) { gen(["☃"]) }
|
|
199
|
+
assert_match /bail/i, e.message
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_generate_arbitrary_nested_array_sequence
|
|
203
|
+
assert_equal [[c,t],[a,t],[k,t],[e,t],[e,f],[k,f],[a,f],[c,f]], gen([["c",["a",["k",["e"]]]]])
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_generate_command_A
|
|
207
|
+
assert_equal [cd,sd,[a,t],[a,f],su,cu], gen([["\\COMMAND",["A"]]])
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# NOTE: DO NOT TEST POSTING EVENTS HERE
|
|
214
|
+
# We only want to test posting events if all the tests in this file pass,
|
|
215
|
+
# otherwise the posted events may be unpredictable depending on what fails.
|
|
216
|
+
# Test event posting in the integration tests.
|
|
217
|
+
class TestAccessibilityString < MiniTest::Unit::TestCase
|
|
218
|
+
include Accessibility::String
|
|
219
|
+
|
|
220
|
+
# basic test to make sure the lexer and generator get along
|
|
221
|
+
def test_keyboard_events_for
|
|
222
|
+
events = keyboard_events_for 'cheezburger'
|
|
223
|
+
assert_kind_of Array, events
|
|
224
|
+
refute_empty events
|
|
225
|
+
|
|
226
|
+
assert_equal true, events[0][1]
|
|
227
|
+
assert_equal false, events[1][1]
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_dynamic_map_initialized
|
|
231
|
+
refute_empty Accessibility::String::EventGenerator::MAPPING
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def test_can_parse_empty_string
|
|
235
|
+
assert_equal [], keyboard_events_for('')
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'test/runner'
|
|
2
|
+
require 'accessibility/translator'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestAccessibilityTranslator < MiniTest::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
TRANSLATOR = Accessibility::Translator.instance
|
|
8
|
+
|
|
9
|
+
# trivial but important for backwards compat with Snow Leopard
|
|
10
|
+
def test_identifier_const
|
|
11
|
+
assert_equal 'AXIdentifier', KAXIdentifierAttribute
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_unprefixing
|
|
15
|
+
def prefix_test before, after
|
|
16
|
+
assert_equal after, TRANSLATOR.unprefix(before)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
prefix_test 'AXButton', 'Button'
|
|
20
|
+
prefix_test 'MCAXButton', 'Button'
|
|
21
|
+
prefix_test 'AXURL', 'URL'
|
|
22
|
+
prefix_test 'AXTitleUIElement', 'TitleUIElement'
|
|
23
|
+
prefix_test 'AXIsApplicationRunning', 'ApplicationRunning'
|
|
24
|
+
prefix_test 'AXAX', 'AX'
|
|
25
|
+
prefix_test 'Quick Look', 'QuickLook'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_lookup
|
|
29
|
+
def lookup_test key, values, expected
|
|
30
|
+
assert_equal expected, TRANSLATOR.lookup(key, values)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
lookup_test :children, [KAXChildrenAttribute], KAXChildrenAttribute
|
|
34
|
+
lookup_test :title_ui_element, [KAXTitleUIElementAttribute], KAXTitleUIElementAttribute
|
|
35
|
+
lookup_test :focused?, [KAXFocusedAttribute], KAXFocusedAttribute
|
|
36
|
+
lookup_test :flabbergast, [], nil
|
|
37
|
+
lookup_test :totally_fake, ['AXTotallyFake'], 'AXTotallyFake'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_lookup_aliases
|
|
41
|
+
def lookup_test key, values, expected
|
|
42
|
+
assert_equal expected, TRANSLATOR.lookup(key, values)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
lookup_test :id, [], KAXIdentifierAttribute
|
|
46
|
+
lookup_test :placeholder, [], KAXPlaceholderValueAttribute
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_rubyize
|
|
50
|
+
def rubyize_test given, expected
|
|
51
|
+
assert_equal Array(expected), TRANSLATOR.rubyize(Array(given))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
rubyize_test KAXMainWindowAttribute, :main_window
|
|
55
|
+
rubyize_test KAXRoleAttribute, :role
|
|
56
|
+
rubyize_test KAXStringForRangeParameterizedAttribute, :string_for_range
|
|
57
|
+
rubyize_test [KAXSubroleAttribute, KAXChildrenAttribute], [:subrole, :children]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_rubyize_doesnt_eat_original_data
|
|
61
|
+
array = [KAXTitleAttribute, KAXMainWindowAttribute]
|
|
62
|
+
TRANSLATOR.rubyize array
|
|
63
|
+
assert_equal [KAXTitleAttribute, KAXMainWindowAttribute], array
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_guess_notification_for
|
|
67
|
+
def notif_test actual, expected
|
|
68
|
+
assert_equal expected, TRANSLATOR.guess_notification_for(actual)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
notif_test 'window_created', KAXWindowCreatedNotification
|
|
72
|
+
notif_test :window_created, KAXWindowCreatedNotification
|
|
73
|
+
notif_test KAXValueChangedNotification, KAXValueChangedNotification
|
|
74
|
+
notif_test 'Cheezburger', 'Cheezburger'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_classify
|
|
78
|
+
def classify_test actual, expected
|
|
79
|
+
assert_equal expected, TRANSLATOR.classify(actual)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
classify_test :buttons, 'Button'
|
|
83
|
+
classify_test :button, 'Button'
|
|
84
|
+
classify_test :menu_item, 'MenuItem'
|
|
85
|
+
classify_test 'floating_window', 'FloatingWindow'
|
|
86
|
+
classify_test 'outline_rows', 'OutlineRow'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_singularize
|
|
90
|
+
def singularize_test actual, expected
|
|
91
|
+
assert_equal expected, TRANSLATOR.singularize(actual)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
singularize_test :buttons, 'button'
|
|
95
|
+
singularize_test :button, 'button'
|
|
96
|
+
singularize_test :windows, 'window'
|
|
97
|
+
singularize_test :check_boxes, 'check_box'
|
|
98
|
+
singularize_test 'classes', 'class'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_unprefixes_are_cached
|
|
103
|
+
unprefixes = TRANSLATOR.instance_variable_get :@unprefixes
|
|
104
|
+
unprefixed = unprefixes['AXPieIsTheTruth']
|
|
105
|
+
assert_includes unprefixes.keys, 'AXPieIsTheTruth'
|
|
106
|
+
assert_equal unprefixed, unprefixes['AXPieIsTheTruth']
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_normalizations_are_cached
|
|
110
|
+
normalizations = TRANSLATOR.instance_variable_get :@normalizations
|
|
111
|
+
normalized = normalizations['AXTheAnswer']
|
|
112
|
+
assert_includes normalizations.keys, 'AXTheAnswer'
|
|
113
|
+
assert_equal normalized, normalizations['AXTheAnswer']
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_rubyisms_are_cached
|
|
117
|
+
rubyisms = TRANSLATOR.instance_variable_get :@rubyisms
|
|
118
|
+
TRANSLATOR.instance_variable_set :@values, ['AXChocolatePancake']
|
|
119
|
+
rubyized = rubyisms[:chocolate_pancake]
|
|
120
|
+
assert_includes rubyisms.keys, :chocolate_pancake
|
|
121
|
+
assert_equal rubyized, rubyisms[:chocolate_pancake]
|
|
122
|
+
|
|
123
|
+
rubyized = rubyisms[:chocolate_pancake?]
|
|
124
|
+
assert_includes rubyisms.keys, :chocolate_pancake?
|
|
125
|
+
assert_equal rubyized, rubyisms[:chocolate_pancake]
|
|
126
|
+
assert_equal rubyized, rubyisms[:chocolate_pancake?]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def test_classifications_are_cached
|
|
130
|
+
classifications = TRANSLATOR.instance_variable_get :@classifications
|
|
131
|
+
|
|
132
|
+
classified = TRANSLATOR.classify 'made_up_class_name'
|
|
133
|
+
assert_includes classifications.keys, 'made_up_class_name'
|
|
134
|
+
assert_equal classified, classifications['made_up_class_name']
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_singularizations_are_cached
|
|
138
|
+
singulars = TRANSLATOR.instance_variable_get :@singularizations
|
|
139
|
+
|
|
140
|
+
singular = TRANSLATOR.singularize 'buttons'
|
|
141
|
+
assert_includes singulars.keys, 'buttons'
|
|
142
|
+
assert_equal singular, singulars['buttons']
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'test/helper'
|
|
3
|
+
require 'ax/application'
|
|
4
|
+
|
|
5
|
+
class AX::Element
|
|
6
|
+
attr_reader :ref
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class TestAXApplication < MiniTest::Unit::TestCase
|
|
10
|
+
|
|
11
|
+
def app
|
|
12
|
+
@app ||= AX::Application.new REF
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def running_app
|
|
16
|
+
@running_app ||=
|
|
17
|
+
NSRunningApplication.runningApplicationWithProcessIdentifier app.pid
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_is_a_direct_subclass_of_element
|
|
21
|
+
assert_equal AX::Element, AX::Application.superclass
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_inspect_includes_pid
|
|
25
|
+
assert_match /\spid=\d+/, app.inspect
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_inspect_includes_focused
|
|
29
|
+
assert_match /\sfocused\[(?:✔|✘)\]/, app.inspect
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_terminate
|
|
33
|
+
got_called = false
|
|
34
|
+
mock = Object.new
|
|
35
|
+
mock.define_singleton_method(:terminate) { got_called = true }
|
|
36
|
+
mock.define_singleton_method(:terminated?) { false }
|
|
37
|
+
app.instance_variable_set :@app, mock
|
|
38
|
+
app.perform :terminate
|
|
39
|
+
assert got_called
|
|
40
|
+
ensure
|
|
41
|
+
app.instance_variable_set :@app, running_app
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_force_terminate
|
|
45
|
+
got_called = false
|
|
46
|
+
mock = Object.new
|
|
47
|
+
mock.define_singleton_method(:forceTerminate) { got_called = true }
|
|
48
|
+
mock.define_singleton_method(:terminated? ) { false }
|
|
49
|
+
app.instance_variable_set :@app, mock
|
|
50
|
+
|
|
51
|
+
app.perform :force_terminate
|
|
52
|
+
assert got_called
|
|
53
|
+
ensure
|
|
54
|
+
app.instance_variable_set :@app, running_app
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_overrides_call_super
|
|
58
|
+
assert_match app.inspect, /children/
|
|
59
|
+
assert_equal 'AXElementsTester', app.title
|
|
60
|
+
|
|
61
|
+
called_super = false
|
|
62
|
+
app.define_singleton_method :perform do |name|
|
|
63
|
+
called_super = true if name == :some_action
|
|
64
|
+
end
|
|
65
|
+
app.perform :some_action
|
|
66
|
+
assert called_super
|
|
67
|
+
|
|
68
|
+
called_super = false
|
|
69
|
+
app.define_singleton_method :set do |attr, value|
|
|
70
|
+
called_super = true if attr == :thingy && value == 'pie'
|
|
71
|
+
end
|
|
72
|
+
app.set :thingy, 'pie'
|
|
73
|
+
assert called_super
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_type_string_forwards_events
|
|
77
|
+
skip "This strangely causes other tests to fail occassionally"
|
|
78
|
+
got_callback = false
|
|
79
|
+
app.ref.define_singleton_method :post do |events|
|
|
80
|
+
got_callback = true if events.kind_of?(Array)
|
|
81
|
+
end
|
|
82
|
+
app.type_string 'test'
|
|
83
|
+
assert got_callback
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_bundle_identifier
|
|
87
|
+
assert_equal running_app.bundleIdentifier, app.bundle_identifier
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|