fusuma-plugin-tap 0.3.1 → 0.4.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/bin/libinput_debug_events_generator.rb +8 -3
  4. data/fusuma-plugin-tap.gemspec +3 -5
  5. data/lib/fusuma/plugin/detectors/tap_detector.rb +27 -13
  6. data/lib/fusuma/plugin/parsers/tap_parser.rb +7 -4
  7. data/lib/fusuma/plugin/tap/version.rb +1 -1
  8. data/spec/fusuma/plugin/buffers/tap_buffer_spec.rb +164 -0
  9. data/spec/fusuma/plugin/detectors/tap_detector_spec.rb +169 -0
  10. data/spec/fusuma/plugin/parsers/1.10.4/1finger-double-tap.txt +15 -0
  11. data/spec/fusuma/plugin/parsers/1.10.4/1finger-hold.txt +6 -0
  12. data/spec/fusuma/plugin/parsers/1.10.4/1finger-tap.txt +8 -0
  13. data/spec/fusuma/plugin/parsers/1.10.4/2finger-hold-invalid.txt +259 -0
  14. data/spec/fusuma/plugin/parsers/1.10.4/2finger-hold.txt +116 -0
  15. data/spec/fusuma/plugin/parsers/1.10.4/2finger-pinch-and-hold-bug.txt +356 -0
  16. data/spec/fusuma/plugin/parsers/1.10.4/2finger-tap.txt +12 -0
  17. data/spec/fusuma/plugin/parsers/1.10.4/3finger-hold-invalid.txt +241 -0
  18. data/spec/fusuma/plugin/parsers/1.10.4/3finger-hold.txt +162 -0
  19. data/spec/fusuma/plugin/parsers/1.10.4/3finger-tap.txt +32 -0
  20. data/spec/fusuma/plugin/parsers/1.10.4/4finger-hold-invalid.txt +262 -0
  21. data/spec/fusuma/plugin/parsers/1.10.4/4finger-hold.txt +686 -0
  22. data/spec/fusuma/plugin/parsers/1.10.4/4finger-tap-after-palm-detected-bug.txt +27 -0
  23. data/spec/fusuma/plugin/parsers/1.10.4/4finger-tap.txt +34 -0
  24. data/spec/fusuma/plugin/parsers/1.14.1/1finger-double-tap.txt +13 -0
  25. data/spec/fusuma/plugin/parsers/1.14.1/1finger-hold.txt +5 -0
  26. data/spec/fusuma/plugin/parsers/1.14.1/1finger-tap.txt +7 -0
  27. data/spec/fusuma/plugin/parsers/1.14.1/2finger-hold-invalid.txt +137 -0
  28. data/spec/fusuma/plugin/parsers/1.14.1/2finger-hold.txt +10 -0
  29. data/spec/fusuma/plugin/parsers/1.14.1/2finger-pinch-and-hold-bug.txt +32 -0
  30. data/spec/fusuma/plugin/parsers/1.14.1/2finger-tap.txt +10 -0
  31. data/spec/fusuma/plugin/parsers/1.14.1/3finger-hold-invalid.txt +173 -0
  32. data/spec/fusuma/plugin/parsers/1.14.1/3finger-hold.txt +15 -0
  33. data/spec/fusuma/plugin/parsers/1.14.1/3finger-tap.txt +16 -0
  34. data/spec/fusuma/plugin/parsers/1.14.1/4finger-hold-invalid.txt +158 -0
  35. data/spec/fusuma/plugin/parsers/1.14.1/4finger-hold.txt +9 -0
  36. data/spec/fusuma/plugin/parsers/1.14.1/4finger-tap-after-palm-detected-bug.txt +20 -0
  37. data/spec/fusuma/plugin/parsers/1.14.1/4finger-tap.txt +17 -0
  38. data/spec/fusuma/plugin/parsers/1.15.5/1finger-double-tap.txt +13 -0
  39. data/spec/fusuma/plugin/parsers/1.15.5/1finger-hold.txt +5 -0
  40. data/spec/fusuma/plugin/parsers/1.15.5/1finger-tap.txt +7 -0
  41. data/spec/fusuma/plugin/parsers/1.15.5/2finger-hold-invalid.txt +139 -0
  42. data/spec/fusuma/plugin/parsers/1.15.5/2finger-hold.txt +10 -0
  43. data/spec/fusuma/plugin/parsers/1.15.5/2finger-pinch-and-hold-bug.txt +48 -0
  44. data/spec/fusuma/plugin/parsers/1.15.5/2finger-tap.txt +10 -0
  45. data/spec/fusuma/plugin/parsers/1.15.5/3finger-hold-invalid.txt +172 -0
  46. data/spec/fusuma/plugin/parsers/1.15.5/3finger-hold.txt +14 -0
  47. data/spec/fusuma/plugin/parsers/1.15.5/3finger-tap.txt +15 -0
  48. data/spec/fusuma/plugin/parsers/1.15.5/4finger-hold-invalid.txt +158 -0
  49. data/spec/fusuma/plugin/parsers/1.15.5/4finger-hold.txt +15 -0
  50. data/spec/fusuma/plugin/parsers/1.15.5/4finger-tap-after-palm-detected-bug.txt +20 -0
  51. data/spec/fusuma/plugin/parsers/1.15.5/4finger-tap.txt +15 -0
  52. data/spec/fusuma/plugin/parsers/1.16.5/1finger-double-tap.txt +13 -0
  53. data/spec/fusuma/plugin/parsers/1.16.5/1finger-hold.txt +5 -0
  54. data/spec/fusuma/plugin/parsers/1.16.5/1finger-tap.txt +7 -0
  55. data/spec/fusuma/plugin/parsers/1.16.5/2finger-hold-invalid.txt +142 -0
  56. data/spec/fusuma/plugin/parsers/1.16.5/2finger-hold.txt +10 -0
  57. data/spec/fusuma/plugin/parsers/1.16.5/2finger-pinch-and-hold-bug.txt +48 -0
  58. data/spec/fusuma/plugin/parsers/1.16.5/2finger-tap.txt +10 -0
  59. data/spec/fusuma/plugin/parsers/1.16.5/3finger-hold-invalid.txt +172 -0
  60. data/spec/fusuma/plugin/parsers/1.16.5/3finger-hold.txt +14 -0
  61. data/spec/fusuma/plugin/parsers/1.16.5/3finger-tap.txt +15 -0
  62. data/spec/fusuma/plugin/parsers/1.16.5/4finger-hold-invalid.txt +159 -0
  63. data/spec/fusuma/plugin/parsers/1.16.5/4finger-hold.txt +15 -0
  64. data/spec/fusuma/plugin/parsers/1.16.5/4finger-tap-after-palm-detected-bug.txt +20 -0
  65. data/spec/fusuma/plugin/parsers/1.16.5/4finger-tap.txt +15 -0
  66. data/spec/fusuma/plugin/parsers/evemu/1finger-double-tap.txt +190 -0
  67. data/spec/fusuma/plugin/parsers/evemu/1finger-hold.txt +646 -0
  68. data/spec/fusuma/plugin/parsers/evemu/1finger-tap.txt +156 -0
  69. data/spec/fusuma/plugin/parsers/evemu/2finger-hold-invalid.txt +1789 -0
  70. data/spec/fusuma/plugin/parsers/evemu/2finger-hold.txt +426 -0
  71. data/spec/fusuma/plugin/parsers/evemu/2finger-pinch-and-hold-bug.txt +925 -0
  72. data/spec/fusuma/plugin/parsers/evemu/2finger-tap.txt +164 -0
  73. data/spec/fusuma/plugin/parsers/evemu/3finger-hold-invalid.txt +2129 -0
  74. data/spec/fusuma/plugin/parsers/evemu/3finger-hold.txt +471 -0
  75. data/spec/fusuma/plugin/parsers/evemu/3finger-tap.txt +169 -0
  76. data/spec/fusuma/plugin/parsers/evemu/4finger-hold-invalid.txt +2374 -0
  77. data/spec/fusuma/plugin/parsers/evemu/4finger-hold.txt +575 -0
  78. data/spec/fusuma/plugin/parsers/evemu/4finger-tap-after-palm-detected-bug.txt +250 -0
  79. data/spec/fusuma/plugin/parsers/evemu/4finger-tap.txt +206 -0
  80. data/spec/fusuma/plugin/parsers/tap_parser_spec.rb +200 -0
  81. data/spec/fusuma/plugin/tap_spec.rb +9 -0
  82. data/spec/helpers/config_helper.rb +16 -0
  83. data/spec/spec_helper.rb +18 -0
  84. metadata +161 -19
  85. data/.gitignore +0 -15
  86. data/.rspec +0 -3
  87. data/.rubocop.yml +0 -26
  88. data/.rubocop_todo.yml +0 -56
  89. data/.travis.yml +0 -23
  90. data/CHANGELOG.md +0 -33
  91. data/CODE_OF_CONDUCT.md +0 -74
  92. data/Gemfile +0 -6
  93. data/Makefile +0 -14
  94. data/Rakefile +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbcac570df7314c2824b8b8b2cff3b7b1e53c7f1d89214d15b41d771cff7450b
