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,96 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
describe Vigilem::Win32API::Eventable do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
EventableAdapter = Class.new do
|
7
|
+
include Vigilem::Core::Adapters::Adapter
|
8
|
+
include Vigilem::Win32API::Rubyized
|
9
|
+
include Vigilem::Win32API::Eventable
|
10
|
+
def initialize(lnk=Vigilem::Win32API::InputSystemHandler.new)
|
11
|
+
initialize_adapter(lnk)
|
12
|
+
self.win32_api_rubyized_source = link()
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:adapt) do
|
18
|
+
EventableAdapter.new
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'has_any?' do
|
22
|
+
|
23
|
+
it 'checks peek_console_input and if the lpBuffer has any messages' do
|
24
|
+
allow(adapt).to receive(:peek_console_input) { %w(a b c) }
|
25
|
+
expect(adapt.has_any?).to be_truthy
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns false when peek_console_input lpBuffer is empty' do
|
29
|
+
allow(adapt).to receive(:peek_console_input) { [] }
|
30
|
+
expect(adapt.has_any?).to be_falsey
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#read_many_nonblock' do
|
35
|
+
|
36
|
+
it 'reads many messages from the input buffer returning if it would block/stopping at limit' do
|
37
|
+
allow(adapt).to receive(:peek_console_input) { %w(a b c) }
|
38
|
+
allow(adapt).to receive(:read_console_input).with(:nLength => 1, :blocking => false) { %w(a) }
|
39
|
+
expect(adapt.read_many_nonblock).to eql(%w(a))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#read_many' do
|
44
|
+
|
45
|
+
it 'reads the default amount of messages from the input buffer' do
|
46
|
+
allow(adapt).to receive(:read_console_input).with(:nLength => 1, :blocking => true) { %w(a) }
|
47
|
+
expect(adapt.read_many).to eql(%w(a))
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'blocks until the number passed in is reached' do
|
51
|
+
allow(adapt).to receive(:read_console_input).with(:nLength => 3, :blocking => true).and_call_original
|
52
|
+
allow(adapt.send(:link)).to receive(:ReadConsoleInput) { %w(a) }
|
53
|
+
expect do
|
54
|
+
Timeout::timeout(4) {
|
55
|
+
adapt.read_many(3)
|
56
|
+
}
|
57
|
+
end.to raise_error(Timeout::Error)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'reads many messages from the input_buffer' do
|
61
|
+
allow(adapt).to receive(:read_console_input).with(:nLength => 3, :blocking => true) { %w(a b c) }
|
62
|
+
expect(adapt.read_many(3)).to eql(%w(a b c))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'read_one_nonblock' do
|
67
|
+
|
68
|
+
it 'reads one message off the input buffer' do
|
69
|
+
allow(adapt).to receive(:peek_console_input) { %w(a) }
|
70
|
+
allow(adapt).to receive(:read_console_input) { %w(a) }
|
71
|
+
expect(adapt.read_one_nonblock).to eql('a')
|
72
|
+
end
|
73
|
+
|
74
|
+
it %q(doesn't block) do
|
75
|
+
allow(adapt).to receive(:peek_console_input) { [] }
|
76
|
+
expect(adapt.read_one_nonblock).to eql(nil)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#read_one' do
|
81
|
+
it 'reads one message off the input buffer' do
|
82
|
+
allow(adapt).to receive(:read_console_input) { %w(a) }
|
83
|
+
expect(adapt.read_one).to eql('a')
|
84
|
+
end
|
85
|
+
|
86
|
+
it %q(blocks when no messages are in the buffer) do
|
87
|
+
allow(adapt).to receive(:read_console_input).and_call_original
|
88
|
+
allow(adapt.send(:link)).to receive(:ReadConsoleInput) { sleep 4 }
|
89
|
+
expect do
|
90
|
+
Timeout::timeout(3) do
|
91
|
+
adapt.read_one
|
92
|
+
end
|
93
|
+
end.to raise_error(Timeout::Error)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api/types'
|
4
|
+
require 'vigilem/win32_api/console_input_events'
|
5
|
+
|
6
|
+
require 'vigilem/win32_api/input__record'
|
7
|
+
|
8
|
+
describe Vigilem::Win32API do
|
9
|
+
|
10
|
+
|
11
|
+
describe 'constants' do
|
12
|
+
specify { expect(described_class::INPUT_RECORD).to eql(described_class::InputRecord) }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe described_class::INPUT_RECORD do
|
16
|
+
|
17
|
+
it 'will create a shell object, when no arguments, without error' do
|
18
|
+
expect { described_class.new }.to_not raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '::EventType' do
|
22
|
+
it 'will have an EventType' do
|
23
|
+
expect(described_class.new).to respond_to(:EventType)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'return the ID representing the window event type' do
|
27
|
+
expect(described_class[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97 }, 32]}].EventType).to eql(1)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '::Event' do
|
32
|
+
it 'will be a union' do
|
33
|
+
expect(subject.Event).to be_a(FFI::Union)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:ir) {
|
38
|
+
ipt = Vigilem::Win32API::INPUT_RECORD.new()
|
39
|
+
ipt.type_of(:Event).struct_class.new()
|
40
|
+
ipt
|
41
|
+
}
|
42
|
+
|
43
|
+
describe described_class::Event do
|
44
|
+
let(:correct) do
|
45
|
+
{ :KeyEvent => (api = Vigilem::Win32API)::KEY_EVENT_RECORD,
|
46
|
+
:MouseEvent => api::MOUSE_EVENT_RECORD,
|
47
|
+
:WindowBufferSizeEvent => api::WINDOW_BUFFER_SIZE_RECORD,
|
48
|
+
:MenuEvent => api::MENU_EVENT_RECORD,
|
49
|
+
:FocusEvent => api::FOCUS_EVENT_RECORD
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
specify 'that fields in the the union match the correct class' do
|
54
|
+
expect(ir.Event.class.layout.fields.all? {|fld| correct[fld.name].name == fld.type.struct_class.name }).to be_truthy
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#to_h' do
|
59
|
+
|
60
|
+
let(:hsh) { input_record.to_h }
|
61
|
+
|
62
|
+
it 'converts the struct attributes into a Hash' do
|
63
|
+
expect(hsh[:EventType]).to eq(1)
|
64
|
+
expect(hsh[:Event]).to eql({:FocusEvent=>{:bSetFocus=>1},
|
65
|
+
:KeyEvent=>{:bKeyDown=>1, :wRepeatCount=>1, :wVirtualKeyCode=>70, :wVirtualScanCode=>33,
|
66
|
+
:uChar=>{:UnicodeChar=>97, :AsciiChar=>97}, :dwControlKeyState=>32},
|
67
|
+
:MenuEvent=>{:dwCommandId=>1},
|
68
|
+
:MouseEvent=>{:dwMousePosition=>{:x=>1, :y=>0},
|
69
|
+
:dwButtonState=>4587521, :dwControlKeyState=>6357025, :dwEventFlags=>32},
|
70
|
+
:WindowBufferSizeEvent=>{:dwSize=>{:x=>1, :y=>0}}
|
71
|
+
})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#type' do
|
76
|
+
it 'returns the EventType' do
|
77
|
+
expect(input_record.type).to eql(input_record.EventType)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
describe '#event_record' do
|
81
|
+
|
82
|
+
it %q(returns the Event that's populated) do
|
83
|
+
expect(input_record.event_record.bytes).to eql(input_record.Event.KeyEvent.bytes)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
let(:input_record) do
|
88
|
+
described_class[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97 }, 32]}]
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:event_record_class) { 'Vigilem::Win32API::ConsoleInputEvents::KEY_EVENT_RECORD' }
|
92
|
+
|
93
|
+
context 'class_methods' do
|
94
|
+
|
95
|
+
describe '::event_record' do
|
96
|
+
it %q(returns the Event that's populated) do
|
97
|
+
expect(described_class.event_record(input_record).class.name).to eql(event_record_class)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'instance methods' do
|
103
|
+
|
104
|
+
end
|
105
|
+
=begin
|
106
|
+
describe '::event_types' do
|
107
|
+
it %q(will return the id's of windows events) do
|
108
|
+
expect(described_class.event_types).to eq([16, 1, 8, 2, 4])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
=end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api/input_system_handler'
|
4
|
+
|
5
|
+
describe Vigilem::Win32API::InputSystemHandler do
|
6
|
+
|
7
|
+
describe '#GetStdHandle' do
|
8
|
+
|
9
|
+
it 'forwards the call to the underlying system' do
|
10
|
+
expect(subject.send(:link)).to receive(:GetStdHandle)
|
11
|
+
subject.GetStdHandle(Vigilem::Win32API::STD_INPUT_HANDLE)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'private' do
|
16
|
+
|
17
|
+
let(:input_record) { Vigilem::Win32API::INPUT_RECORD[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97}, 32]}] }
|
18
|
+
let(:input_record2) { Vigilem::Win32API::INPUT_RECORD[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97}, 32]}] }
|
19
|
+
|
20
|
+
let(:events) { [input_record, input_record2] }
|
21
|
+
|
22
|
+
let(:lpBuffer) { Vigilem::Win32API::PINPUT_RECORD.new(3) }
|
23
|
+
|
24
|
+
let(:lpNumberOfEventsRead) { FFI::MemoryPointer.new(:dword, 1) }
|
25
|
+
|
26
|
+
describe '#_update_out_args' do
|
27
|
+
|
28
|
+
let!(:input_system) do
|
29
|
+
allow(subject).to receive(:_update_out_args).and_call_original
|
30
|
+
subject
|
31
|
+
end
|
32
|
+
|
33
|
+
let!(:result) { input_system.send(:_update_out_args, lpBuffer, lpNumberOfEventsRead, events) }
|
34
|
+
|
35
|
+
it 'updates lpNumberOfEventsRead' do
|
36
|
+
expect(FFIUtils.read_typedef(lpNumberOfEventsRead, :dword)).to eql(events.size)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#PeekConsoleInput' do
|
43
|
+
context 'empty buffer' do
|
44
|
+
let(:args) do
|
45
|
+
{
|
46
|
+
:hConsoleInput => Vigilem::Win32API.GetStdHandle(Vigilem::Win32API::STD_INPUT_HANDLE),
|
47
|
+
:lpBuffer => Vigilem::Win32API::PINPUT_RECORD.new(len = 1),
|
48
|
+
:nLength => len,
|
49
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
let!(:input_system) do
|
54
|
+
lnk = spy(subject.send(:link), :semaphore => @monitor ||= Monitor.new)
|
55
|
+
subject.send(:link=, lnk)
|
56
|
+
allow(subject).to receive(:buffer).and_call_original
|
57
|
+
allow(subject).to receive(:PeekConsoleInput).and_call_original
|
58
|
+
subject.PeekConsoleInput(*args.values)
|
59
|
+
subject
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'checks the buffer first' do
|
63
|
+
expect(input_system).to have_received(:buffer).at_least(1).times
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'calls the link#PeekConsoleInput' do
|
67
|
+
expect(input_system.send(:link)).to have_received(:PeekConsoleInputW)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
context 'buffer > length' do
|
71
|
+
let(:input_record) { Vigilem::Win32API::INPUT_RECORD[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97}, 32]}] }
|
72
|
+
let!(:input_system) do
|
73
|
+
subject.buffer.concat(3.times.map { input_record.dup })
|
74
|
+
lnk = spy(subject.send(:link), :semaphore => @monitor ||= Monitor.new)
|
75
|
+
subject.send(:link=, lnk)
|
76
|
+
allow(subject).to receive(:buffer).and_call_original
|
77
|
+
allow(subject).to receive(:PeekConsoleInput).and_call_original
|
78
|
+
subject.PeekConsoleInput(*args.values)
|
79
|
+
subject
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:args) do
|
83
|
+
{
|
84
|
+
:hConsoleInput => Vigilem::Win32API.GetStdHandle(Vigilem::Win32API::STD_INPUT_HANDLE),
|
85
|
+
:lpBuffer => Vigilem::Win32API::PINPUT_RECORD.new(len = 1),
|
86
|
+
:nLength => len,
|
87
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'checks the buffer first then call the system' do
|
92
|
+
expect(subject).to receive(:buffer).and_call_original
|
93
|
+
subject.PeekConsoleInput(*args.values)
|
94
|
+
end
|
95
|
+
|
96
|
+
it %q{doesn't call link#PeekConsoleInput} do
|
97
|
+
expect(input_system.send(:link)).not_to have_received(:PeekConsoleInputW)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#ReadConsoleInput' do
|
105
|
+
context 'empty buffer' do
|
106
|
+
let(:args) do
|
107
|
+
{
|
108
|
+
:hConsoleInput => Vigilem::Win32API.GetStdHandle(Vigilem::Win32API::STD_INPUT_HANDLE),
|
109
|
+
:lpBuffer => Vigilem::Win32API::PINPUT_RECORD.new(len = 3),
|
110
|
+
:nLength => len,
|
111
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
let(:input_record) { Vigilem::Win32API::INPUT_RECORD[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97}, 32]}] }
|
116
|
+
|
117
|
+
let!(:input_system) do
|
118
|
+
lnk = spy(subject.send(:link), :semaphore => @monitor ||= Monitor.new)
|
119
|
+
subject.send(:link=, lnk)
|
120
|
+
allow(subject).to receive(:buffer).and_call_original
|
121
|
+
allow(subject).to receive(:ReadConsoleInput).and_call_original
|
122
|
+
subject.ReadConsoleInput(*args.values)
|
123
|
+
subject
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'checks the buffer first' do
|
127
|
+
expect(input_system).to have_received(:buffer).at_least(:once)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'calls the link#ReadConsoleInput' do
|
131
|
+
expect(input_system.send(:link)).to have_received(:ReadConsoleInputW).at_least(:once)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'buffer > length' do
|
136
|
+
let(:input_record) { Vigilem::Win32API::INPUT_RECORD[Vigilem::Win32API::KEY_EVENT, {:KeyEvent => [1, 1, 70, 33, {:UnicodeChar => 97}, 32]}] }
|
137
|
+
let!(:input_system) do
|
138
|
+
subject.buffer.concat(3.times.map { input_record.dup })
|
139
|
+
lnk = spy(subject.send(:link), :semaphore => @monitor ||= Monitor.new)
|
140
|
+
subject.send(:link=, lnk)
|
141
|
+
allow(subject).to receive(:buffer).and_call_original
|
142
|
+
allow(subject).to receive(:PeekConsoleInput).and_call_original
|
143
|
+
subject.ReadConsoleInput(*args.values)
|
144
|
+
subject
|
145
|
+
end
|
146
|
+
|
147
|
+
let(:args) do
|
148
|
+
{
|
149
|
+
:hConsoleInput => Vigilem::Win32API.GetStdHandle(Vigilem::Win32API::STD_INPUT_HANDLE),
|
150
|
+
:lpBuffer => Vigilem::Win32API::PINPUT_RECORD.new(len = 1),
|
151
|
+
:nLength => len,
|
152
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:dword, 1)
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'checks the buffer first then call the system' do
|
157
|
+
expect(subject).to receive(:buffer).at_least(:once).and_call_original
|
158
|
+
subject.ReadConsoleInput(*args.values)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api/p_input__record'
|
4
|
+
|
5
|
+
describe Vigilem::Win32API::PINPUT_RECORD do
|
6
|
+
|
7
|
+
let(:api) { Vigilem::Win32API }
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
@pir = described_class.new(3,
|
11
|
+
api::INPUT_RECORD[:EventType => 0x0001, :Event => api::INPUT_RECORD::Event.new],
|
12
|
+
api::INPUT_RECORD[:EventType => 0x0008, :Event => api::INPUT_RECORD::Event.new])
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { @pir }
|
16
|
+
|
17
|
+
context 'when first created' do
|
18
|
+
|
19
|
+
specify { expect(subject.first).to be_a api::INPUT_RECORD }
|
20
|
+
|
21
|
+
specify { expect(subject.first.values.first).to eql(0x0001) }
|
22
|
+
|
23
|
+
specify { expect(subject[1].values.first).to eql(0x0008) }
|
24
|
+
|
25
|
+
it 'will update the underlying ptr' do
|
26
|
+
expect(api::INPUT_RECORD.new(subject.ptr).values.first).to eql(1)
|
27
|
+
|
28
|
+
#::Win32API::INPUT_RECORD.new(@pir.ptr.read_pointer).values #causes segfault because it
|
29
|
+
# wasnt saved as a pointer, it was saved as bytes, maybe subclass pointer? to get around this
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'update-able' do
|
34
|
+
|
35
|
+
it 'will increase size' do
|
36
|
+
expect((subject << api::INPUT_RECORD.new).length).to eql(3)
|
37
|
+
end
|
38
|
+
|
39
|
+
it %q(won't allow a length more than the init max value) do
|
40
|
+
expect { subject.concat [api::INPUT_RECORD.new, api::INPUT_RECORD.new ] }.to raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'vigilem/win32_api'
|
4
|
+
|
5
|
+
# @todo brittle and hags, need to use a double for the brittle calls, and
|
6
|
+
# seperate out teh os specific stuff
|
7
|
+
describe Vigilem::Win32API::Rubyized do
|
8
|
+
|
9
|
+
after(:example) do
|
10
|
+
flush
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:handler_class) { ::Vigilem::Win32API::InputSystemHandler }
|
14
|
+
let(:handler) { handler_class.new }
|
15
|
+
|
16
|
+
let(:adapt) do
|
17
|
+
class WinRubyAPIAdapter
|
18
|
+
include Vigilem::Core::Adapters::Adapter
|
19
|
+
include Vigilem::Win32API::Rubyized
|
20
|
+
def initialize(lnk=Vigilem::Win32API::InputSystemHandler.new)
|
21
|
+
initialize_adapter(lnk)
|
22
|
+
self.win32_api_rubyized_source = lnk
|
23
|
+
end
|
24
|
+
end
|
25
|
+
WinRubyAPIAdapter.new.attach(handler)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#get_std_handle' do
|
29
|
+
it 'calls link.GetStdHandle' do
|
30
|
+
expect(adapt.send(:win32_api_rubyized_source)).to receive(:GetStdHandle).with(Vigilem::Win32API::STD_INPUT_HANDLE)
|
31
|
+
adapt.get_std_handle()
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'methods except #get_std_handle,' do
|
36
|
+
let(:pointer_args) do
|
37
|
+
{
|
38
|
+
:lpBuffer => Vigilem::Win32API::PINPUT_RECORD.new(1),
|
39
|
+
:lpNumberOfEventsRead => FFI::MemoryPointer.new(:DWORD, 1)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:non_pointer_args) do
|
44
|
+
{
|
45
|
+
:hConsoleInput => adapt.get_std_handle,
|
46
|
+
:nLength => 1,
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:all_non_pointer_args) do
|
51
|
+
non_pointer_args.merge( :blocking => nil )
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:all_args) do
|
55
|
+
non_pointer_args.merge(pointer_args)
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'private' do
|
59
|
+
describe '#_options' do
|
60
|
+
it 'returns default arguments' do
|
61
|
+
arg = adapt.send(:_options)
|
62
|
+
|
63
|
+
# @todo
|
64
|
+
expect(arg).to match a_hash_including(
|
65
|
+
#{ :lpBuffer => instance_of(Vigilem::Win32API::PINPUT_RECORD),
|
66
|
+
# :lpNumberOfEventsRead => kind_of(FFI::MemoryPointer)
|
67
|
+
#}.merge(non_pointer_args)
|
68
|
+
non_pointer_args
|
69
|
+
)
|
70
|
+
|
71
|
+
#expect(arg).to include(:lpBuffer => instance_of(Vigilem::Win32API::PINPUT_RECORD))
|
72
|
+
#expect(arg).to include(non_pointer_args)
|
73
|
+
# a_kind_of/instance_of(FFI::MemoryPointer) throws `Invalid Memory'
|
74
|
+
#expect(arg[:lpNumberOfEventsRead]).to be_a(FFI::MemoryPointer)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'configures the default lpBuffer based on nLength' do
|
78
|
+
args = adapt.send(:_options, :nLength => 3)
|
79
|
+
expect([args[:lpBuffer].max_size, args[:nLength]]).to eql([3, 3])
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'configures the default nLength based on lpBuffer.size' do
|
83
|
+
args = adapt.send(:_options, :lpBuffer => [nil] * 4)
|
84
|
+
expect([args[:lpBuffer].size, args[:nLength]]).to eql([4, 4])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#peek_console_input' do
|
90
|
+
it %q(won't block when the queue is empty) do
|
91
|
+
flush
|
92
|
+
expect do
|
93
|
+
Timeout::timeout(5) do
|
94
|
+
adapt.peek_console_input()
|
95
|
+
end
|
96
|
+
end.to_not raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'calls link.PeekConsoleInput' do
|
100
|
+
expect(adapt.send(:win32_api_rubyized_source)).to receive(:PeekConsoleInput)
|
101
|
+
adapt.peek_console_input()
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#read_console_input' do
|
106
|
+
# need to allocConsole so it's isolated
|
107
|
+
=begin
|
108
|
+
it %q(will block when the queue is empty) do
|
109
|
+
flush
|
110
|
+
expect do
|
111
|
+
Timeout::timeout(5) do
|
112
|
+
adapt.read_console_input()
|
113
|
+
end
|
114
|
+
end.to raise_error(Timeout::Error)
|
115
|
+
end
|
116
|
+
=end
|
117
|
+
it %q(won't block when the buffer has somthing in it) do
|
118
|
+
write_console_input_test
|
119
|
+
expect do
|
120
|
+
Timeout::timeout(5) do
|
121
|
+
adapt.read_console_input()
|
122
|
+
end
|
123
|
+
end.to_not raise_error
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'calls link.ReadConsoleInput' do
|
127
|
+
expect(adapt.send(:win32_api_rubyized_source)).to receive(:ReadConsoleInput)
|
128
|
+
adapt.read_console_input()
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vigilem::Win32API::Types do
|
4
|
+
=begin
|
5
|
+
# Check for 64b operating systems.
|
6
|
+
if Vigilem::Core::System.x64bit?
|
7
|
+
::FFI.typedef(:uint64, :ulong_ptr)
|
8
|
+
::FFI.typedef(:int64, :long_ptr)
|
9
|
+
else
|
10
|
+
::FFI.typedef(:ulong, :ulong_ptr)
|
11
|
+
::FFI.typedef(:long, :long_ptr)
|
12
|
+
end
|
13
|
+
=end
|
14
|
+
describe described_class::PVOID do
|
15
|
+
|
16
|
+
describe '::from_native' do
|
17
|
+
|
18
|
+
#def from_native(value, ctx)
|
19
|
+
# value.address
|
20
|
+
#end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '::to_native' do
|
24
|
+
|
25
|
+
=begin
|
26
|
+
def to_native(value, ctx)
|
27
|
+
case
|
28
|
+
when value.kind_of?(FFI::Pointer)
|
29
|
+
value
|
30
|
+
when value.kind_of?(FFI::Struct)
|
31
|
+
value.to_ptr
|
32
|
+
else
|
33
|
+
FFI::Pointer.new(value.to_i)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
=end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
=begin
|
40
|
+
|
41
|
+
#
|
42
|
+
class PBYTE
|
43
|
+
|
44
|
+
include ::Vigilem::FFI::ArrayPointerSync
|
45
|
+
|
46
|
+
# @see ArrayPointerSync#initialize_array_sync
|
47
|
+
# @param [Integer || ::FFI::Pointer] max_len_or_ptr
|
48
|
+
# @param [Array]
|
49
|
+
def initialize(max_len_or_ptr, *init_values)
|
50
|
+
initialize_array_sync(max_len_or_ptr, *init_values)
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
|
55
|
+
#
|
56
|
+
# [Class || Symbol]
|
57
|
+
def array_type
|
58
|
+
:BYTE
|
59
|
+
end
|
60
|
+
|
61
|
+
# Converts the specified value from the native type.
|
62
|
+
# @return [Integer]
|
63
|
+
def from_native(value, ctx)
|
64
|
+
value
|
65
|
+
end
|
66
|
+
|
67
|
+
# Converts the specified value to the native type.
|
68
|
+
# @return [::FFI::Pointer]
|
69
|
+
def to_native(value, ctx)
|
70
|
+
case
|
71
|
+
when value.is_a?(::FFI::Pointer)
|
72
|
+
value
|
73
|
+
when value.is_a?(self)
|
74
|
+
value.ptr
|
75
|
+
else
|
76
|
+
raise "#{value} is an Unsupported Type"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
::FFI.typedef(PVOID, :p_void)
|
83
|
+
::FFI.typedef(PVOID, :PVOID)
|
84
|
+
|
85
|
+
::FFI.typedef(PBYTE, :PBYTE)
|
86
|
+
|
87
|
+
::FFI.typedef(:p_void, :handle)
|
88
|
+
::FFI.typedef(:PVOID, :HANDLE)
|
89
|
+
|
90
|
+
::FFI.typedef(:handle, :h_wnd)
|
91
|
+
::FFI.typedef(:handle, :HWND)
|
92
|
+
|
93
|
+
::FFI.typedef(:ushort, :word)
|
94
|
+
::FFI.typedef(:ushort, :WORD)
|
95
|
+
|
96
|
+
::FFI.typedef(:ushort, :wchar)
|
97
|
+
::FFI.typedef(:ushort, :WCHAR)
|
98
|
+
|
99
|
+
::FFI.typedef(:uint, :dword)
|
100
|
+
::FFI.typedef(:uint, :DWORD)
|
101
|
+
|
102
|
+
::FFI.typedef(:int, :BOOL)
|
103
|
+
|
104
|
+
::FFI.typedef(:uchar, :BYTE)
|
105
|
+
|
106
|
+
::FFI.typedef(:ulong_ptr, :WPARAM)
|
107
|
+
::FFI.typedef(:long_ptr, :LPARAM)
|
108
|
+
=end
|
109
|
+
describe described_class::POINT do
|
110
|
+
|
111
|
+
it 'will have methods as attrs' do
|
112
|
+
expect(described_class.new).to respond_to(:x, :y)
|
113
|
+
end
|
114
|
+
|
115
|
+
it %q(will have an size eql to it's layout types sizes) do
|
116
|
+
expect(described_class.new.to_ptr.type_size).to eql(described_class.size)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe described_class::MSG do
|
121
|
+
|
122
|
+
it 'will have methods as attrs' do
|
123
|
+
expect(described_class.new).to respond_to(:hwnd, :message, :wParam, :lParam, :time, :pt)
|
124
|
+
end
|
125
|
+
|
126
|
+
it %q(will have an size eql to it's layout types sizes) do
|
127
|
+
expect(described_class.new.to_ptr.size).to eql(described_class.size)
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
describe described_class::COORD do
|
133
|
+
it_behaves_like 'attributes_and_size_test' do
|
134
|
+
let(:ary) { [:x, :y] }
|
135
|
+
let(:sze) { 4 }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|