vigilem-win32_api 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|