4
- data.tar.gz: 065071af803859ba19f68e7031faa6682f03a654169b45dd30c2c5a65368a9da
3
+ metadata.gz: a0b6a2fa331a7031a3329d400dd4721da0232a7676ef857eaa366bc14e996fc9
4
+ data.tar.gz: fc4aea089191c918a02546398ccf47c4027ea1980282cc269bbdda697968ec12
5
5
  SHA512:
6
- metadata.gz: 349c907d247d2dd5dc24499672255adf3e0721b41fdc400612e8bb9f608b2412d8d678a1f733d3b964f171bb4d521a2e491faf370eaceb617cdf271e1a91d9d3
7
- data.tar.gz: 0cc70c1117850acb5f727c891815fdf3ae6793a571482b04d1ab1a354d414f4ccd906b45cf41b1a44dbc444da405a8f76db2a369a0fb27685a3fecee2f254fab
6
+ metadata.gz: fe19b07b7314b743b9d1da653944886500f869411d46a037417e3b053bedcd93e533be82a79323dd994d5b361e4b425bf12632b59ae521bc1ee98e92c810fc2a
7
+ data.tar.gz: 3e38a46bf4dba46853af4f716acc459d80daa772914c47ed4148b805cfc07f5c2f7e93f6a02330d0b3c2c41f57e6643cc2e15370afa5172b53a4427d09c52b99
data/README.md CHANGED
@@ -62,6 +62,11 @@ plugin:
62
62
  verbose: true
