fusuma-plugin-tap 0.3.1 → 0.4.1

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