vigilem-win32_api 0.0.10
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 +7 -0
- data/LICENSE.txt +22 -0
- data/lib/vigilem/win32_api/console_input_events.rb +78 -0
- data/lib/vigilem/win32_api/constants.rb +97 -0
- data/lib/vigilem/win32_api/dom/adapter.rb +59 -0
- data/lib/vigilem/win32_api/dom/code_values_tables.rb +136 -0
- data/lib/vigilem/win32_api/dom/input_record_utils.rb +259 -0
- data/lib/vigilem/win32_api/dom/key_values_tables.rb +123 -0
- data/lib/vigilem/win32_api/dom.rb +5 -0
- data/lib/vigilem/win32_api/eventable.rb +41 -0
- data/lib/vigilem/win32_api/input__record.rb +53 -0
- data/lib/vigilem/win32_api/input_system_handler.rb +124 -0
- data/lib/vigilem/win32_api/p_input__record.rb +55 -0
- data/lib/vigilem/win32_api/rubyized.rb +114 -0
- data/lib/vigilem/win32_api/types.rb +153 -0
- data/lib/vigilem/win32_api/utils/keyboard.rb +120 -0
- data/lib/vigilem/win32_api/version.rb +5 -0
- data/lib/vigilem/win32_api/virtual_keys/map.rb +211 -0
- data/lib/vigilem/win32_api/virtual_keys.rb +9 -0
- data/lib/vigilem/win32_api.rb +61 -0
- data/spec/acceptance/custom_input_system.feature +3 -0
- data/spec/acceptance/dom_adapter.feature +7 -0
- data/spec/acceptance/rubyized.feature +6 -0
- data/spec/acceptance/steps/custom_input_system_steps.rb +37 -0
- data/spec/acceptance/steps/dom_adapter_steps.rb +7 -0
- data/spec/acceptance/steps/rubyized_steps.rb +20 -0
- data/spec/attributes_and_size_test.rb +10 -0
- data/spec/input_helper.rb +41 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/turnip_helper.rb +1 -0
- data/spec/vigilem/api_spec.rb +139 -0
- data/spec/vigilem/win32_api/console_input_events_spec.rb +67 -0
- data/spec/vigilem/win32_api/dom/adapter_spec.rb +164 -0
- data/spec/vigilem/win32_api/dom/code_values_tables_spec.rb +5 -0
- data/spec/vigilem/win32_api/dom/input_record_utils_spec.rb +255 -0
- data/spec/vigilem/win32_api/dom/key_values_tables_spec.rb +5 -0
- data/spec/vigilem/win32_api/eventable_spec.rb +96 -0
- data/spec/vigilem/win32_api/input__record_spec.rb +113 -0
- data/spec/vigilem/win32_api/input_system_handler_spec.rb +164 -0
- data/spec/vigilem/win32_api/p_input__record_spec.rb +43 -0
- data/spec/vigilem/win32_api/rubyized_spec.rb +134 -0
- data/spec/vigilem/win32_api/types_spec.rb +139 -0
- data/spec/vigilem/win32_api/utils/keyboard_spec.rb +126 -0
- data/spec/vigilem/win32_api/virtual_keys/map_spec.rb +10 -0
- data/spec/vigilem/win32_api/virtual_keys_spec.rb +28 -0
- metadata +225 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api'
|
4
|
+
|
5
|
+
require 'timeout'
|
6
|
+
|
7
|
+
describe Vigilem::Win32API do
|
8
|
+
|
9
|
+
after(:example) do
|
10
|
+
flush
|
11
|
+
end
|
12
|
+
|
13
|
+
context '::GetStdHandle' do
|
14
|
+
it 'will return STD_INPUT_HANDLE' do
|
15
|
+
expect(subject.GetStdHandle(described_class::STD_INPUT_HANDLE)).to eql(std_handle)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
context 'methods except GetStdHandle,' do
|
21
|
+
|
22
|
+
describe '::PeekConsoleInputW' do
|
23
|
+
|
24
|
+
let(:args) do
|
25
|
+
{
|
26
|
+
:hConsoleInput => described_class.GetStdHandle(described_class::STD_INPUT_HANDLE),
|
27
|
+
:lpBuffer => described_class::PINPUT_RECORD.new(len = 1),
|
28
|
+
:nLength => len,
|
29
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
it %q(won't block when the queue is empty) do
|
34
|
+
flush
|
35
|
+
expect do
|
36
|
+
Timeout::timeout(5) do
|
37
|
+
subject.PeekConsoleInputW(*args.values)
|
38
|
+
end
|
39
|
+
end.to_not raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'will return one when it executes correctly' do
|
43
|
+
expect(subject.PeekConsoleInputW(*args.values)).to eql 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'user input' do
|
48
|
+
|
49
|
+
before :each do
|
50
|
+
flush
|
51
|
+
write_console_input_test
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '::PeekConsoleInputW' do
|
55
|
+
|
56
|
+
before :all do
|
57
|
+
@args = {
|
58
|
+
:hConsoleInput => std_handle,
|
59
|
+
:lpBuffer => described_class::PINPUT_RECORD.new(len = 1),
|
60
|
+
:nLength => len,
|
61
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'updates lpNumberOfEventsRead passed in arguments' do
|
66
|
+
expect do
|
67
|
+
Timeout::timeout(5) do
|
68
|
+
subject.PeekConsoleInputW(*@args.values) until @args[:lpNumberOfEventsRead].read_short > 0
|
69
|
+
end
|
70
|
+
end.to_not raise_error
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'updates the [:lpBuffer].INPUT_RECORD.EventType passed in arguments' do
|
74
|
+
#puts ">#{@args[:lpBuffer].first}"
|
75
|
+
# expected [] to respond to `a??`
|
76
|
+
#expect(args[:lpBuffer]).to be_a?(described_class::PINPUT_RECORD)
|
77
|
+
|
78
|
+
expect(0.upto(4).map {|n| 2**n }).to include(@args[:lpBuffer].first.EventType)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'updates the [:lpBuffer].INPUT_RECORD.Event.KeyEvent passed in arguments' do
|
82
|
+
expect(@args[:lpBuffer].first.Event.KeyEvent.uChar).to_not eql(0)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '::ReadConsoleInputW' do
|
88
|
+
|
89
|
+
before :all do
|
90
|
+
@rargs = {
|
91
|
+
:hConsoleInput => std_handle,
|
92
|
+
:lpBuffer => described_class::PINPUT_RECORD.new(len = 2),
|
93
|
+
:nLength => len,
|
94
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
95
|
+
}
|
96
|
+
write_console_input_test
|
97
|
+
described_class.ReadConsoleInputW(*@rargs.values)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'pulls input_records from queue' do
|
101
|
+
expect(@rargs[:lpNumberOfEventsRead].read_short).to be > 1
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'updates the [:lpBuffer].INPUT_RECORD.EventType passed in arguments' do
|
105
|
+
expect(@rargs[:lpBuffer].first.EventType).to eql(1)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'updates the [:lpBuffer].INPUT_RECORD.Event.KeyEvent passed in arguments' do
|
109
|
+
expect(@rargs[:lpBuffer].first.Event.KeyEvent.uChar).to_not be_nil
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '::PeekConsoleInputW' do
|
115
|
+
|
116
|
+
before :all do
|
117
|
+
@pargs = {
|
118
|
+
:hConsoleInput => std_handle,
|
119
|
+
:lpBuffer => described_class::PINPUT_RECORD.new(len = 1),
|
120
|
+
:nLength => len,
|
121
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
122
|
+
}
|
123
|
+
@prargs = {
|
124
|
+
:hConsoleInput => std_handle,
|
125
|
+
:lpBuffer => described_class::PINPUT_RECORD.new(len = 1),
|
126
|
+
:nLength => len,
|
127
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'does not effect the queue' do
|
132
|
+
expect(subject.PeekConsoleInputW(*@pargs.values)).to be == subject.ReadConsoleInputW(*@prargs.values)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api/constants'
|
4
|
+
|
5
|
+
require 'vigilem/win32_api/types'
|
6
|
+
|
7
|
+
require 'vigilem/win32_api/console_input_events'
|
8
|
+
|
9
|
+
|
10
|
+
describe Vigilem::Win32API::ConsoleInputEvents do
|
11
|
+
|
12
|
+
describe described_class::MOUSE_EVENT_RECORD do
|
13
|
+
it_behaves_like 'attributes_and_size_test' do
|
14
|
+
let(:ary) { [:dwMousePosition, :dwButtonState, :dwControlKeyState, :dwEventFlags] }
|
15
|
+
let(:sze) { 16 }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe described_class::WINDOW_BUFFER_SIZE_RECORD do
|
20
|
+
it_behaves_like 'attributes_and_size_test' do
|
21
|
+
let(:ary) { [:dwSize] }
|
22
|
+
let(:sze) { 4 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe described_class::MENU_EVENT_RECORD do
|
27
|
+
it_behaves_like 'attributes_and_size_test' do
|
28
|
+
let(:ary) { [:dwCommandId] }
|
29
|
+
let(:sze) { 4 }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe described_class::FOCUS_EVENT_RECORD do
|
34
|
+
it_behaves_like 'attributes_and_size_test' do
|
35
|
+
let(:ary) { [:bSetFocus] }
|
36
|
+
let(:sze) { 4 }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe described_class::KEY_EVENT_RECORD do
|
41
|
+
it_behaves_like 'attributes_and_size_test' do
|
42
|
+
let(:ary) { [:bKeyDown, :wRepeatCount, :wVirtualKeyCode, :wVirtualScanCode, :uChar, :dwControlKeyState] }
|
43
|
+
let(:sze) { 16 }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '::vk_names' do
|
48
|
+
it 'has the list of events' do
|
49
|
+
expect(described_class.vk_names).to eql([:KEY_EVENT, :MOUSE_EVENT, :WINDOW_BUFFER_SIZE_EVENT, :MENU_EVENT, :FOCUS_EVENT])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '::vk_hash' do
|
54
|
+
it 'to be a hash with keys equal to Constant values and values equal to constant names' do
|
55
|
+
expect(described_class.vk_hash).to eql(described_class.vk_names.map.with_object({}) {|vk, hsh| hsh[Vigilem::Win32API::Constants::Events.const_get(vk)] = vk })
|
56
|
+
end
|
57
|
+
end
|
58
|
+
=begin
|
59
|
+
describe '::structs' do
|
60
|
+
it 'will return an array of the structs that are the event types' do
|
61
|
+
expect(described_class.structs.sort).to eq([described_class::KEY_EVENT_RECORD,
|
62
|
+
described_class::MOUSE_EVENT_RECORD, described_class::WINDOW_BUFFER_SIZE_RECORD,
|
63
|
+
described_class::MENU_EVENT_RECORD, described_class::FOCUS_EVENT_RECORD].sort)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
=end
|
67
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api/dom'
|
4
|
+
|
5
|
+
describe Vigilem::Win32API::DOM::Adapter do
|
6
|
+
|
7
|
+
let(:api) { Vigilem::Win32API }
|
8
|
+
|
9
|
+
after(:example) do
|
10
|
+
flush
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:dw_numlock) { 0x0020 }
|
14
|
+
|
15
|
+
let(:input_record) {
|
16
|
+
api::INPUT_RECORD[api::KEY_EVENT, {:KeyEvent => [1, 1, 0x41, 30, {:UnicodeChar => 65 }, dw_numlock]}]
|
17
|
+
}
|
18
|
+
|
19
|
+
def key_event_template(type, opts={})
|
20
|
+
{
|
21
|
+
:bubbles=>false, :cancelable=>false, :code=>"KeyA", :detail=>0, :isTrusted=>true, :isComposing=>false,
|
22
|
+
:key=>"A", :location=>0,
|
23
|
+
:modifier_state=>{"Accel"=>false, "Alt"=>false, "AltGraph"=>false, "CapsLock"=>false,
|
24
|
+
"Control"=>false, "Fn"=>false, "FnLock"=>false, "Hyper"=>false, "Meta"=>false,
|
25
|
+
"NumLock"=>false, "OS"=>false, "ScrollLock"=>false, "Shift"=>false, "Super"=>false,
|
26
|
+
"Symbol"=>false, "SymbolLock"=>false},
|
27
|
+
:os_specific=>{:bKeyDown=>1, :wRepeatCount=>1, :wVirtualKeyCode=>65, :wVirtualScanCode=>30,
|
28
|
+
:uChar=>{:UnicodeChar=>65, :AsciiChar=>65}, :dwControlKeyState=>32},
|
29
|
+
:repeat=>false, :timeStamp=>kind_of(Numeric), :type=>type,
|
30
|
+
:view=>nil
|
31
|
+
}.merge(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#handle' do
|
35
|
+
it 'sends Win32API::KEY_EVENT_RECORD events to #to_dom_key_event' do
|
36
|
+
allow(subject).to receive(:to_dom_key_event)
|
37
|
+
expect(subject).to receive(:to_dom_key_event)
|
38
|
+
subject.handle(input_record.event_record)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#read_many' do
|
43
|
+
it 'blocks until the number passed in is reached' do
|
44
|
+
allow(subject.send(:link)).to receive(:ReadConsoleInput) { [input_record] }
|
45
|
+
expect do
|
46
|
+
Timeout::timeout(4) {
|
47
|
+
subject.read_many(3)
|
48
|
+
}
|
49
|
+
end.to raise_error(Timeout::Error)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'retrieves multiple dom message' do
|
53
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record, input_record])
|
54
|
+
Timeout::timeout(4) {
|
55
|
+
expect(subject.read_many(2)).to contain_exactly(
|
56
|
+
an_object_having_attributes(key_event_template("keydown")),
|
57
|
+
an_object_having_attributes(key_event_template("keypress"))
|
58
|
+
)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'will fill the buffer with the leftovers' do
|
63
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record, input_record])
|
64
|
+
subject.read_many(2)
|
65
|
+
Timeout::timeout(4) {
|
66
|
+
expect(subject.buffer.to_a).to contain_exactly(
|
67
|
+
an_object_having_attributes(key_event_template("keydown", repeat: true)),
|
68
|
+
an_object_having_attributes(key_event_template("keypress", repeat: true))
|
69
|
+
)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#read_many_nonblock' do
|
75
|
+
|
76
|
+
it %q{doesn't block and returns nil when nothing in the queue} do
|
77
|
+
allow(subject.send(:link)).to receive(:read_console_input).with(:nLength => 1, :blocking => true).and_call_original
|
78
|
+
allow(subject.send(:link)).to receive(:ReadConsoleInput) { sleep 3.5 }
|
79
|
+
expect do
|
80
|
+
Timeout::timeout(3) {
|
81
|
+
subject.read_many_nonblock(3)
|
82
|
+
}
|
83
|
+
end.not_to raise_error
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'retrieves multiple dom messages' do
|
87
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record, input_record])
|
88
|
+
expect(subject.read_many_nonblock(2)).to contain_exactly(
|
89
|
+
an_object_having_attributes(key_event_template("keydown")),
|
90
|
+
an_object_having_attributes(key_event_template("keypress"))
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'will fill the buffer with the leftovers' do
|
95
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record, input_record])
|
96
|
+
subject.read_many_nonblock(2)
|
97
|
+
expect(subject.buffer.to_a).to contain_exactly(
|
98
|
+
an_object_having_attributes(key_event_template("keydown", repeat: true)),
|
99
|
+
an_object_having_attributes(key_event_template("keypress", repeat: true))
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
class UnknownEvent
|
104
|
+
def event_record
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'will return emty array if none of the events are handled' do
|
109
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([UnknownEvent.new])
|
110
|
+
expect(subject.read_many_nonblock(2)).to eql([])
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#read_one' do
|
116
|
+
|
117
|
+
it 'retrieves one dom message' do
|
118
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record])
|
119
|
+
Timeout::timeout(4) {
|
120
|
+
expect(subject.read_one).to be_a(Vigilem::DOM::KeyboardEvent) and
|
121
|
+
have_attributes(key_event_template("keydown"))
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'will block when no messages in buffer and non in the windows message queue' do
|
126
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_call_original
|
127
|
+
allow(subject.send(:link)).to receive(:ReadConsoleInput) { sleep 2.5 }
|
128
|
+
expect do
|
129
|
+
Timeout::timeout(2) {
|
130
|
+
subject.read_one
|
131
|
+
}
|
132
|
+
end.to raise_error(Timeout::Error)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#read_one_nonblock' do
|
137
|
+
|
138
|
+
it 'retrieves one dom message' do
|
139
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record])
|
140
|
+
Timeout::timeout(4) {
|
141
|
+
expect(subject.read_one_nonblock).to be_a(Vigilem::DOM::KeyboardEvent) and
|
142
|
+
have_attributes(key_event_template("keydown"))
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'will fill the buffer with the leftovers' do
|
147
|
+
allow(subject.send(:link)).to receive(:read_many_nonblock).and_return([input_record])
|
148
|
+
subject.read_one_nonblock
|
149
|
+
expect(subject.buffer.to_a).to contain_exactly(
|
150
|
+
an_object_having_attributes(key_event_template("keypress"))
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
it %q{will not block when no messages in buffer} do
|
155
|
+
allow(subject.send(:link)).to receive(:read_console_input).with(:nLength => 1, :blocking => false).and_call_original
|
156
|
+
allow(subject.send(:link)).to receive(:ReadConsoleInput) { sleep 2.5 }
|
157
|
+
expect do
|
158
|
+
Timeout::timeout(2) {
|
159
|
+
subject.read_one_nonblock
|
160
|
+
}
|
161
|
+
end.not_to raise_error
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/dom'
|
4
|
+
|
5
|
+
require 'vigilem/win32_api'
|
6
|
+
|
7
|
+
require 'vigilem/win32_api/input_system_handler'
|
8
|
+
|
9
|
+
require 'vigilem/win32_api/dom/input_record_utils'
|
10
|
+
|
11
|
+
|
12
|
+
describe Vigilem::Win32API::DOM::InputRecordUtils do
|
13
|
+
|
14
|
+
let(:api) { Vigilem::Win32API }
|
15
|
+
|
16
|
+
let(:dw_numlock) { 0x0020 }
|
17
|
+
|
18
|
+
let(:dw_lmenu) { 0x0002 }
|
19
|
+
|
20
|
+
let(:dw_rmenu) { 0x0001 }
|
21
|
+
|
22
|
+
let(:dw_shift) { 0x0010 }
|
23
|
+
|
24
|
+
let(:key_event_record) { api::KEY_EVENT_RECORD[1, 1, 0x41, 30, {:UnicodeChar => 65 }, dw_numlock] }
|
25
|
+
|
26
|
+
let(:event_record_lmenu) { api::KEY_EVENT_RECORD[1, 1, 0x12, 30, {:UnicodeChar => 0 }, dw_numlock + dw_lmenu] }
|
27
|
+
|
28
|
+
let!(:host) do
|
29
|
+
class IRU
|
30
|
+
include Vigilem::Core::Adapters::Adapter
|
31
|
+
include Vigilem::Win32API::Rubyized
|
32
|
+
include Vigilem::Win32API::DOM::InputRecordUtils
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
self.win32_api_rubyized_src = self.link
|
36
|
+
end
|
37
|
+
|
38
|
+
def link
|
39
|
+
@isys ||= Vigilem::Win32API::InputSystemHandler.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
IRU.new
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#current_keys' do
|
46
|
+
it 'defaults to an empty array' do
|
47
|
+
expect(host.current_keys).to eql([])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#to_dom_key_event' do
|
52
|
+
|
53
|
+
def key_event(type, opts={})
|
54
|
+
{
|
55
|
+
bubbles: false, cancelable: false, code: "KeyA", detail: 0, isTrusted: true,
|
56
|
+
isComposing: false, key: "A", location: 0,
|
57
|
+
modifier_state: {"Accel"=>false, "Alt"=>false, "AltGraph"=>false, "CapsLock"=>false, "Control"=>false,
|
58
|
+
"Fn"=>false, "FnLock"=>false, "Hyper"=>false, "Meta"=>false, "NumLock"=>false, "OS"=>false,
|
59
|
+
"ScrollLock"=>false, "Shift"=>false, "Super"=>false, "Symbol"=>false, "SymbolLock"=>false},
|
60
|
+
os_specific: {:bKeyDown=>1, :wRepeatCount=>1, :wVirtualKeyCode=>65, :wVirtualScanCode=>30,
|
61
|
+
:uChar=>{:UnicodeChar=>65, :AsciiChar=>65}, :dwControlKeyState=>dw_numlock},
|
62
|
+
repeat: false, timeStamp: kind_of(Numeric), type: type, view: nil
|
63
|
+
}.merge(opts)
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'simple conversion' do
|
67
|
+
|
68
|
+
let!(:result) { host.to_dom_key_event(key_event_record) }
|
69
|
+
|
70
|
+
it 'converts an input_record to a DOM Event' do
|
71
|
+
expect(result).to match [
|
72
|
+
an_object_having_attributes(key_event('keydown')),
|
73
|
+
an_object_having_attributes(key_event('keypress'))
|
74
|
+
]
|
75
|
+
end
|
76
|
+
|
77
|
+
# @todo be more specific
|
78
|
+
it 'updates #current_keys' do
|
79
|
+
expect(host.current_keys.size).to be > 0
|
80
|
+
end
|
81
|
+
end
|
82
|
+
context 'repeats' do
|
83
|
+
|
84
|
+
let(:repeat_results) { 1.upto(2).map {|n| host.to_dom_key_event(key_event_record) } }
|
85
|
+
|
86
|
+
it 'converts an input_record to a DOM Event and keeps track of state' do
|
87
|
+
expect(repeat_results).to match [
|
88
|
+
[an_object_having_attributes(key_event('keydown')), # its wrongly making this repeat
|
89
|
+
an_object_having_attributes(key_event('keypress'))], # its wrongly making this repeat
|
90
|
+
[an_object_having_attributes(key_event('keydown', repeat: true)),
|
91
|
+
an_object_having_attributes(key_event('keypress', repeat: true))] # chrome 39.0.2171.95 m produces `false'
|
92
|
+
]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#dw_control_key_state_vks' do
|
99
|
+
it 'lists the names of the constants that represent the dw_control_state' do
|
100
|
+
expect(host.dw_control_key_state_vks(dw_numlock + dw_lmenu)).to eql([:LEFT_ALT_PRESSED, :NUMLOCK_ON])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#location_less_vks_map' do
|
105
|
+
it 'returns a Hash with vk as keys' do
|
106
|
+
expect(host.location_less_vks_map.keys).to all( be_instance_of(Symbol) )
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'returns a Hash with Regexp as values' do
|
110
|
+
expect(host.location_less_vks_map.values).to all( be_instance_of(Regexp) )
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#vk_without_location_info?' do
|
115
|
+
it 'returns whether or not a virtual key need location info' do
|
116
|
+
expect(:VK_MENU).to be_truthy
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#shift_scan_code_to_location_vk' do
|
121
|
+
|
122
|
+
let(:l_shift) { IRU::VK_LSHIFT }
|
123
|
+
|
124
|
+
let(:l_shift_vsc) { api.MapVirtualKeyW(l_shift, IRU::MapVK::VK_TO_VSC) }
|
125
|
+
|
126
|
+
it 'creates a hash that maps the scancodes to :VK_LSHIFT and :VK_RSHIFT ' do
|
127
|
+
expect(host.shift_scan_code_to_location_vk[l_shift_vsc]).to eql(:VK_LSHIFT)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '::flip_lr_sides' do
|
132
|
+
it 'converts "l" or "L" to "r" or "R"' do
|
133
|
+
expect(described_class.flip_lr_sides('L')).to eql('R')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '::lr_location_from_name' do
|
138
|
+
it 'pulls the "L" or "R" from the string name' do
|
139
|
+
expect(described_class.lr_location_from_name(:LEFT_CTRL_PRESSED)).to eql('L')
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '::empty_or_null?' do
|
144
|
+
it 'returns true for empty Strings ' do
|
145
|
+
expect(described_class.empty_or_null?("")).to be_truthy
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'returns true for a String with only "\x00"' do
|
149
|
+
expect(described_class.empty_or_null?("\x00\x00")).to be_truthy
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#dom_location' do
|
154
|
+
|
155
|
+
let(:vk_menu_vsc) { api.MapVirtualKeyW(IRU::VK_MENU, IRU::MapVK::VK_TO_VSC) }
|
156
|
+
|
157
|
+
context ', both ALT\'s are pressed yet niether in the current_keys' do
|
158
|
+
|
159
|
+
let(:dw_state_names) { host.dw_control_key_state_vks(3) }
|
160
|
+
|
161
|
+
it 'will raise an error in this situation' do
|
162
|
+
expect { host.dom_location(:VK_MENU, vk_menu_vsc, dw_state_names) }.to raise_error
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'generic vk with dw_state_names' do
|
168
|
+
|
169
|
+
let(:dw_state_names) { host.dw_control_key_state_vks(2) }
|
170
|
+
|
171
|
+
let(:dw_state_names_right) { host.dw_control_key_state_vks(1) }
|
172
|
+
|
173
|
+
it 'will get left the location from the dw_state_name' do
|
174
|
+
expect(host.dom_location(:VK_MENU, vk_menu_vsc, dw_state_names)).to eql(1)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'will get right the location from the dw_state_name' do
|
178
|
+
expect(host.dom_location(:VK_MENU, vk_menu_vsc, dw_state_names_right)).to eql(2)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#lr_not_in_name' do
|
185
|
+
|
186
|
+
let(:vk_menu_vsc) { api.MapVirtualKeyW(IRU::VK_MENU, IRU::MapVK::VK_TO_VSC) }
|
187
|
+
|
188
|
+
let(:vk_rmenu_vsc) { api.MapVirtualKeyW(IRU::VK_RMENU, IRU::MapVK::VK_TO_VSC) }
|
189
|
+
|
190
|
+
let(:vk_rshift_vsc) { api.MapVirtualKeyW(IRU::VK_RSHIFT, IRU::MapVK::VK_TO_VSC) }
|
191
|
+
|
192
|
+
let(:lr_menu_dw_state_names) { host.dw_control_key_state_vks(dw_numlock + dw_lmenu + dw_rmenu) }
|
193
|
+
|
194
|
+
let(:l_menu_dw_state_names) { host.dw_control_key_state_vks(dw_numlock + dw_lmenu) }
|
195
|
+
|
196
|
+
let(:dw_state_names_w_shift) { host.dw_control_key_state_vks(dw_shift) }
|
197
|
+
|
198
|
+
it 'gets the location info from virtual-key and dw_state_names' do
|
199
|
+
expect(host.lr_not_in_name(:VK_MENU, vk_menu_vsc, l_menu_dw_state_names)).to eql('l')
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'gets the location info from the scan code' do
|
203
|
+
expect(host.lr_not_in_name(:VK_SHIFT, vk_rshift_vsc, dw_state_names_w_shift)).to eql('r')
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with current keys' do
|
207
|
+
let!(:converted_result) { host.to_dom_key_event(event_record_lmenu) }
|
208
|
+
|
209
|
+
it 'gets the location info from the #current keys' do
|
210
|
+
expect(host.lr_not_in_name(:VK_MENU, vk_rmenu_vsc, lr_menu_dw_state_names)).to eql('r')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '#dom_key' do
|
216
|
+
|
217
|
+
let(:l_shift) { IRU::VK_LSHIFT }
|
218
|
+
|
219
|
+
it 'converts modifier virtual-key to dom_key' do
|
220
|
+
expect(host.dom_key(:VK_SHIFT, 0)).to eql('Shift')
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'converts character virtual-key to dom_key' do
|
224
|
+
expect(host.dom_key(:VK_A, 97)).to eql('a')
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe '#dom_code' do
|
229
|
+
it 'produces the code attribute for a character key For DOM::Keyboard Event' do
|
230
|
+
expect(host.dom_code(:VK_A, 65, 0)).to eql('KeyA')
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'produces the code attribute for a modifier key For DOM::Keyboard Event' do
|
234
|
+
expect(host.dom_code(:VK_MENU, 0, 'l')).to eql('AltLeft')
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'produces the code attribute for a modifier key For DOM::Keyboard Event' do
|
238
|
+
expect(host.dom_code(:VK_RETURN, 10, 3, :ENHANCED_KEY)).to eql('NumpadEnter')
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe '#dom_modifiers' do
|
243
|
+
|
244
|
+
it 'convert dw_control_names to more typical modifier names' do
|
245
|
+
expect(::VDOM::KeyboardEvent).to receive(:shared_keyboard_and_mouse_event_init).with([:alt, :numlock])
|
246
|
+
host.dom_modifiers(:LEFT_ALT_PRESSED, :NUMLOCK_ON)
|
247
|
+
end
|
248
|
+
it 'converts dw_control_state_names to an array of symbols' do
|
249
|
+
expect(host.dom_modifiers(:LEFT_ALT_PRESSED, :NUMLOCK_ON)).to eql({ :altKey=>true, :keyModifierStateAltGraph=>false, :keyModifierStateCapsLock=>false,
|
250
|
+
:ctrlKey=>false, :keyModifierStateFn=>false, :keyModifierStateFnLock=>false, :keyModifierStateHyper=>false,
|
251
|
+
:metaKey=>false, :keyModifierStateNumLock=>true, :keyModifierStateOS=>false, :keyModifierStateScrollLock=>false,
|
252
|
+
:shiftKey=>false, :keyModifierStateSuper=>false, :keyModifierStateSymbol=>false, :keyModifierStateSymbolLock=>false })
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|