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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fusuma/plugin/manager.rb +3 -3
  3. data/lib/fusuma/version.rb +1 -1
  4. data/spec/helpers/config_helper.rb +20 -0
  5. data/spec/lib/config/searcher_spec.rb +97 -0
  6. data/spec/lib/config_spec.rb +112 -0
  7. data/spec/lib/custom_process_spec.rb +28 -0
  8. data/spec/lib/device_spec.rb +98 -0
  9. data/spec/lib/dummy_config.yml +31 -0
  10. data/spec/lib/fusuma_spec.rb +103 -0
  11. data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +181 -0
  12. data/spec/lib/libinput-list-devices_magic_trackpad.txt +51 -0
  13. data/spec/lib/libinput-list-devices_razer_razer_blade.txt +252 -0
  14. data/spec/lib/libinput-list-devices_thejinx0r.txt +361 -0
  15. data/spec/lib/libinput-list-devices_unavailable.txt +36 -0
  16. data/spec/lib/libinput_command_spec.rb +167 -0
  17. data/spec/lib/plugin/base_spec.rb +74 -0
  18. data/spec/lib/plugin/buffers/buffer_spec.rb +80 -0
  19. data/spec/lib/plugin/buffers/dummy_buffer.rb +20 -0
  20. data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +172 -0
  21. data/spec/lib/plugin/detectors/detector_spec.rb +43 -0
  22. data/spec/lib/plugin/detectors/dummy_detector.rb +24 -0
  23. data/spec/lib/plugin/detectors/pinch_detector_spec.rb +119 -0
  24. data/spec/lib/plugin/detectors/rotate_detector_spec.rb +125 -0
  25. data/spec/lib/plugin/detectors/swipe_detector_spec.rb +118 -0
  26. data/spec/lib/plugin/events/event_spec.rb +30 -0
  27. data/spec/lib/plugin/events/records/gesture_record_spec.rb +22 -0
  28. data/spec/lib/plugin/events/records/record_spec.rb +31 -0
  29. data/spec/lib/plugin/events/records/text_record_spec.rb +26 -0
  30. data/spec/lib/plugin/executors/command_executor_spec.rb +57 -0
  31. data/spec/lib/plugin/executors/executor_spec.rb +160 -0
  32. data/spec/lib/plugin/filters/filter_spec.rb +92 -0
  33. data/spec/lib/plugin/filters/libinput_filter_spec.rb +120 -0
  34. data/spec/lib/plugin/inputs/input_spec.rb +70 -0
  35. data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +120 -0
  36. data/spec/lib/plugin/inputs/timer_input_spec.rb +40 -0
  37. data/spec/lib/plugin/manager_spec.rb +27 -0
  38. data/spec/lib/plugin/parsers/parser_spec.rb +45 -0
  39. data/spec/spec_helper.rb +20 -0
  40. metadata +74 -20
  41. data/.github/FUNDING.yml +0 -8
  42. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  43. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  44. data/.github/pull_request_template.md +0 -9
  45. data/.github/stale.yml +0 -18
  46. data/.gitignore +0 -17
  47. data/.reek.yml +0 -96
  48. data/.rspec +0 -2
  49. data/.rubocop.yml +0 -43
  50. data/.rubocop_todo.yml +0 -55
  51. data/.solargraph.yml +0 -16
  52. data/.travis.yml +0 -9
  53. data/CHANGELOG.md +0 -456
  54. data/CODE_OF_CONDUCT.md +0 -74
  55. data/CONTRIBUTING.md +0 -72
  56. data/Gemfile +0 -23
  57. data/Rakefile +0 -15
  58. data/fusuma.gemspec +0 -29