63
63
  ```
64
64
 
65
+ ## Known issues
66
+ * `libinput debug-events --verbose` outputs is unstable, so it may not work properly with some versions of libinput.
67
+ * **libinput 1.10.4 contains a bug that suddenly stopped detecting taps.**
68
+ * ref: https://github.com/iberianpig/fusuma-plugin-tap/pull/8
69
+
65
70
  ## Development
66
71
 
67
72
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -4,15 +4,16 @@
4
4
  require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'fusuma/device'
7
+ require 'fusuma/plugin/inputs/libinput_command_input'
7
8
 
8
9
  # Generate libinput generator
9
10
  class LibinputDebugEventsGenerator
10
11
  def initialize(evemu_record:)
11
12
  @evemu_record = evemu_record
12
13
  @gesture_name = Pathname.new(evemu_record).basename
13
- @list_devices = ENV.fetch('LIBINPUT_LIST_DEVICES', 'libinput list-devices')
14
- @debug_events = ENV.fetch('LIBINPUT_DEBUG_EVENTS', 'libinput debug-events')
15
- @libinput_version = ENV.fetch('LIBINPUT_VERSION', 'libinput list-devices')
14
+ @list_devices = ENV.fetch('LIBINPUT_LIST_DEVICES')
15
+ @debug_events = ENV.fetch('LIBINPUT_DEBUG_EVENTS')
16
+ @libinput_version = ENV.fetch('LIBINPUT_VERSION')
16
17
  end
17
18
 
18
19
  def generate_debug_events
@@ -41,6 +42,10 @@ class LibinputDebugEventsGenerator
41
42
  rescue Timeout::Error
42
43
  puts 'cut out device infos'
43
44
  end
45
+ if `which evemu-play` == ''
46
+ warn 'evemu-play is not found'
47
+ exit 1
48
+ end
44
49
 
45
50
  command = "evemu-play /dev/input/#{device_id} < #{@evemu_record}"
46
51
 
@@ -16,17 +16,15 @@ Gem::Specification.new do |spec|
16
16
  spec.license = 'MIT'
17
17
 
18
18
  # Specify which files should be added to the gem when it is released.
19
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
- end
19
+ spec.files = Dir['{bin,lib,exe}/**/*', 'LICENSE*', 'README*', '*.gemspec']
20
+ spec.test_files = Dir['{test,spec,features}/**/*']
23
21
  spec.bindir = 'exe'
24
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
23
  spec.require_paths = ['lib']
26
24
 
27
25
  spec.required_ruby_version = '>= 2.3' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
28
26
 
29
- spec.add_dependency 'fusuma', '~> 1.10'
27
+ spec.add_dependency 'fusuma', '~> 2.0.0'
30
28
 
31
29
  spec.add_development_dependency 'bundler'
32
30
  spec.add_development_dependency 'github_changelog_generator', '~> 1.14'
@@ -7,6 +7,7 @@ module Fusuma
7
7
  module Detectors
8
8
  # Detect tap event
9
9
  class TapDetector < Detector
10
+ SOURCES = ['tap', 'gesture', 'timer']
10
11
  BUFFER_TYPE = 'tap'
11
12
  GESTURE_RECORD_TYPE = 'tap'
12
13
 
@@ -18,24 +19,27 @@ module Fusuma
18
19
  # @return [Event] if event is detected
19
20
  # @return [NilClass] if event is NOT detected
20
21
  def detect(buffers)
21
- buffer = buffers.find { |b| b.type == BUFFER_TYPE }
22
+ tap_buffer = buffers.find { |b| b.type == BUFFER_TYPE }
22
23
  gesture_buffer = buffers.find { |b| b.type == 'gesture' }
24
+ timer_buffer = buffers.find { |b| b.type == 'timer' }
23
25
 
24
- return if buffer.empty? || moved?(tap_buffer: buffer, gesture_buffer: gesture_buffer)
26
+ if tap_buffer.empty? || moved?(tap_buffer: tap_buffer, gesture_buffer: gesture_buffer)
27
+ return
28
+ end
25
29
 
26
- holding_time = buffer.events.last.time - buffer.events.first.time
30
+ holding_time = calc_holding_time(tap_buffer: tap_buffer, timer_buffer: timer_buffer)
27
31
 
28
- direction = if hold?(buffer, holding_time)
32
+ direction = if hold?(tap_buffer, holding_time)
29
33
  'hold'
30
- elsif tap?(buffer, holding_time)
34
+ elsif tap?(tap_buffer, holding_time)
31
35
  'tap'
32
36
  end
33
37
 
34
38
  return if direction.nil?
35
39
 
36
- finger = buffer.finger
40
+ finger = tap_buffer.finger
37
41
 
38
- buffer.clear
42
+ tap_buffer.clear # NOTE: Clear after detecting hold
39
43
 
40
44
  index = create_index(finger: finger, direction: direction)
41
45
 
@@ -97,6 +101,16 @@ module Fusuma
97
101
  end
98
102
  end
99
103
 
104
+ def calc_holding_time(tap_buffer:, timer_buffer:)
105
+ last_time = if timer_buffer && !timer_buffer.empty? &&
106
+ (tap_buffer.events.last.time < timer_buffer.events.last.time)
107
+ timer_buffer.events.last.time
108
+ else
109
+ tap_buffer.events.last.time
110
+ end
111
+ last_time - tap_buffer.events.first.time
112
+ end
113
+
100
114
  private
101
115
 
102
116
  def enough?(index:, direction:)
@@ -113,12 +127,12 @@ module Fusuma
113
127
  def interval_time(index:, direction:)
114
128
  @interval_time ||= {}
115
129
  @interval_time[index.cache_key] ||= begin
116
- keys_specific = Config::Index.new [*index.keys, 'interval']
117
- keys_global = Config::Index.new ['interval', direction]
118
- config_value = Config.search(keys_specific) ||
119
- Config.search(keys_global) || 1
120
- BASE_INTERVAL * config_value
121
- end
130
+ keys_specific = Config::Index.new [*index.keys, 'interval']
131
+ keys_global = Config::Index.new ['interval', direction]
132
+ config_value = Config.search(keys_specific) ||
133
+ Config.search(keys_global) || 1
134
+ BASE_INTERVAL * config_value
135
+ end
122
136
  end
123
137
  end
124
138
  end
@@ -67,7 +67,11 @@ module Fusuma
67
67
 
68
68
  finger = case Regexp.last_match(2)
69
69
  when 'TAP_STATE_DEAD'
70
- 4
70
+ if Regexp.last_match(1) == 'TAP_STATE_TOUCH_3'
71
+ 4
72
+ else
73
+ 0
74
+ end
71
75
  when 'TAP_STATE_TOUCH_3'
72
76
  3
73
77
  when 'TAP_STATE_TOUCH_2'
@@ -94,8 +98,7 @@ module Fusuma
94
98
  1
95
99
  end
96
100
  # KEEP
97
- when 'LIBINPUT TIMEOUT', # Timeout Event
98
- /\sgesture(| state):\s/ # 1.10.4 prints "gesture state: GESTURE_STATE_.*"
101
+ when /\sgesture(| state):\s/ # 1.10.4 prints "gesture state: GESTURE_STATE_.*"
99
102
  # NOTE: treat the "gesture(| state):" as KEEP
100
103
  status = 'keep'
101
104
  finger = 0
@@ -144,7 +147,7 @@ module Fusuma
144
147
  Events::Records::GestureRecord.new(status: status,
145
148
  gesture: gesture,
146
149
  finger: finger,
147
- direction: nil)
150
+ delta: nil)
148
151
  end
149
152
 
150
153
  def tag
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Tap
6
- VERSION = '0.3.1'
6
+ VERSION = '0.4.1'
7
7
  end
8
8
  end
9
9
  end
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fusuma/plugin/events/records/gesture_record.rb'
6
+ require 'fusuma/plugin/events/event.rb'
7
+ require 'fusuma/plugin/buffers/buffer.rb'
8
+
9
+ module Fusuma
10
+ module Plugin
11
+ module Buffers
12
+ RSpec.describe TapBuffer do
13
+ before do
14
+ @buffer = TapBuffer.new
15
+ @event_generator = lambda { |time = nil, finger = 1, status = 'begin'|
16
+ Events::Event.new(time: time,
17
+ tag: 'libinput_tap_parser',
18
+ record: Events::Records::GestureRecord.new(
19
+ status: status,
20
+ gesture: 'tap',
21
+ finger: finger,
22
+ delta: nil
23
+ ))
24
+ }
25
+ end
26
+
27
+ describe '#type' do
28
+ it { expect(@buffer.type).to eq 'tap' }
29
+ end
30
+
31
+ describe '#buffer' do
32
+ it 'should buffer gesture event' do
33
+ event = @event_generator.call(Time.now)
34
+ @buffer.buffer(event)
35
+ expect(@buffer.events).to eq [event]
36
+ end
37
+
38
+ it 'should NOT buffer other event' do
39
+ event = Events::Event.new(tag: 'SHOULD NOT BUFFER', record: 'dummy record')
40
+ @buffer.buffer(event)
41
+ expect(@buffer.events).to eq []
42
+ end
43
+ end
44
+
45
+ describe '#clear_expired' do
46
+ context 'with including end' do
47
+ it 'should NOT clear any events' do
48
+ time = Time.now
49
+ event1 = @event_generator.call(time, 1, 'begin')
50
+ event2 = @event_generator.call(time + 0.1, 2, 'touch')
51
+ event3 = @event_generator.call(time + 0.2, 1, 'release')
52
+ event4 = @event_generator.call(time + 0.2, 1, 'end')
53
+ @buffer.buffer(event1)
54
+ @buffer.buffer(event2)
55
+ @buffer.buffer(event3)
56
+ @buffer.buffer(event4)
57
+
58
+ @buffer.clear_expired(current_time: time + 100)
59
+
60
+ expect(@buffer.events).to eq []
61
+ end
62
+ end
63
+ context 'WITHOUT including end' do
64
+ it 'should NOT clear any events' do
65
+ time = Time.now
66
+ event1 = @event_generator.call(time, 1, 'begin')
67
+ event2 = @event_generator.call(time + 0.1, 2, 'touch')
68
+ event3 = @event_generator.call(time + 0.2, 1, 'release')
69
+ @buffer.buffer(event1)
70
+ @buffer.buffer(event2)
71
+ @buffer.buffer(event3)
72
+
73
+ @buffer.clear_expired(current_time: time + 100)
74
+
75
+ expect(@buffer.events).to eq [event1, event2, event3]
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#bufferable?' do
81
+ it 'should buffer first begin event' do
82
+ time = Time.now
83
+ event1 = @event_generator.call(time, 1, 'begin')
84
+ expect(@buffer.bufferable?(event1)).to eq true
85
+ end
86
+
87
+ context 'already exists events in buffer' do
88
+ before do
89
+ event2 = @event_generator.call(Time.now, 1, 'begin')
90
+ @buffer.buffer(event2)
91
+ end
92
+ it 'should NOT buffer begin event' do
93
+ event2 = @event_generator.call(Time.now, 1, 'begin')
94
+ expect(@buffer.bufferable?(event2)).to eq false
95
+ end
96
+
97
+ it 'should buffer touch event' do
98
+ event2 = @event_generator.call(Time.now, 2, 'touch')
99
+ expect(@buffer.bufferable?(event2)).to eq true
100
+ end
101
+
102
+ it 'should buffer release event' do
103
+ event2 = @event_generator.call(Time.now, 1, 'release')
104
+ expect(@buffer.bufferable?(event2)).to eq true
105
+ end
106
+
107
+ it 'should buffer end event' do
108
+ event2 = @event_generator.call(Time.now, 1, 'end')
109
+ expect(@buffer.bufferable?(event2)).to eq true
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#source' do
115
+ it { expect(@buffer.source).to eq TapBuffer::DEFAULT_SOURCE }
116
+
117
+ context 'with config' do
118
+ around do |example|
119
+ @source = 'custom_event'
120
+
121
+ ConfigHelper.load_config_yml = <<~CONFIG
122
+ plugin:
123
+ buffers:
124
+ tap_buffer:
125
+ source: #{@source}
126
+ CONFIG
127
+
128
+ example.run
129
+
130
+ Config.custom_path = nil
131
+ end
132
+
133
+ it { expect(@buffer.source).to eq @source }
134
+ end
135
+ end
136
+
137
+ describe '#finger' do
138
+ it 'should return number of fingers in gestures' do
139
+ @buffer.buffer(@event_generator.call(Time.now, 1, 'begin'))
140
+ expect(@buffer.finger).to eq 1
141
+ @buffer.buffer(@event_generator.call(Time.now, 2, 'touch'))
142
+ expect(@buffer.finger).to eq 2
143
+ @buffer.buffer(@event_generator.call(Time.now, 3, 'touch'))
144
+ expect(@buffer.finger).to eq 3
145
+ @buffer.buffer(@event_generator.call(Time.now, 3, 'release'))
146
+ expect(@buffer.finger).to eq 3
147
+ end
148
+ end
149
+
150
+ describe '#empty?' do
151
+ context 'no gestures in buffer' do
152
+ before { @buffer.clear }
153
+ it { expect(@buffer.empty?).to be true }
154
+ end
155
+
156
+ context 'buffered some gestures' do
157
+ before { @buffer.buffer(@event_generator.call(Time.now, 'begin')) }
158
+ it { expect(@buffer.empty?).to be false }
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fusuma/plugin/detectors/detector.rb'
6
+ require 'fusuma/plugin/buffers/gesture_buffer.rb'
7
+ require 'fusuma/plugin/events/event.rb'
8
+
9
+ module Fusuma
10
+ module Plugin
11
+ module Detectors
12
+ RSpec.describe TapDetector do
13
+ before do
14
+ @detector = TapDetector.new
15
+ @buffer = Buffers::TapBuffer.new
16
+ @buffers = [@buffer, Buffers::GestureBuffer.new]
17
+
18
+ @event_generator = lambda { |time, finger, status|
19
+ Events::Event.new(
20
+ time: time,
21
+ tag: 'libinput_tap_parser',
22
+ record: Events::Records::GestureRecord.new(
23
+ finger: finger,
24
+ gesture: 'tap',
25
+ status: status,
26
+ delta: Events::Records::GestureRecord::Delta.new(0, 0, 0, 0)
27
+ )
28
+ )
29
+ }
30
+ end
31
+
32
+ describe '#detect' do
33
+ context 'with 1 finger tap events in buffer' do
34
+ before do
35
+ [
36
+ @event_generator.call(Time.now, 1, 'begin'),
37
+ @event_generator.call(Time.now, 1, 'release')
38
+ ].each { |event| @buffer.buffer(event) }
39
+ end
40
+
41
+ it 'should generate tap index' do
42
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
43
+ expect(key_symbol).to eq [:tap, 1]
44
+ end
45
+ end
46
+
47
+ context 'with 2 fingers tap events in buffer' do
48
+ before do
49
+ [
50
+ @event_generator.call(Time.now, 1, 'begin'),
51
+ @event_generator.call(Time.now, 2, 'touch'),
52
+ @event_generator.call(Time.now, 2, 'release')
53
+ ].each { |event| @buffer.buffer(event) }
54
+ end
55
+
56
+ it 'should generate tap index' do
57
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
58
+ expect(key_symbol).to eq [:tap, 2]
59
+ end
60
+ end
61
+
62
+ context 'with 3 fingers tap events in buffer' do
63
+ before do
64
+ time = Time.now
65
+ [
66
+ @event_generator.call(time, 1, 'begin'),
67
+ @event_generator.call(time, 2, 'touch'),
68
+ @event_generator.call(time, 3, 'touch'),
69
+ @event_generator.call(time, 3, 'release'),
70
+ @event_generator.call(time + 0.1, 2, 'release')
71
+ ].each { |event| @buffer.buffer(event) }
72
+ end
73
+
74
+ it 'should generate tap index' do
75
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
76
+ expect(key_symbol).to eq [:tap, 3]
77
+ end
78
+ end
79
+ context 'with 4 fingers tap events in buffer' do
80
+ before do
81
+ time = Time.now
82
+ [
83
+ @event_generator.call(time, 1, 'begin'),
84
+ @event_generator.call(time, 2, 'touch'),
85
+ @event_generator.call(time, 3, 'touch'),
86
+ @event_generator.call(time, 4, 'touch'),
87
+ @event_generator.call(time + 0.1, 4, 'end')
88
+ ].each { |event| @buffer.buffer(event) }
89
+ end
90
+
91
+ it 'should generate tap index' do
92
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
93
+ expect(key_symbol).to eq [:tap, 4]
94
+ end
95
+ end
96
+
97
+ context 'with 1 finger hold events in buffer' do
98
+ before do
99
+ time = Time.now
100
+ [
101
+ @event_generator.call(time, 1, 'begin'),
102
+ @event_generator.call(time + 2, 1, 'hold')
103
+ ].each { |event| @buffer.buffer(event) }
104
+ end
105
+
106
+ it 'should generate tap index' do
107
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
108
+ expect(key_symbol).to eq [:hold, 1]
109
+ end
110
+ end
111
+
112
+ context 'with 2 fingers hold events in buffer' do
113
+ before do
114
+ time = Time.now
115
+ [
116
+ @event_generator.call(time, 1, 'begin'),
117
+ @event_generator.call(time, 2, 'touch'),
118
+ @event_generator.call(time, 2, 'hold'),
119
+ @event_generator.call(time + 1, 2, 'release')
120
+ ].each { |event| @buffer.buffer(event) }
121
+ end
122
+
123
+ it 'should generate tap index' do
124
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
125
+ expect(key_symbol).to eq [:hold, 2]
126
+ end
127
+ end
128
+ context 'with 3 fingers hold events in buffer' do
129
+ before do
130
+ time = Time.now
131
+ [
132
+ @event_generator.call(time, 1, 'begin'),
133
+ @event_generator.call(time, 2, 'touch'),
134
+ @event_generator.call(time, 3, 'hold'),
135
+ @event_generator.call(time, 3, 'release'),
136
+ @event_generator.call(time + 1, 2, 'release')
137
+ ].each { |event| @buffer.buffer(event) }
138
+ end
139
+
140
+ it 'should generate hold index' do
141
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
142
+ expect(key_symbol).to eq [:hold, 3]
143
+ end
144
+ end
145
+ context 'with 4 fingers hold events in buffer' do
146
+ before do
147
+ time = Time.now
148
+ [
149
+ @event_generator.call(time, 1, 'begin'),
150
+ @event_generator.call(time, 2, 'touch'),
151
+ @event_generator.call(time, 3, 'touch'),
152
+ @event_generator.call(time, 4, 'touch'),
153
+ @event_generator.call(time, 0, 'keep'),
154
+ @event_generator.call(time, 0, 'keep'),
155
+ @event_generator.call(time, 0, 'keep'),
156
+ @event_generator.call(time + 1, 2, 'release')
157
+ ].each { |event| @buffer.buffer(event) }
158
+ end
159
+
160
+ it 'should generate hold index' do
161
+ key_symbol = @detector.detect(@buffers).record.index.keys.map(&:symbol)
162
+ expect(key_symbol).to eq [:hold, 4]
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end