fusuma 2.4.0 → 2.5.0

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -2
  3. data/fusuma.gemspec +17 -18
  4. data/lib/fusuma/config/index.rb +17 -17
  5. data/lib/fusuma/config/searcher.rb +1 -1
  6. data/lib/fusuma/config/yaml_duplication_checker.rb +7 -7
  7. data/lib/fusuma/config.rb +17 -13
  8. data/lib/fusuma/device.rb +12 -12
  9. data/lib/fusuma/environment.rb +10 -10
  10. data/lib/fusuma/hash_support.rb +1 -1
  11. data/lib/fusuma/libinput_command.rb +18 -19
  12. data/lib/fusuma/multi_logger.rb +4 -4
  13. data/lib/fusuma/plugin/base.rb +6 -6
  14. data/lib/fusuma/plugin/buffers/buffer.rb +5 -4
  15. data/lib/fusuma/plugin/buffers/gesture_buffer.rb +6 -6
  16. data/lib/fusuma/plugin/buffers/timer_buffer.rb +2 -2
  17. data/lib/fusuma/plugin/detectors/detector.rb +5 -5
  18. data/lib/fusuma/plugin/detectors/hold_detector.rb +29 -29
  19. data/lib/fusuma/plugin/detectors/pinch_detector.rb +47 -47
  20. data/lib/fusuma/plugin/detectors/rotate_detector.rb +40 -40
  21. data/lib/fusuma/plugin/detectors/swipe_detector.rb +43 -43
  22. data/lib/fusuma/plugin/events/event.rb +11 -11
  23. data/lib/fusuma/plugin/events/records/gesture_record.rb +5 -5
  24. data/lib/fusuma/plugin/events/records/index_record.rb +5 -5
  25. data/lib/fusuma/plugin/events/records/record.rb +2 -2
  26. data/lib/fusuma/plugin/events/records/text_record.rb +1 -1
  27. data/lib/fusuma/plugin/executors/command_executor.rb +4 -4
  28. data/lib/fusuma/plugin/executors/executor.rb +3 -3
  29. data/lib/fusuma/plugin/filters/filter.rb +3 -3
  30. data/lib/fusuma/plugin/filters/libinput_device_filter.rb +12 -12
  31. data/lib/fusuma/plugin/inputs/input.rb +8 -8
  32. data/lib/fusuma/plugin/inputs/libinput_command_input.rb +13 -13
  33. data/lib/fusuma/plugin/inputs/timer_input.rb +3 -3
  34. data/lib/fusuma/plugin/manager.rb +27 -21
  35. data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +10 -10
  36. data/lib/fusuma/plugin/parsers/parser.rb +3 -3
  37. data/lib/fusuma/string_support.rb +3 -3
  38. data/lib/fusuma/version.rb +1 -1
  39. data/lib/fusuma.rb +10 -10
  40. metadata +3 -79
  41. data/spec/helpers/config_helper.rb +0 -20
  42. data/spec/lib/config/searcher_spec.rb +0 -179
  43. data/spec/lib/config_spec.rb +0 -104
  44. data/spec/lib/custom_process_spec.rb +0 -28
  45. data/spec/lib/device_spec.rb +0 -96
  46. data/spec/lib/dummy_config.yml +0 -31
  47. data/spec/lib/fusuma_spec.rb +0 -103
  48. data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +0 -181
  49. data/spec/lib/libinput-list-devices_magic_trackpad.txt +0 -51
  50. data/spec/lib/libinput-list-devices_razer_razer_blade.txt +0 -252
  51. data/spec/lib/libinput-list-devices_thejinx0r.txt +0 -361
  52. data/spec/lib/libinput-list-devices_unavailable.txt +0 -36
  53. data/spec/lib/libinput_command_spec.rb +0 -164
  54. data/spec/lib/plugin/base_spec.rb +0 -74
  55. data/spec/lib/plugin/buffers/buffer_spec.rb +0 -80
  56. data/spec/lib/plugin/buffers/dummy_buffer.rb +0 -20
  57. data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +0 -192
  58. data/spec/lib/plugin/detectors/detector_spec.rb +0 -43
  59. data/spec/lib/plugin/detectors/dummy_detector.rb +0 -24
  60. data/spec/lib/plugin/detectors/hold_detector_spec.rb +0 -145
  61. data/spec/lib/plugin/detectors/pinch_detector_spec.rb +0 -119
  62. data/spec/lib/plugin/detectors/rotate_detector_spec.rb +0 -125
  63. data/spec/lib/plugin/detectors/swipe_detector_spec.rb +0 -118
  64. data/spec/lib/plugin/events/event_spec.rb +0 -30
  65. data/spec/lib/plugin/events/records/gesture_record_spec.rb +0 -22
  66. data/spec/lib/plugin/events/records/record_spec.rb +0 -31
  67. data/spec/lib/plugin/events/records/text_record_spec.rb +0 -26
  68. data/spec/lib/plugin/executors/command_executor_spec.rb +0 -57
  69. data/spec/lib/plugin/executors/executor_spec.rb +0 -164
  70. data/spec/lib/plugin/filters/filter_spec.rb +0 -92
  71. data/spec/lib/plugin/filters/libinput_filter_spec.rb +0 -120
  72. data/spec/lib/plugin/inputs/input_spec.rb +0 -70
  73. data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +0 -121
  74. data/spec/lib/plugin/inputs/timer_input_spec.rb +0 -40
  75. data/spec/lib/plugin/manager_spec.rb +0 -27
  76. data/spec/lib/plugin/parsers/libinput_gesture_parser_spec.rb +0 -76
  77. data/spec/lib/plugin/parsers/parser_spec.rb +0 -45
  78. data/spec/spec_helper.rb +0 -20
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require './lib/fusuma/config'
5
- require './lib/fusuma/config/searcher'
6
-
7
- # spec for Config
8
- module Fusuma
9
- RSpec.describe Config::Searcher do
10
- around do |example|
11
- ConfigHelper.load_config_yml = <<~CONFIG
12
- swipe:
13
- 3:
14
- left:
15
- command: 'alt+Left'
16
- right:
17
- command: 'alt+Right'
18
- 4:
19
- left:
20
- command: 'super+Left'
21
- right:
22
- command: 'super+Right'
23
- pinch:
24
- in:
25
- command: 'ctrl+plus'
26
- out:
27
- command: 'ctrl+minus'
28
- CONFIG
29
-
30
- example.run
31
-
32
- ConfigHelper.clear_config_yml
33
- end
34
-
35
- describe '.search' do
36
- let(:index) { nil }
37
- let(:location) { Config.instance.keymap[0] }
38
- let(:search) { Config::Searcher.new.search(index, location: location) }
39
- context 'index correct order' do
40
- let(:index) { Config::Index.new %w[pinch in command] }
41
- it { expect(Config::Searcher.new.search(index, location: location)).to eq 'ctrl+plus' }
42
- end
43
-
44
- context 'index incorrect order' do
45
- let(:index) { Config::Index.new %w[in pinch 2 command] }
46
- it { expect(Config::Searcher.new.search(index, location: location)).not_to eq 'ctrl+plus' }
47
- end
48
-
49
- context 'with Skip condtions' do
50
- context 'when index includes skippable key' do
51
- let(:index) do
52
- Config::Index.new [
53
- Config::Index::Key.new('pinch'),
54
- Config::Index::Key.new(2, skippable: true),
55
- Config::Index::Key.new('out'),
56
- Config::Index::Key.new('command')
57
- ]
58
- end
59
- it 'detects ctrl+minus with skip' do
60
- condition, value = Config::Searcher.find_condition do
61
- Config::Searcher.new.search(index, location: location)
62
- end
63
- expect([condition, value]).to eq([:skip, 'ctrl+minus'])
64
- end
65
- end
66
-
67
- context 'when index includes skippable key at first' do
68
- let(:index) do
69
- Config::Index.new [
70
- Config::Index::Key.new(:hoge, skippable: true),
71
- Config::Index::Key.new(:fuga, skippable: true),
72
- Config::Index::Key.new('pinch'),
73
- Config::Index::Key.new('in'),
74
- Config::Index::Key.new(:piyo, skippable: true),
75
- Config::Index::Key.new('command')
76
- ]
77
- end
78
- it 'detects ctrl+plus with skip' do
79
- condition, value = Config::Searcher.find_condition do
80
- Config::Searcher.new.search(index, location: location)
81
- end
82
- expect([condition, value]).to eq([:skip, 'ctrl+plus'])
83
- end
84
- end
85
-
86
- context 'with begin/update/end' do
87
- around do |example|
88
- ConfigHelper.load_config_yml = <<~CONFIG
89
- swipe:
90
- 3:
91
- begin:
92
- command: 'echo begin'
93
- update:
94
- command: 'echo update'
95
- end:
96
- command: 'echo end'
97
- keypress:
98
- LEFTCTRL:
99
- command: 'echo end+ctrl'
100
- CONFIG
101
-
102
- example.run
103
-
104
- ConfigHelper.clear_config_yml
105
- end
106
-
107
- context 'without keypress' do
108
- let(:index) do
109
- Config::Index.new [
110
- Config::Index::Key.new(:swipe),
111
- Config::Index::Key.new(3),
112
- Config::Index::Key.new('left', skippable: true),
113
- Config::Index::Key.new('end'),
114
- Config::Index::Key.new('command')
115
- ]
116
- end
117
-
118
- it 'detects with skip' do
119
- condition, value = Config::Searcher.find_condition do
120
- Config::Searcher.new.search(index, location: location)
121
- end
122
- expect([condition, value]).to eq([:skip, 'echo end'])
123
- end
124
- end
125
- context 'with keypress' do
126
- context 'with valid key existing in config.yml' do
127
- let(:index) do
128
- Config::Index.new [
129
- Config::Index::Key.new(:swipe),
130
- Config::Index::Key.new(3),
131
- Config::Index::Key.new('left', skippable: true),
132
- Config::Index::Key.new('end'),
133
- Config::Index::Key.new('keypress', skippable: true),
134
- Config::Index::Key.new('LEFTCTRL', skippable: true),
135
- Config::Index::Key.new('command')
136
- ]
137
- end
138
- it 'detects end+ctrl with skip' do
139
- condition, value = Config::Searcher.find_condition do
140
- Config::Searcher.new.search(index, location: location)
141
- end
142
- expect([condition, value]).to eq([:skip, 'echo end+ctrl'])
143
- end
144
- end
145
- context 'with non-existing key not existing in config.yml' do
146
- let(:index) do
147
- Config::Index.new [
148
- Config::Index::Key.new(:swipe),
149
- Config::Index::Key.new(3),
150
- Config::Index::Key.new('up', skippable: true),
151
- Config::Index::Key.new('end'),
152
- Config::Index::Key.new('keypress', skippable: true),
153
- Config::Index::Key.new('LEFTSHIFT', skippable: true), # Invalid key
154
- Config::Index::Key.new('command')
155
- ]
156
- end
157
- it 'detects end with skip (fallback to no keypress)' do
158
- condition, value = Config::Searcher.find_condition do
159
- Config::Searcher.new.search(index, location: location)
160
- end
161
- expect([condition, value]).to eq([:skip, 'echo end'])
162
- end
163
- end
164
- end
165
- end
166
- end
167
- end
168
-
169
- describe 'private_method: :cache' do
170
- it 'should cache command' do
171
- key = %w[event_type finger direction command].join(',')
172
- value = 'shourtcut string'
173
- searcher = Config::Searcher.new
174
- searcher.send(:cache, key) { value }
175
- expect(searcher.send(:cache, key)).to eq value
176
- end
177
- end
178
- end
179
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require './lib/fusuma/config'
5
-
6
- # spec for Config
7
- module Fusuma
8
- RSpec.describe Config do
9
- let(:keymap) do
10
- {
11
- 'swipe' => {
12
- 3 => {
13
- 'left' => { 'command' => 'alt+Left' },
14
- 'right' => { 'command' => 'alt+Right' }
15
- },
16
- 4 => {
17
- 'left' => { 'command' => 'super+Left' },
18
- 'right' => { 'command' => 'super+Right' }
19
- }
20
- },
21
- 'pinch' => {
22
- 'in' => { 'command' => 'ctrl+plus' },
23
- 'out' => { 'command' => 'ctrl+minus' }
24
- }
25
- }
26
- end
27
-
28
- describe '.custom_path=' do
29
- before { Singleton.__init__(Config) }
30
- it 'should reload keymap file' do
31
- keymap = Config.instance.keymap
32
- Config.custom_path = './spec/lib/dummy_config.yml'
33
- custom_keymap = Config.instance.keymap
34
- expect(keymap).not_to eq custom_keymap
35
- end
36
- end
37
-
38
- describe '#reload' do
39
- before { Singleton.__init__(Config) }
40
- it 'set Seacher' do
41
- old = Config.instance.searcher
42
- Config.instance.reload
43
- expect(Config.instance.searcher).not_to eq(old)
44
- end
45
- end
46
-
47
- describe '#validate' do
48
- context 'with valid yaml' do
49
- before do
50
- string = <<~CONFIG
51
- swipe:
52
- 3:
53
- left:
54
- command: echo 'swipe left'
55
-
56
- CONFIG
57
- @file_path = Tempfile.open do |temp_file|
58
- temp_file.tap { |f| f.write(string) }
59
- end
60
- end
61
-
62
- it 'should return Hash' do
63
- Config.instance.validate(@file_path)
64
- end
65
- end
66
-
67
- context 'with invalid yaml' do
68
- before do
69
- string = <<~CONFIG
70
- this is not yaml
71
- CONFIG
72
- @file_path = Tempfile.open do |temp_file|
73
- temp_file.tap { |f| f.write(string) }
74
- end
75
- end
76
-
77
- it 'raise InvalidFileError' do
78
- expect { Config.instance.validate(@file_path) }.to raise_error(Config::InvalidFileError)
79
- end
80
-
81
- context 'with duplicated key' do
82
- before do
83
- string = <<~CONFIG
84
- pinch:
85
- 2:
86
- in:
87
- command: "xdotool keydown ctrl click 4 keyup ctrl" # threshold: 0.5, interval: 0.5
88
- 2:
89
- out:
90
- command: "xdotool keydown ctrl click 5 keyup ctrl" # threshold: 0.5, interval: 0.5
91
- CONFIG
92
- @file_path = Tempfile.open do |temp_file|
93
- temp_file.tap { |f| f.write(string) }
94
- end
95
- end
96
-
97
- it 'raise InvalidFileError' do
98
- expect { Config.instance.validate(@file_path) }.to raise_error(Config::InvalidFileError)
99
- end
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require './lib/fusuma/custom_process'
5
-
6
- module Fusuma
7
- RSpec.describe CustomProcess do
8
- class ForkTest
9
- include CustomProcess
10
-
11
- def call
12
- fork { puts 'hoge' }
13
- end
14
- end
15
-
16
- describe '.fork' do
17
- before do
18
- allow(Process).to receive(:fork)
19
- end
20
- it 'call Process.fork and Process.setproctitle' do
21
- expect(Process).to receive(:fork).and_yield do
22
- expect(Process).to receive(:setproctitle)
23
- end
24
- ForkTest.new.call
25
- end
26
- end
27
- end
28
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require './lib/fusuma/device'
5
- require './lib/fusuma/plugin/inputs/libinput_command_input'
6
-
7
- module Fusuma
8
- RSpec.describe Device do
9
- describe '.all' do
10
- it 'should fetch all devices'
11
- end
12
-
13
- describe '.reset' do
14
- it 'should clear all cache'
15
- end
16
-
17
- describe '.available' do
18
- let(:libinput_device_command) { 'dummy-libinput-list-devices' }
19
-
20
- before do
21
- Device.reset
22
- allow_any_instance_of(LibinputCommand)
23
- .to receive(:list_devices_command)
24
- .and_return(libinput_device_command)
25
-
26
- @dummy_io = StringIO.new('dummy')
27
- allow(Open3).to receive(:popen3)
28
- .with(libinput_device_command)
29
- .and_return([@dummy_io, list_devices_output, @dummy_io, nil])
30
- end
31
-
32
- context 'with XPS-9360 (have a correct device)' do
33
- let(:list_devices_output) do
34
- File.open('./spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt')
35
- end
36
-
37
- it { expect(Device.available).to be_a Array }
38
- it { expect(Device.available.map(&:name)).not_to include 'Power Button' }
39
- it { expect(Device.available.map(&:name)).to include 'DLL075B:01 06CB:76AF Touchpad' }
40
- end
41
-
42
- context 'with no tap to click device (like a bluetooth apple trackpad)' do
43
- let(:list_devices_output) do
44
- File.open('spec/lib/libinput-list-devices_magic_trackpad.txt')
45
- end
46
-
47
- it { expect(Device.available).to be_a Array }
48
- it { expect(Device.available.map(&:name)).to eq ['Christopher’s Trackpad', 'bcm5974'] }
49
- end
50
-
51
- context "context with the device's name not found at first line" do
52
- let(:list_devices_output) do
53
- File.open('spec/lib/libinput-list-devices_thejinx0r.txt')
54
- end
55
-
56
- it { expect(Device.available).to be_a Array }
57
- it { expect(Device.available.map(&:name)).to include 'HTX USB HID Device HTX HID Device Touchpad' }
58
- end
59
-
60
- context 'when no devices' do
61
- let(:list_devices_output) do
62
- File.open('spec/lib/libinput-list-devices_unavailable.txt')
63
- end
64
-
65
- it 'should failed with exit' do
66
- expect { Device.available }.to raise_error(SystemExit)
67
- end
68
-
69
- it 'should failed with printing error log' do
70
- expect(MultiLogger).to receive(:error)
71
- expect { Device.available }.to raise_error(SystemExit)
72
- end
73
- end
74
-
75
- context 'with some device has same names' do
76
- let(:list_devices_output) do
77
- File.open('spec/lib/libinput-list-devices_razer_razer_blade.txt')
78
- end
79
-
80
- it { expect(Device.available).to be_a Array }
81
- it 'should have capabilities' do
82
- razer_devices = Device.all.group_by(&:name)['Razer Razer Blade']
83
- expect(razer_devices.size).to eq 3
84
- end
85
-
86
- it 'should know capabilities' do
87
- razer_devices = Device.all.group_by(&:name)['Razer Razer Blade']
88
- capabilities = razer_devices.map(&:capabilities)
89
- expect(capabilities).to eq ['keyboard', 'keyboard pointer', 'pointer']
90
- keyboard_devices = razer_devices.select { |d| d.capabilities == 'keyboard' }
91
- expect(keyboard_devices.size).to eq 1
92
- end
93
- end
94
- end
95
- end
96
- end
@@ -1,31 +0,0 @@
1
- swipe:
2
- 3:
3
- left:
4
- command: 'echo swipe 3 left'
5
- right:
6
- command: 'echo swipe 3 right'
7
- up:
8
- command: 'echo swipe 3 up'
9
- down:
10
- command: 'echo swipe 3 down'
11
- 4:
12
- left:
13
- command: 'echo swipe 4 left'
14
- right:
15
- command: 'echo swipe 4 right'
16
- up:
17
- command: 'echo swipe 4 up'
18
- down:
19
- command: 'echo swipe 4 down'
20
-
21
- pinch:
22
- 2:
23
- in:
24
- command: 'echo pinch 2 in'
25
- out:
26
- command: 'echo pinch 2 out'
27
- 4:
28
- in:
29
- command: 'echo pinch 4 in'
30
- out:
31
- command: 'echo pinch 4 in'
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require './lib/fusuma'
5
- require './lib/fusuma/plugin/inputs/libinput_command_input'
6
- require './lib/fusuma/plugin/filters/libinput_device_filter'
7
-
8
- module Fusuma
9
- RSpec.describe Runner do
10
- describe '.run' do
11
- before do
12
- Singleton.__init__(MultiLogger)
13
- Singleton.__init__(Config)
14
- allow_any_instance_of(Runner).to receive(:run)
15
- allow_any_instance_of(LibinputCommand).to receive(:version)
16
- .and_return("1.8\n")
17
- end
18
-
19
- context 'when without option' do
20
- it 'should not enable debug mode' do
21
- expect(MultiLogger.instance).not_to be_debug_mode
22
- Runner.run
23
- end
24
- end
25
-
26
- context 'when run with argument "--version"' do
27
- # NOTE: skip print reload config message
28
- before { allow(MultiLogger).to receive(:info).with(anything) }
29
- it 'should print version' do
30
- expect(MultiLogger).to receive(:info)
31
- .with("Fusuma: #{Fusuma::VERSION}")
32
- expect(MultiLogger).to receive(:info)
33
- .with("libinput: #{LibinputCommand.new.version}")
34
- expect(MultiLogger).to receive(:info)
35
- .with("OS: #{`uname -rsv`}".strip)
36
- expect(MultiLogger).to receive(:info)
37
- .with("Distribution: #{`cat /etc/issue`}".strip)
38
- expect(MultiLogger).to receive(:info)
39
- .with("Desktop session: #{`echo $DESKTOP_SESSION $XDG_SESSION_TYPE`}".strip)
40
- expect { Runner.run(version: true) }.to raise_error(SystemExit)
41
- end
42
- end
43
-
44
- context 'when run with argument "-l"' do
45
- it 'should print device list' do
46
- allow(Device).to receive(:available) {
47
- [
48
- Device.new(name: 'test_device1'),
49
- Device.new(name: 'test_device2')
50
- ]
51
- }
52
-
53
- expected = <<~OUTPUT
54
- test_device1
55
- test_device2
56
- OUTPUT
57
- expect { Runner.run(list: true) }.to raise_error(SystemExit)
58
- .and output(/#{expected}/).to_stdout
59
- end
60
- end
61
-
62
- # TODO: remove from_option and command line options
63
- context 'when run with argument "--device="test_device2"' do
64
- it 'should set device' do
65
- allow(Device).to receive(:names) { %w[test_device1 test_device2] }
66
- expect(Plugin::Filters::LibinputDeviceFilter::KeepDevice)
67
- .to receive(:from_option=).with('test_device2')
68
- Runner.run(device: 'test_device2')
69
- end
70
- end
71
-
72
- context 'when run with argument "-v"' do
73
- it 'should enable debug mode' do
74
- MultiLogger.send(:new)
75
- Runner.run(verbose: true)
76
- expect(MultiLogger.instance).to be_debug_mode
77
- end
78
- end
79
-
80
- context 'when run with argument "-c path/to/config.yml"' do
81
- before do
82
- allow_any_instance_of(Runner).to receive(:run)
83
- @config = Config.instance
84
-
85
- string = <<~CONFIG
86
- swipe:
87
- 3:
88
- left:
89
- command: echo 'swipe left'
90
-
91
- CONFIG
92
- @file_path = Tempfile.open do |temp_file|
93
- temp_file.tap { |f| f.write(string) }
94
- end
95
- end
96
- it 'should assign custom_path' do
97
- expect { Runner.run(config_path: @file_path) }
98
- .to change { @config.custom_path }.from(nil).to(@file_path)
99
- end
100
- end
101
- end
102
- end
103
- end