@@ -0,0 +1,74 @@
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
+ class DummyPlugin < Base
10
+ def config_param_types
11
+ {
12
+ dummy_string: String,
13
+ dummy_list: Array,
14
+ dummy_bool: [TrueClass, FalseClass]
15
+ }
16
+ end
17
+ end
18
+
19
+ class DummyChildPlugin < DummyPlugin
20
+ end
21
+
22
+ RSpec.describe DummyPlugin do
23
+ before do
24
+ @dummy_plugin = DummyPlugin.new
25
+ @dummy_child_plugin = DummyChildPlugin.new
26
+
27
+ ConfigHelper.load_config_yml = <<-CONFIG
28
+ plugin:
29
+ dummy_plugin:
30
+ dummy_string: dummy
31
+ dummy_list:
32
+ - 1
33
+ - 2
34
+ - 3
35
+ dummy_bool: true
36
+ CONFIG
37
+ end
38
+
39
+ after do
40
+ Config.custom_path = nil
41
+ end
42
+ describe '.inherited' do
43
+ it 'should add required class to subclass on Manager' do
44
+ expect(Manager.plugins[Base.name]).to include(DummyPlugin)
45
+ end
46
+ end
47
+
48
+ describe '.plugins' do
49
+ it 'should list plugins' do
50
+ expect(DummyPlugin.plugins).to eq([DummyChildPlugin])
51
+ end
52
+ end
53
+
54
+ describe '#config_param_types' do
55
+ it 'should define class for config params' do
56
+ expect(@dummy_plugin.config_param_types).to be_a Hash
57
+ end
58
+ end
59
+
60
+ describe '#config_params' do
61
+ it 'should fetch options from config' do
62
+ expect(@dummy_plugin.config_params).to be_a Hash
63
+ expect(@dummy_plugin.config_params(:dummy_string)).to be_a String
64
+ end
65
+ end
66
+
67
+ describe '#config_index' do
68
+ it 'should return index' do
69
+ expect(@dummy_plugin.config_index).to be_a Config::Index
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require './lib/fusuma/plugin/events/event'
6
+ require_relative './dummy_buffer'
7
+
8
+ module Fusuma
9
+ module Plugin
10
+ module Buffers
11
+ RSpec.describe DummyBuffer do
12
+ before do
13
+ @buffer = DummyBuffer.new
14
+ end
15
+
16
+ describe '#type' do
17
+ subject { @buffer.type }
18
+ it { is_expected.to eq 'dummy' }
19
+ end
20
+
21
+ describe '#buffer' do
22
+ it 'should buffer event' do
23
+ event = Events::Event.new(tag: 'dummy', record: 'dummy record')
24
+ expect(@buffer.buffer(event)).to eq [event]
25
+ expect(@buffer.events).to eq [event]
26
+ end
27
+
28
+ it 'should NOT buffer event' do
29
+ event = Events::Event.new(tag: 'SHOULD NOT BUFFER', record: 'dummy record')
30
+ @buffer.buffer(event)
31
+ expect(@buffer.events).to eq []
32
+ end
33
+ end
34
+
35
+ describe '#source' do
36
+ subject { @buffer.source }
37
+
38
+ it { is_expected.to eq DummyBuffer::DEFAULT_SOURCE }
39
+
40
+ context 'with config' do
41
+ around do |example|
42
+ @source = 'custom_event'
43
+
44
+ ConfigHelper.load_config_yml = <<~CONFIG
45
+ plugin:
46
+ buffers:
47
+ dummy_buffer:
48
+ source: #{@source}
49
+ CONFIG
50
+
51
+ example.run
52
+
53
+ Config.custom_path = nil
54
+ end
55
+
56
+ it { is_expected.to eq @source }
57
+ end
58
+ end
59
+
60
+ describe '#config_params' do
61
+ around do |example|
62
+ ConfigHelper.load_config_yml = <<~CONFIG
63
+ plugin:
64
+ buffers:
65
+ dummy_buffer:
66
+ dummy: dummy
67
+ CONFIG
68
+
69
+ example.run
70
+
71
+ Config.custom_path = nil
72
+ end
73
+
74
+ subject { @buffer.config_params }
75
+ it { is_expected.to eq(dummy: 'dummy') }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/fusuma/plugin/buffers/buffer'
4
+
5
+ module Fusuma
6
+ module Plugin
7
+ module Buffers
8
+ class DummyBuffer < Buffer
9
+ DEFAULT_SOURCE = 'dummy'
10
+
11
+ def config_param_types
12
+ {
13
+ source: String,
14
+ dummy: String
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require './lib/fusuma/plugin/events/event'
6
+ require './lib/fusuma/plugin/events/records/gesture_record'
7
+ require './lib/fusuma/plugin/buffers/gesture_buffer'
8
+
9
+ module Fusuma
10
+ module Plugin
11
+ module Buffers
12
+ RSpec.describe GestureBuffer do
13
+ before do
14
+ @buffer = GestureBuffer.new
15
+ delta = Events::Records::GestureRecord::Delta.new(-1, 0, 0, 0, 0, 0)
16
+ @event_generator = lambda { |time = nil, status = 'updating'|
17
+ Events::Event.new(time: time,
18
+ tag: 'libinput_gesture_parser',
19
+ record: Events::Records::GestureRecord.new(
20
+ status: status,
21
+ gesture: 'SWIPE',
22
+ finger: 3,
23
+ delta: delta
24
+ ))
25
+ }
26
+ end
27
+
28
+ describe '#type' do
29
+ it { expect(@buffer.type).to eq 'gesture' }
30
+ end
31
+
32
+ describe '#buffer' do
33
+ it 'should buffer gesture event' do
34
+ event = @event_generator.call
35
+ @buffer.buffer(event)
36
+ expect(@buffer.events).to eq [event]
37
+ end
38
+
39
+ it 'should NOT buffer other event' do
40
+ event = Events::Event.new(tag: 'SHOULD NOT BUFFER', record: 'dummy record')
41
+ @buffer.buffer(event)
42
+ expect(@buffer.events).to eq []
43
+ end
44
+
45
+ it 'should buffer begin/end' do
46
+ begin_event = @event_generator.call(nil, 'begin')
47
+ @buffer.buffer(begin_event)
48
+ expect(@buffer.events).to eq [begin_event]
49
+ end_event = @event_generator.call(nil, 'end')
50
+ @buffer.buffer(end_event)
51
+ expect(@buffer.events).to eq [begin_event, end_event]
52
+ end
53
+ end
54
+
55
+ describe '#clear_expired' do
56
+ it 'should keep only events generated within 30 seconds' do
57
+ time = Time.now
58
+ event1 = @event_generator.call(time)
59
+ @buffer.buffer(event1)
60
+ event2 = @event_generator.call(time + 100)
61
+ event3 = @event_generator.call(time + 100)
62
+ @buffer.buffer(event2)
63
+ @buffer.buffer(event3)
64
+
65
+ @buffer.clear_expired(current_time: time + 100.1)
66
+
67
+ expect(@buffer.events).to eq [event2, event3]
68
+ end
69
+
70
+ context 'change seconds to keep' do
71
+ around do |example|
72
+ ConfigHelper.load_config_yml = <<~CONFIG
73
+ plugin:
74
+ buffers:
75
+ gesture_buffer:
76
+ seconds_to_keep: 0.3
77
+ CONFIG
78
+
79
+ example.run
80
+
81
+ Config.custom_path = nil
82
+ end
83
+
84
+ it 'should keep only events generated within 0.3 seconds' do
85
+ expect(@buffer.config_params).to eq(seconds_to_keep: 0.3)
86
+ time = Time.now
87
+ event1 = @event_generator.call(time)
88
+ @buffer.buffer(event1)
89
+ event2 = @event_generator.call(time + 0.1)
90
+ @buffer.buffer(event2)
91
+ event3 = @event_generator.call(time + 0.2)
92
+ @buffer.buffer(event3)
93
+ @buffer.clear_expired(current_time: time + 0.29)
94
+ expect(@buffer.events).to eq [event1, event2, event3]
95
+
96
+ @buffer.clear_expired(current_time: time + 0.3)
97
+ expect(@buffer.events).to eq [event2, event3]
98
+ end
99
+ end
100
+ end
101
+
102
+ describe '#source' do
103
+ it { expect(@buffer.source).to eq GestureBuffer::DEFAULT_SOURCE }
104
+
105
+ context 'with config' do
106
+ around do |example|
107
+ @source = 'custom_event'
108
+
109
+ ConfigHelper.load_config_yml = <<~CONFIG
110
+ plugin:
111
+ buffers:
112
+ gesture_buffer:
113
+ source: #{@source}
114
+ CONFIG
115
+
116
+ example.run
117
+
118
+ Config.custom_path = nil
119
+ end
120
+
121
+ it { expect(@buffer.source).to eq @source }
122
+ end
123
+ end
124
+
125
+ describe '#sum_attrs' do
126
+ it 'should calculate the sum of each attribute'
127
+ end
128
+
129
+ describe '#avg_attrs' do
130
+ it 'should calculate the average of each attribute'
131
+ end
132
+
133
+ describe '#finger' do
134
+ it 'should return number of fingers in gestures'
135
+ end
136
+
137
+ describe '#gesture' do
138
+ it 'should return string of gesture type'
139
+ end
140
+
141
+ describe '#empty?' do
142
+ context 'no gestures in buffer' do
143
+ before { @buffer.clear }
144
+ it { expect(@buffer.empty?).to be true }
145
+ end
146
+
147
+ context 'buffered some gestures' do
148
+ before { @buffer.buffer(@event_generator.call) }
149
+ it { expect(@buffer.empty?).to be false }
150
+ end
151
+ end
152
+
153
+ describe '#slect_by_events' do
154
+ context 'without block' do
155
+ it { expect(@buffer.select_by_events).to be_a Enumerator }
156
+ end
157
+
158
+ context 'with block' do
159
+ before do
160
+ @e1 = @event_generator.call(nil, 'hoge')
161
+ @e2 = @event_generator.call(nil, 'hoge')
162
+ @e3 = @event_generator.call(nil, 'fuga')
163
+ [@e1, @e2, @e3].each { |event| @buffer.buffer(event) }
164
+ end
165
+ it { expect(@buffer.select_by_events { |e| e.record.status == 'hoge' }).to be_a GestureBuffer }
166
+ it { expect(@buffer.select_by_events { |e| e.record.status == 'hoge' }.events).to eq [@e1, @e2] }
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require './lib/fusuma/plugin/events/event'
6
+ require './lib/fusuma/plugin/detectors/detector'
7
+ require './lib/fusuma/config'
8
+ require_relative '../buffers/dummy_buffer'
9
+ require_relative './dummy_detector'
10
+
11
+ module Fusuma
12
+ module Plugin
13
+ module Detectors
14
+ RSpec.describe DummyDetector do
15
+ before do
16
+ @detector = DummyDetector.new
17
+ @buffer = Buffers::DummyBuffer.new
18
+ end
19
+
20
+ around do |example|
21
+ ConfigHelper.load_config_yml = <<~CONFIG
22
+ plugin:
23
+ detectors:
24
+ dummy_detector:
25
+ dummy: dummy
26
+ CONFIG
27
+
28
+ example.run
29
+
30
+ Config.custom_path = nil
31
+ end
32
+
33
+ describe '#detect' do
34
+ it { expect(@detector.detect([@buffer])).to be_a(Events::Event) }
35
+ end
36
+
37
+ describe '#config_params' do
38
+ it { expect(@detector.config_params).to eq(dummy: 'dummy') }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/fusuma/plugin/detectors/detector'
4
+ require './lib/fusuma/plugin/buffers/buffer'
5
+ require './lib/fusuma/plugin/events/records/index_record'
6
+
7
+ module Fusuma
8
+ module Plugin
9
+ module Detectors
10
+ class DummyDetector < Detector
11
+ # @param buffers [Array<Buffers::Buffer>]
12
+ # @return [Event]
13
+ def detect(buffers)
14
+ buffers.each do |buffer|
15
+ next unless buffer.type == 'dummy'
16
+
17
+ record = Events::Records::IndexRecord.new(index: Config::Index.new(%w[dummy index]))
18
+ return create_event(record: record)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require './lib/fusuma/plugin/detectors/pinch_detector'
6
+ require './lib/fusuma/plugin/buffers/gesture_buffer'
7
+ require './lib/fusuma/plugin/events/event'
8
+ require './lib/fusuma/config'
9
+
10
+ module Fusuma
11
+ module Plugin
12
+ module Detectors
13
+ RSpec.describe PinchDetector do
14
+ before do
15
+ @detector = PinchDetector.new
16
+ @buffer = Buffers::GestureBuffer.new
17
+ end
18
+
19
+ around do |example|
20
+ ConfigHelper.load_config_yml = <<~CONFIG
21
+ threshold:
22
+ rotate: 1
23
+ CONFIG
24
+
25
+ example.run
26
+
27
+ Config.custom_path = nil
28
+ end
29
+
30
+ describe '#detect' do
31
+ context 'with no pinch event in buffer' do
32
+ before do
33
+ @buffer.clear
34
+ end
35
+ it { expect(@detector.detect([@buffer])).to eq nil }
36
+ end
37
+
38
+ context 'with not enough pinch events in buffer' do
39
+ before do
40
+ deltas = [
41
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 1, 0),
42
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 1.1, 0)
43
+ ]
44
+ events = create_events(deltas: deltas)
45
+
46
+ events.each { |event| @buffer.buffer(event) }
47
+ end
48
+ it 'should have repeat record' do
49
+ expect(@detector.detect([@buffer]).record.trigger).to eq :repeat
50
+ end
51
+ end
52
+
53
+ context 'with enough pinch IN event' do
54
+ before do
55
+ deltas = [
56
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 1.0, 0),
57
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 1.0, 0),
58
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 2.0, 0)
59
+ ]
60
+ events = create_events(deltas: deltas)
61
+
62
+ events.each { |event| @buffer.buffer(event) }
63
+ end
64
+ it { expect(@detector.detect([@buffer])).to all be_a Events::Event }
65
+ it { expect(@detector.detect([@buffer]).map(&:record)).to all be_a Events::Records::IndexRecord }
66
+ it { expect(@detector.detect([@buffer]).map(&:record).map(&:index)).to all be_a Config::Index }
67
+
68
+ it 'should detect 3 fingers pinch-in (oneshot/repeat)' do
69
+ events = @detector.detect([@buffer])
70
+ expect(events[0].record.index.keys.map(&:symbol))
71
+ .to eq([:pinch, 3, :in])
72
+ expect(events[1].record.index.keys.map(&:symbol))
73
+ .to eq([:pinch, 3, :in, :update])
74
+ end
75
+ end
76
+
77
+ context 'with enough pinch OUT event' do
78
+ before do
79
+ deltas = [
80
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 1.0, 0),
81
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 0.6, 0),
82
+ Events::Records::GestureRecord::Delta.new(0, 0, 0, 0, 0.3, 0)
83
+ ]
84
+ events = create_events(deltas: deltas)
85
+
86
+ events.each { |event| @buffer.buffer(event) }
87
+ end
88
+ it 'should detect 3 fingers pinch-out (oneshot/repeat)' do
89
+ events = @detector.detect([@buffer])
90
+ expect(events[0].record.index.keys.map(&:symbol))
91
+ .to eq([:pinch, 3, :out])
92
+ expect(events[1].record.index.keys.map(&:symbol))
93
+ .to eq([:pinch, 3, :out, :update])
94
+ end
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def create_events(deltas: [])
101
+ record_type = PinchDetector::GESTURE_RECORD_TYPE
102
+ deltas.map do |delta|
103
+ status = if deltas[0].equal? delta
104
+ 'begin'
105
+ else
106
+ 'update'
107
+ end
108
+
109
+ gesture_record = Events::Records::GestureRecord.new(status: status,
110
+ gesture: record_type,
111
+ finger: 3,
112
+ delta: delta)
113
+ Events::Event.new(tag: 'libinput_gesture_parser', record: gesture_record)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end