fusuma 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fusuma/plugin/manager.rb +3 -3
- data/lib/fusuma/version.rb +1 -1
- data/spec/helpers/config_helper.rb +20 -0
- data/spec/lib/config/searcher_spec.rb +97 -0
- data/spec/lib/config_spec.rb +112 -0
- data/spec/lib/custom_process_spec.rb +28 -0
- data/spec/lib/device_spec.rb +98 -0
- data/spec/lib/dummy_config.yml +31 -0
- data/spec/lib/fusuma_spec.rb +103 -0
- data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +181 -0
- data/spec/lib/libinput-list-devices_magic_trackpad.txt +51 -0
- data/spec/lib/libinput-list-devices_razer_razer_blade.txt +252 -0
- data/spec/lib/libinput-list-devices_thejinx0r.txt +361 -0
- data/spec/lib/libinput-list-devices_unavailable.txt +36 -0
- data/spec/lib/libinput_command_spec.rb +167 -0
- data/spec/lib/plugin/base_spec.rb +74 -0
- data/spec/lib/plugin/buffers/buffer_spec.rb +80 -0
- data/spec/lib/plugin/buffers/dummy_buffer.rb +20 -0
- data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +172 -0
- data/spec/lib/plugin/detectors/detector_spec.rb +43 -0
- data/spec/lib/plugin/detectors/dummy_detector.rb +24 -0
- data/spec/lib/plugin/detectors/pinch_detector_spec.rb +119 -0
- data/spec/lib/plugin/detectors/rotate_detector_spec.rb +125 -0
- data/spec/lib/plugin/detectors/swipe_detector_spec.rb +118 -0
- data/spec/lib/plugin/events/event_spec.rb +30 -0
- data/spec/lib/plugin/events/records/gesture_record_spec.rb +22 -0
- data/spec/lib/plugin/events/records/record_spec.rb +31 -0
- data/spec/lib/plugin/events/records/text_record_spec.rb +26 -0
- data/spec/lib/plugin/executors/command_executor_spec.rb +57 -0
- data/spec/lib/plugin/executors/executor_spec.rb +160 -0
- data/spec/lib/plugin/filters/filter_spec.rb +92 -0
- data/spec/lib/plugin/filters/libinput_filter_spec.rb +120 -0
- data/spec/lib/plugin/inputs/input_spec.rb +70 -0
- data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +120 -0
- data/spec/lib/plugin/inputs/timer_input_spec.rb +40 -0
- data/spec/lib/plugin/manager_spec.rb +27 -0
- data/spec/lib/plugin/parsers/parser_spec.rb +45 -0
- data/spec/spec_helper.rb +20 -0
- metadata +74 -20
- data/.github/FUNDING.yml +0 -8
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- data/.github/pull_request_template.md +0 -9
- data/.github/stale.yml +0 -18
- data/.gitignore +0 -17
- data/.reek.yml +0 -96
- data/.rspec +0 -2
- data/.rubocop.yml +0 -43
- data/.rubocop_todo.yml +0 -55
- data/.solargraph.yml +0 -16
- data/.travis.yml +0 -9
- data/CHANGELOG.md +0 -456
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -72
- data/Gemfile +0 -23
- data/Rakefile +0 -15
- data/fusuma.gemspec +0 -29
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
require './lib/fusuma/config'
|
7
|
+
require './lib/fusuma/plugin/filters/filter'
|
8
|
+
require './lib/fusuma/plugin/events/event'
|
9
|
+
|
10
|
+
module Fusuma
|
11
|
+
module Plugin
|
12
|
+
module Filters
|
13
|
+
class DummyFilter < Filter
|
14
|
+
DEFAULT_SOURCE = 'dummy_input'
|
15
|
+
|
16
|
+
def config_param_types
|
17
|
+
{
|
18
|
+
source: String
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.describe DummyFilter do
|
24
|
+
let(:filter) { DummyFilter.new }
|
25
|
+
|
26
|
+
describe '#source' do
|
27
|
+
subject { filter.source }
|
28
|
+
|
29
|
+
it { is_expected.to eq DummyFilter::DEFAULT_SOURCE }
|
30
|
+
|
31
|
+
context 'with config' do
|
32
|
+
around do |example|
|
33
|
+
@custom_source = 'custom_input'
|
34
|
+
|
35
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
36
|
+
plugin:
|
37
|
+
filters:
|
38
|
+
dummy_filter:
|
39
|
+
source: #{@custom_source}
|
40
|
+
CONFIG
|
41
|
+
|
42
|
+
example.run
|
43
|
+
|
44
|
+
Config.custom_path = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it { is_expected.to eq @custom_source }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#filter' do
|
52
|
+
subject { filter.filter(event) }
|
53
|
+
let(:event) { Events::Event.new(tag: 'dummy_input', record: 'dummy') }
|
54
|
+
|
55
|
+
context 'when filter#keep? return false' do
|
56
|
+
before do
|
57
|
+
allow(filter).to receive(:keep?).and_return(false)
|
58
|
+
end
|
59
|
+
|
60
|
+
it { is_expected.to be nil }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when filter#keep? return true' do
|
64
|
+
before do
|
65
|
+
allow(filter).to receive(:keep?).and_return(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
it { is_expected.to be event }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#config_params' do
|
73
|
+
around do |example|
|
74
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
75
|
+
plugin:
|
76
|
+
filters:
|
77
|
+
dummy_filter:
|
78
|
+
dummy: dummy
|
79
|
+
CONFIG
|
80
|
+
|
81
|
+
example.run
|
82
|
+
|
83
|
+
Config.custom_path = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
subject { filter.config_params }
|
87
|
+
it { is_expected.to eq(dummy: 'dummy') }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
require './lib/fusuma/config'
|
7
|
+
require './lib/fusuma/plugin/filters/libinput_device_filter'
|
8
|
+
require './lib/fusuma/plugin/events/event'
|
9
|
+
|
10
|
+
module Fusuma
|
11
|
+
module Plugin
|
12
|
+
module Filters
|
13
|
+
RSpec.describe LibinputDeviceFilter do
|
14
|
+
before do
|
15
|
+
@filter = LibinputDeviceFilter.new
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#source' do
|
19
|
+
it { expect(@filter.source).to eq LibinputDeviceFilter::DEFAULT_SOURCE }
|
20
|
+
|
21
|
+
context 'with config' do
|
22
|
+
around do |example|
|
23
|
+
@custom_source = 'custom_input'
|
24
|
+
|
25
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
26
|
+
plugin:
|
27
|
+
filters:
|
28
|
+
libinput_device_filter:
|
29
|
+
source: #{@custom_source}
|
30
|
+
CONFIG
|
31
|
+
|
32
|
+
example.run
|
33
|
+
|
34
|
+
Config.custom_path = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it { expect(@filter.source).to eq @custom_source }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#filter' do
|
42
|
+
before do
|
43
|
+
@event = Events::Event.new(tag: 'libinput_command_input', record: 'dummy')
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when filter#keep? return false' do
|
47
|
+
before do
|
48
|
+
allow(@filter).to receive(:keep?).and_return(false)
|
49
|
+
end
|
50
|
+
|
51
|
+
it { expect(@filter.filter(@event)).to be nil }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when filter#keep? return true' do
|
55
|
+
before do
|
56
|
+
allow(@filter).to receive(:keep?).and_return(true)
|
57
|
+
end
|
58
|
+
|
59
|
+
it { expect(@filter.filter(@event)).to be @event }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#keep?' do
|
64
|
+
before do
|
65
|
+
device = Device.new(id: 'event18', name: 'Awesome Touchpad', available: true)
|
66
|
+
allow(Device).to receive(:all).and_return([device])
|
67
|
+
@keep_device = LibinputDeviceFilter::KeepDevice.new(name_patterns: [])
|
68
|
+
allow(@filter).to receive(:keep_device).and_return(@keep_device)
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when including record generated from touchpad' do
|
72
|
+
before do
|
73
|
+
text = ' event18 GESTURE_SWIPE_UPDATE +1.44s 4 11.23/ 1.00 (36.91/ 3.28 unaccelerated) '
|
74
|
+
@event = Events::Event.new(tag: 'libinput_command_input', record: text)
|
75
|
+
end
|
76
|
+
it 'should keep record' do
|
77
|
+
expect(@filter.keep?(@event.record)).to be true
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when including -' do
|
81
|
+
before do
|
82
|
+
text = '-event18 GESTURE_SWIPE_UPDATE +1.44s 4 11.23/ 1.00 (36.91/ 3.28 unaccelerated) '
|
83
|
+
@event = Events::Event.new(tag: 'libinput_command_input', record: text)
|
84
|
+
end
|
85
|
+
it 'should keep record' do
|
86
|
+
expect(@filter.keep?(@event.record)).to be true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
context 'when new device is added' do
|
91
|
+
before do
|
92
|
+
text = '-event18 DEVICE_ADDED Apple Wireless Trackpad seat0 default group13 cap:pg size 132x112mm tap(dl off) left scroll-nat scroll-2fg-edge click-buttonareas-clickfing '
|
93
|
+
@event = Events::Event.new(tag: 'libinput_command_input', record: text)
|
94
|
+
end
|
95
|
+
it 'should reset KeepDevice' do
|
96
|
+
expect(@keep_device).to receive(:reset)
|
97
|
+
@filter.keep?(@event.record)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'discard DEVICE_ADDED record' do
|
101
|
+
expect(@filter.keep?(@event.record)).to be false
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when keep device is NOT matched' do
|
105
|
+
before do
|
106
|
+
@keep_device = LibinputDeviceFilter::KeepDevice.new(name_patterns: ['Microsoft Arc Mouse'])
|
107
|
+
allow(@filter).to receive(:keep_device).and_return(@keep_device)
|
108
|
+
end
|
109
|
+
it 'should NOT reset KeepDevice' do
|
110
|
+
expect(@keep_device).not_to receive(:reset)
|
111
|
+
# NOTE: @event.record is 'Apple Wireless Touchpad'
|
112
|
+
@filter.keep?(@event.record)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/plugin/inputs/input'
|
5
|
+
|
6
|
+
module Fusuma
|
7
|
+
module Plugin
|
8
|
+
module Inputs
|
9
|
+
RSpec.describe Input do
|
10
|
+
let(:input) { described_class.new }
|
11
|
+
|
12
|
+
describe '#io' do
|
13
|
+
subject { input.io { 'dummy' } }
|
14
|
+
it { expect { subject }.to raise_error(NotImplementedError) }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#create_event' do
|
18
|
+
subject { input.create_event }
|
19
|
+
it { is_expected.to be_a Events::Event }
|
20
|
+
|
21
|
+
it { expect(input.tag).to eq 'input' }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.select' do
|
25
|
+
subject { Input.select([DummyInput.new]) }
|
26
|
+
|
27
|
+
it { is_expected.to be_a Events::Event }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class DummyInput < Input
|
32
|
+
def io
|
33
|
+
@io ||= begin
|
34
|
+
r, w = IO.pipe
|
35
|
+
w.puts 'hoge'
|
36
|
+
w.close
|
37
|
+
r
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
RSpec.describe DummyInput do
|
43
|
+
let(:dummy_input) { described_class.new }
|
44
|
+
|
45
|
+
around do |example|
|
46
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
47
|
+
plugin:
|
48
|
+
inputs:
|
49
|
+
dummy_input:
|
50
|
+
dummy: dummy
|
51
|
+
CONFIG
|
52
|
+
|
53
|
+
example.run
|
54
|
+
|
55
|
+
Config.custom_path = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#io' do
|
59
|
+
subject { dummy_input.io }
|
60
|
+
it { is_expected.to be_a IO }
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#config_params' do
|
64
|
+
subject { dummy_input.config_params }
|
65
|
+
it { is_expected.to eq(dummy: 'dummy') }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/plugin/inputs/libinput_command_input'
|
5
|
+
|
6
|
+
module Fusuma
|
7
|
+
module Plugin
|
8
|
+
module Inputs
|
9
|
+
RSpec.describe LibinputCommandInput do
|
10
|
+
let(:input) { described_class.new }
|
11
|
+
|
12
|
+
describe '#io' do
|
13
|
+
before do
|
14
|
+
@dummy_io = StringIO.new('dummy')
|
15
|
+
dummy_pid = 999_999_999
|
16
|
+
libinput_command = instance_double(LibinputCommand)
|
17
|
+
allow(LibinputCommand).to receive(:new).and_return(libinput_command)
|
18
|
+
allow(libinput_command).to receive(:debug_events).and_return([dummy_pid, @dummy_io])
|
19
|
+
end
|
20
|
+
|
21
|
+
it { expect(input.io).to eq @dummy_io }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#libinput_options' do
|
25
|
+
it { expect(input.libinput_options).to be_a Array }
|
26
|
+
|
27
|
+
context 'when device: awesome_device is given as config_params' do
|
28
|
+
around do |example|
|
29
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
30
|
+
plugin:
|
31
|
+
inputs:
|
32
|
+
libinput_command_input:
|
33
|
+
device: awesome device
|
34
|
+
CONFIG
|
35
|
+
|
36
|
+
example.run
|
37
|
+
|
38
|
+
Config.custom_path = nil
|
39
|
+
end
|
40
|
+
it "contains --device='awesome device'" do
|
41
|
+
expect(input.libinput_options).to be_include "--device='awesome device'"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when enable-tap: true is given as config_params' do
|
46
|
+
around do |example|
|
47
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
48
|
+
plugin:
|
49
|
+
inputs:
|
50
|
+
libinput_command_input:
|
51
|
+
enable-tap: true
|
52
|
+
CONFIG
|
53
|
+
|
54
|
+
example.run
|
55
|
+
|
56
|
+
Config.custom_path = nil
|
57
|
+
end
|
58
|
+
it 'contains --enable-tap' do
|
59
|
+
expect(input.libinput_options).to be_include '--enable-tap'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when enable-dwt: true is given as config_params' do
|
64
|
+
around do |example|
|
65
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
66
|
+
plugin:
|
67
|
+
inputs:
|
68
|
+
libinput_command_input:
|
69
|
+
enable-dwt: true
|
70
|
+
CONFIG
|
71
|
+
|
72
|
+
example.run
|
73
|
+
|
74
|
+
Config.custom_path = nil
|
75
|
+
end
|
76
|
+
it 'contains --enable-dwt' do
|
77
|
+
expect(input.libinput_options).to be_include '--enable-dwt'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when show-keycodes: true is given as config_params' do
|
82
|
+
around do |example|
|
83
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
84
|
+
plugin:
|
85
|
+
inputs:
|
86
|
+
libinput_command_input:
|
87
|
+
show-keycodes: true
|
88
|
+
CONFIG
|
89
|
+
|
90
|
+
example.run
|
91
|
+
|
92
|
+
Config.custom_path = nil
|
93
|
+
end
|
94
|
+
it 'contains --show-keycodes' do
|
95
|
+
expect(input.libinput_options).to be_include '--show-keycodes'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when verbose: true is given as config_params' do
|
100
|
+
around do |example|
|
101
|
+
ConfigHelper.load_config_yml = <<~CONFIG
|
102
|
+
plugin:
|
103
|
+
inputs:
|
104
|
+
libinput_command_input:
|
105
|
+
verbose: true
|
106
|
+
CONFIG
|
107
|
+
|
108
|
+
example.run
|
109
|
+
|
110
|
+
Config.custom_path = nil
|
111
|
+
end
|
112
|
+
it 'contains --verbose' do
|
113
|
+
expect(input.libinput_options).to be_include '--verbose'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/plugin/inputs/timer_input'
|
5
|
+
|
6
|
+
module Fusuma
|
7
|
+
module Plugin
|
8
|
+
module Inputs
|
9
|
+
RSpec.describe TimerInput do
|
10
|
+
before do
|
11
|
+
@dummy_read = StringIO.new('dummy_read')
|
12
|
+
@dummy_write = StringIO.new('dummy_write')
|
13
|
+
@input = TimerInput.new
|
14
|
+
allow(@input).to receive(:create_io).and_return [@dummy_read, @dummy_write]
|
15
|
+
allow(@input).to receive(:fork)
|
16
|
+
allow(Process).to receive(:detach).with(anything)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#io' do
|
20
|
+
it { expect(@input.io).to eq @dummy_read }
|
21
|
+
|
22
|
+
it 'should call #create_io' do
|
23
|
+
expect(@input).to receive(:create_io)
|
24
|
+
expect(@input).to receive(:start)
|
25
|
+
@input.io
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#start' do
|
30
|
+
it {
|
31
|
+
expect(@input).to receive(:fork).and_yield do |block_context|
|
32
|
+
expect(block_context).to receive(:timer_loop).with(@dummy_read, @dummy_write)
|
33
|
+
end
|
34
|
+
@input.start(@dummy_read, @dummy_write)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/plugin/base'
|
5
|
+
require './lib/fusuma/plugin/manager'
|
6
|
+
|
7
|
+
module Fusuma
|
8
|
+
module Plugin
|
9
|
+
RSpec.describe Manager do
|
10
|
+
describe '#require_siblings_from_plugin_dir' do
|
11
|
+
Manager.new(Base).require_siblings_from_plugin_dir
|
12
|
+
subject { Manager.new(Base).require_siblings_from_plugin_dir }
|
13
|
+
it { expect { subject }.not_to raise_error(LoadError) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#require_siblings_from_gem' do
|
17
|
+
subject { Manager.new(Inputs::Input).require_siblings_from_gem }
|
18
|
+
it { expect { subject }.not_to raise_error(LoadError) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.plugins' do
|
22
|
+
subject { Manger.plugins }
|
23
|
+
pending
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|