fusuma-plugin-sendkey 0.6.4 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b0d16b0e0388ece2a4315f7c7750d7c94bf838f9cbdd6637804fc7b288963b5
4
- data.tar.gz: 44af0181708e6556ebddea600e61fbe23b53ac6816dd4939d572eafa83b9000c
3
+ metadata.gz: 0512b4f118bd0b676616741f47a643a759d8eb123eb581bb3136b38a34f0acc4
4
+ data.tar.gz: 45cafd5f8b3f8cd1e44643c20438b04ce59065854548123285ea5eea1e5585fc
5
5
  SHA512:
6
- metadata.gz: 1fc15b8f4242f9914c0b07e318711dfb8f7d82e3522817f9c7d59352938aa244c7bbb542c491dcd4d949207f019a84f46821c81ecfa1dc99bd1fcb61a6fc63cf
7
- data.tar.gz: 73bd090d983315fa128c18ed61f7a293c5ba805064ae06c801472295b75913540ca7e15bf46bee27a84d1f32fea63e42b4310fad6198b378ad3c8ee28aeeea94
6
+ metadata.gz: 264b5e7d2ae3729ccc1f3fe0db02dab1ee1999e089fab2cd2df9f97f3994ff0c20976e37a6e2105c141161dc70db20d4058098529bba5372427bfe242d6d10d5
7
+ data.tar.gz: b1cb6a075c279a15e63f7685d5887dc0b2c4c767915fb4066b2d929788b725c2d8127d766e5045ee5b1c49f2f40e9882793066e6607f56d2dae967347d89667a
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Fusuma::Plugin::Sendkey [![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg)](https://badge.fury.io/rb/fusuma-plugin-sendkey) [![Build Status](https://travis-ci.com/iberianpig/fusuma-plugin-sendkey.svg?branch=master)](https://travis-ci.com/iberianpig/fusuma-plugin-sendkey)
1
+ # Fusuma::Plugin::Sendkey [![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg)](https://badge.fury.io/rb/fusuma-plugin-sendkey) [![Build Status](https://github.com/iberianpig/fusuma-plugin-sendkey/actions/workflows/main.yml/badge.svg)](https://github.com/iberianpig/fusuma-plugin-sendkey/actions/workflows/main.yml)
2
2
 
3
3
  [Fusuma](https://github.com/iberianpig/fusuma) plugin to send keyboard events
4
4
 
@@ -85,6 +85,20 @@ swipe:
85
85
  sendkey: "LEFTCTRL+W" # close tab
86
86
  ```
87
87
 
88
+ ### clearmodifiers
89
+
90
+ - `clearmodifiers: true` option clears other modifier keys before sending
91
+
92
+ ```yaml
93
+ swipe:
94
+ 4:
95
+ up:
96
+ keypress:
97
+ LEFTSHIFT:
98
+ sendkey: "LEFTMETA+DOWN"
99
+ clearmodifiers: true # clear LEFTSHIFT before sending LEFTMETA+DOWN
100
+ ```
101
+
88
102
 
89
103
  ### Specify keyboard by device name
90
104
 
@@ -105,6 +119,9 @@ plugin:
105
119
  device_name: 'YOUR KEYBOARD NAME'
106
120
  ```
107
121
 
122
+ **If [fusuma-plugin-remap](https://github.com/iberianpig/fusuma-plugin-remap) is available, it will be automatically connected to `fusuma_virtual_keyboard`, so `device_name` option is not required.**
123
+
124
+
108
125
  ## Contributing
109
126
 
110
127
  Bug reports and pull requests are welcome on GitHub at https://github.com/iberianpig/fusuma-plugin-sendkey. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
data/bin/console CHANGED
@@ -4,9 +4,7 @@ require "bundler/setup"
4
4
  require 'fusuma/plugin/executors/executor'
5
5
  require "fusuma/plugin/sendkey"
6
6
 
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
7
+ Fusuma::Plugin::Manager.require_base_plugins
9
8
 
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- require "pry"
12
- Pry.start
9
+ require "irb"
10
+ IRB.start(__FILE__)
@@ -1,29 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'fusuma/plugin/sendkey/version'
5
+ require "fusuma/plugin/sendkey/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'fusuma-plugin-sendkey'
9
- spec.version = Fusuma::Plugin::Sendkey::VERSION
10
- spec.authors = ['iberianpig']
11
- spec.email = ['yhkyky@gmail.com']
8
+ spec.name = "fusuma-plugin-sendkey"
9
+ spec.version = Fusuma::Plugin::Sendkey::VERSION
10
+ spec.authors = ["iberianpig"]
11
+ spec.email = ["yhkyky@gmail.com"]
12
12
 
13
- spec.summary = 'Fusuma plugin to send keyboard events'
14
- spec.description = 'Fusuma::Plugin::Sendkey emulate keyboard events with evdev'
15
- spec.homepage = 'https://github.com/iberianpig/fusuma-plugin-sendkey'
16
- spec.license = 'MIT'
13
+ spec.summary = "Fusuma plugin to send keyboard events"
14
+ spec.description = "Fusuma::Plugin::Sendkey emulate keyboard events with evdev"
15
+ spec.homepage = "https://github.com/iberianpig/fusuma-plugin-sendkey"
16
+ spec.license = "MIT"
17
17
 
18
18
  # Specify which files should be added to the gem when it is released.
19
- spec.files = Dir['{bin,lib,exe}/**/*', 'LICENSE*', 'README*', '*.gemspec']
20
- spec.test_files = Dir['{test,spec,features}/**/*']
21
- spec.bindir = 'exe'
22
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
- spec.require_paths = ['lib']
24
- spec.required_ruby_version = '>= 2.5.1' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
19
+ spec.files = Dir["{bin,lib,exe}/**/*", "LICENSE*", "README*", "*.gemspec"]
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+ spec.required_ruby_version = ">= 2.5.1" # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
25
24
  # support bionic (18.04LTS) 2.5.1
26
25
 
27
- spec.add_dependency 'fusuma', '~> 2.0'
28
- spec.add_dependency 'revdev'
26
+ spec.add_dependency "fusuma", "~> 2.0"
27
+ spec.add_dependency "revdev"
29
28
  end
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../sendkey/keyboard'
3
+ require_relative "../sendkey/keyboard"
4
4
 
5
5
  module Fusuma
6
6
  module Plugin
7
7
  module Executors
8
- # Control Window or Workspaces by executing wctrl
8
+ # Execute to send key event to device
9
9
  class SendkeyExecutor < Executor
10
+ def initialize
11
+ @device_name = config_params(:device_name)
12
+ super
13
+ end
14
+
10
15
  def execute_keys
11
16
  [:sendkey]
12
17
  end
@@ -22,26 +27,18 @@ module Fusuma
22
27
  # @return [nil]
23
28
  def execute(event)
24
29
  MultiLogger.info(sendkey: search_param(event))
25
- pid = fork do
26
- Process.daemon(true)
27
- _execute(event)
28
- end
29
-
30
- Process.detach(pid)
31
- end
32
-
33
- # execute sendkey command
34
- # @param event [Event]
35
- # @return [nil]
36
- def _execute(event)
37
- keyboard.type(param: search_param(event))
30
+ keyboard.type(
31
+ param: search_param(event),
32
+ keep: search_keypress(event),
33
+ clear: clearmodifiers(event)
34
+ )
38
35
  end
39
36
 
40
37
  # check executable
41
38
  # @param event [Event]
42
39
  # @return [TrueClass, FalseClass]
43
40
  def executable?(event)
44
- event.tag.end_with?('_detector') &&
41
+ event.tag.end_with?("_detector") &&
45
42
  event.record.type == :index &&
46
43
  keyboard.valid?(param: search_param(event))
47
44
  end
@@ -49,16 +46,36 @@ module Fusuma
49
46
  private
50
47
 
51
48
  def keyboard
52
- @keyboard ||= begin
53
- name_pattren = config_params(:device_name)
54
- Sendkey::Keyboard.new(name_pattern: name_pattren)
55
- end
49
+ @keyboard ||= Sendkey::Keyboard.new(name_pattern: @device_name)
56
50
  end
57
51
 
58
52
  def search_param(event)
59
53
  index = Config::Index.new([*event.record.index.keys, :sendkey])
60
54
  Config.search(index)
61
55
  end
56
+
57
+ # search keypress from config for keep modifiers when sendkey
58
+ # @param event [Event]
59
+ # @return [String]
60
+ def search_keypress(event)
61
+ # if fusuma_virtual_keyboard exists, don't have to keep modifiers
62
+ return "" if keyboard.use_virtual_keyboard?
63
+
64
+ keys = event.record.index.keys
65
+ keypress_index = keys.find_index { |k| k.symbol == :keypress }
66
+ code = keypress_index && keys[keypress_index + 1].symbol
67
+ code.to_s
68
+ end
69
+
70
+ # clearmodifiers from config
71
+ # @param event [Event]
72
+ # @return [String, TrueClass, Symbole]
73
+ def clearmodifiers(event)
74
+ @clearmodifiers ||= {}
75
+ index = event.record.index
76
+ @clearmodifiers[index.cache_key] ||=
77
+ Config.search(Config::Index.new([*index.keys, "clearmodifiers"])) || :none
78
+ end
62
79
  end
63
80
  end
64
81
  end
@@ -10,7 +10,7 @@ module Fusuma
10
10
  end
11
11
 
12
12
  def path
13
- raise 'Device path is not found' if @evdev.nil?
13
+ raise "Device path is not found" if @evdev.nil?
14
14
 
15
15
  @path ||= @evdev.file.path
16
16
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'revdev'
4
- require 'fusuma/device'
3
+ require "revdev"
4
+ require "fusuma/device"
5
5
 
6
- require_relative './device'
6
+ require_relative "./device"
7
7
 
8
8
  module Fusuma
9
9
  module Plugin
@@ -24,120 +24,150 @@ module Fusuma
24
24
  KEY_RIGHTMETA
25
25
  ].freeze
26
26
 
27
+ DEFAULT_NAME_PATTERN = "keyboard|Keyboard|KEYBOARD"
28
+ VIRTUAL_KEYBOARD = "fusuma_virtual_keyboard" # fusuma-plugin-remap creates uinput device
29
+
27
30
  def self.find_device(name_pattern:)
31
+ Fusuma::Device.reset
28
32
  Fusuma::Device.all.find { |d| d.name.match(/#{name_pattern}/) }
29
33
  end
30
34
 
31
35
  def initialize(name_pattern: nil)
32
- name_pattern ||= 'keyboard|Keyboard|KEYBOARD'
33
- device = Keyboard.find_device(name_pattern: name_pattern)
36
+ device = if name_pattern
37
+ Keyboard.find_device(name_pattern: name_pattern)
38
+ else
39
+ Keyboard.find_device(name_pattern: VIRTUAL_KEYBOARD) || Keyboard.find_device(name_pattern: DEFAULT_NAME_PATTERN)
40
+ end
34
41
 
35
42
  if device.nil?
36
43
  warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
37
44
  exit(1)
38
45
  end
46
+ MultiLogger.info "sendkey: Keyboard: #{device.name}"
39
47
 
48
+ @use_virtual_keyboard = device.name.match(/#{VIRTUAL_KEYBOARD}/o)
40
49
  @device = Device.new(path: "/dev/input/#{device.id}")
41
50
  end
42
51
 
43
- attr_reader :device
52
+ def use_virtual_keyboard?
53
+ @use_virtual_keyboard
54
+ end
44
55
 
45
- # @param param [String]
46
- # @param keep [String]
47
- def type(param:)
56
+ # @param param [String] key names separated by '+' to type
57
+ # @param keep [String] key names separated by '+' to keep
58
+ # @param clear [String, Symbol, TrueClass] key names separated by '+' to clear or :all to relase all modifiers
59
+ def type(param:, keep: "", clear: :none)
48
60
  return unless param.is_a?(String)
49
61
 
50
- keycodes = split_param(param)
51
- clear_modifiers(MODIFIER_KEY_CODES - keycodes)
52
- keycodes.each { |keycode| key_event(keycode: keycode, press: true) && wait }
53
- key_sync(press: true)
54
- keycodes.reverse.each { |keycode| key_event(keycode: keycode, press: false) && wait }
55
- key_sync(press: false)
62
+ param_keycodes = param_to_keycodes(param)
63
+ type_keycodes = param_keycodes - param_to_keycodes(keep)
64
+
65
+ clear_keycodes =
66
+ case clear
67
+ when true
68
+ MODIFIER_KEY_CODES
69
+ when :none, false
70
+ []
71
+ else
72
+ # release keys specified by clearmodifiers
73
+ param_to_keycodes(clear)
74
+ end
75
+
76
+ clear_modifiers(clear_keycodes - param_keycodes)
77
+
78
+ type_keycodes.each { |keycode| keydown(keycode) && key_sync }
79
+ type_keycodes.reverse_each { |keycode| keyup(keycode) && key_sync }
80
+ end
81
+
82
+ def keydown(keycode)
83
+ send_event(code: keycode, press: true)
84
+ end
85
+
86
+ def keyup(keycode)
87
+ send_event(code: keycode, press: false)
56
88
  end
57
89
 
58
90
  # @param param [String]
59
91
  def valid?(param:)
60
92
  return unless param.is_a?(String)
61
93
 
62
- keycodes = split_param(param)
94
+ keycodes = param_to_keycodes(param)
63
95
  keycodes.all? { |keycode| support?(keycode) }
64
96
  end
65
97
 
66
- def key_event(keycode:, press: true)
98
+ def send_event(code:, press: true)
67
99
  event = Revdev::InputEvent.new(
68
100
  nil,
69
101
  Revdev.const_get(:EV_KEY),
70
- Revdev.const_get(keycode),
102
+ Revdev.const_get(code),
71
103
  press ? 1 : 0
72
104
  )
73
105
  @device.write_event(event)
74
106
  end
75
107
 
76
- def key_sync(press: true)
108
+ def key_sync
77
109
  event = Revdev::InputEvent.new(
78
110
  nil,
79
111
  Revdev.const_get(:EV_SYN),
80
112
  Revdev.const_get(:SYN_REPORT),
81
- press ? 1 : 0
113
+ 0
82
114
  )
83
115
  @device.write_event(event)
116
+ sleep(INTERVAL)
84
117
  end
85
118
 
86
119
  def support?(keycode)
87
120
  @supported_code ||= {}
88
- @supported_code[keycode] ||= if find_code(keycode: keycode)
89
- true
90
- else
91
- search_candidates(keycode: keycode)
92
- end
121
+ @supported_code[keycode] ||= find_code(keycode: keycode)
93
122
  end
94
123
 
95
- def search_candidates(keycode:)
96
- query = keycode&.upcase&.gsub('KEY_', '')
124
+ def warn_undefined_codes(keycode:)
125
+ query = keycode&.upcase&.gsub("KEY_", "")
97
126
 
98
127
  candidates = search_codes(query: query)
99
128
 
100
- warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
129
+ warn "Did you mean? #{candidates.join(" / ")}" unless candidates.empty?
101
130
  warn "sendkey: #{remove_prefix(keycode)} is unsupported."
102
131
  end
103
132
 
104
133
  def search_codes(query: nil)
105
134
  Revdev.constants
106
- .select { |c| c[/KEY_.*#{query}.*/] }
107
- .map { |c| c.to_s.gsub('KEY_', '') }
135
+ .select { |c| c[/KEY_.*#{query}.*/] }
136
+ .map { |c| c.to_s.gsub("KEY_", "") }
108
137
  end
109
138
 
110
139
  def find_code(keycode: nil)
111
- query = keycode&.upcase&.gsub('KEY_', '')
140
+ query = keycode&.upcase&.gsub("KEY_", "")
141
+
142
+ result = Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
112
143
 
113
- Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
144
+ warn_undefined_codes(keycode: keycode) unless result
145
+ result
114
146
  end
115
147
 
116
148
  def keycode_const(keycode)
117
- Object.const_get "LinuxInput::#{keycode}"
149
+ Object.const_get "Revdev::#{keycode}"
118
150
  end
119
151
 
120
152
  # @param [Array<String>] keycodes to be released
121
153
  def clear_modifiers(keycodes)
122
- keycodes.each { |code| key_event(keycode: code, press: false) }
154
+ keycodes.each { |code| send_event(code: code, press: false) }
123
155
  end
124
156
 
125
- private
126
-
127
- def split_param(param)
128
- param.split('+').map { |code| key_prefix(code) }
157
+ # @param [String]
158
+ # @return [Array<String>]
159
+ def param_to_keycodes(param)
160
+ param.split("+").map { |keyname| add_key_prefix(keyname) }
129
161
  end
130
162
 
131
- def key_prefix(code)
163
+ private
164
+
165
+ def add_key_prefix(code)
132
166
  "KEY_#{code.upcase}"
133
167
  end
134
168
 
135
169
  def remove_prefix(keycode)
136
- keycode.gsub('KEY_', '')
137
- end
138
-
139
- def wait
140
- sleep(INTERVAL)
170
+ keycode.gsub("KEY_", "")
141
171
  end
142
172
  end
143
173
  end
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Sendkey
6
- VERSION = '0.6.4'
6
+ VERSION = "0.8.0"
7
7
  end
8
8
  end
9
9
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # fusuma will `require fusuma-plugin-xxxx/plugin/xxxx.rb`
4
4
 
5
- require_relative './sendkey/version'
6
- require_relative './executors/sendkey_executor'
5
+ require_relative "./sendkey/version"
6
+ require_relative "./executors/sendkey_executor"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusuma-plugin-sendkey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-06 00:00:00.000000000 Z
11
+ date: 2023-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fusuma
@@ -57,16 +57,11 @@ files:
57
57
  - lib/fusuma/plugin/sendkey/device.rb
58
58
  - lib/fusuma/plugin/sendkey/keyboard.rb
59
59
  - lib/fusuma/plugin/sendkey/version.rb
60
- - spec/fusuma/plugin/executors/sendkey_executor_spec.rb
61
- - spec/fusuma/plugin/sendkey/keyboard_spec.rb
62
- - spec/fusuma/plugin/sendkey_spec.rb
63
- - spec/helpers/config_helper.rb
64
- - spec/spec_helper.rb
65
60
  homepage: https://github.com/iberianpig/fusuma-plugin-sendkey
66
61
  licenses:
67
62
  - MIT
68
63
  metadata: {}
69
- post_install_message:
64
+ post_install_message:
70
65
  rdoc_options: []
71
66
  require_paths:
72
67
  - lib
@@ -81,13 +76,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
76
  - !ruby/object:Gem::Version
82
77
  version: '0'
83
78
  requirements: []
84
- rubygems_version: 3.2.22
85
- signing_key:
79
+ rubygems_version: 3.3.26
80
+ signing_key:
86
81
  specification_version: 4
87
82
  summary: Fusuma plugin to send keyboard events
88
- test_files:
89
- - spec/fusuma/plugin/executors/sendkey_executor_spec.rb
90
- - spec/fusuma/plugin/sendkey/keyboard_spec.rb
91
- - spec/fusuma/plugin/sendkey_spec.rb
92
- - spec/helpers/config_helper.rb
93
- - spec/spec_helper.rb
83
+ test_files: []
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- require 'fusuma/plugin/executors/executor'
6
- require 'fusuma/plugin/events/event'
7
- require 'fusuma/plugin/events/records/index_record'
8
-
9
- require './lib/fusuma/plugin/executors/sendkey_executor'
10
-
11
- module Fusuma
12
- module Plugin
13
- module Executors
14
- RSpec.describe SendkeyExecutor do
15
- around do |example|
16
- ConfigHelper.load_config_yml = <<~CONFIG
17
- dummy:
18
- 1:
19
- direction:
20
- sendkey: KEY_CODE
21
-
22
- plugin:
23
- executors:
24
- sendkey_executor:
25
- device_name: dummy
26
- CONFIG
27
-
28
- example.run
29
-
30
- Config.custom_path = nil
31
- end
32
-
33
- before do
34
- index = Config::Index.new([:dummy, 1, :direction])
35
- record = Events::Records::IndexRecord.new(index: index)
36
- @event = Events::Event.new(tag: 'dummy_detector', record: record)
37
- @executor = described_class.new
38
-
39
- @keyboard = instance_double(Sendkey::Keyboard)
40
-
41
- allow(@executor).to receive(:keyboard).and_return @keyboard
42
- end
43
-
44
- describe '#execute' do
45
- before do
46
- allow(Process).to receive(:daemon).with(true)
47
- allow(Process).to receive(:detach).with(anything)
48
- end
49
-
50
- it 'fork' do
51
- expect(@executor).to receive(:fork).and_yield do |block_context|
52
- expect(block_context).to receive(:_execute).with(@event)
53
- end
54
-
55
- @executor.execute(@event)
56
- end
57
- end
58
-
59
- describe '#_execute' do
60
- it 'send KEY_CODE message to keybard' do
61
- allow(@executor).to receive(:search_param).with(@event).and_return('KEY_CODE')
62
- expect(@keyboard).to receive(:type).with(param: 'KEY_CODE')
63
- @executor._execute(@event)
64
- end
65
- end
66
-
67
- describe '#executable?' do
68
- before do
69
- allow(@keyboard).to receive(:valid?).with(param: 'MODIFIER_CODE+KEY_CODE')
70
- .and_return true
71
- allow(@keyboard).to receive(:valid?).with(param: 'KEY_CODE')
72
- .and_return true
73
- allow(@keyboard).to receive(:valid?).with(param: 'INVALID_CODE')
74
- .and_return false
75
- end
76
-
77
- context 'when given valid event tagged as xxxx_detector' do
78
- it { expect(@executor).to be_executable(@event) }
79
- end
80
-
81
- context 'when given INVALID event tagged as invalid_tag' do
82
- before do
83
- @event.tag = 'invalid_tag'
84
- end
85
-
86
- it { expect(@executor).not_to be_executable(@event) }
87
- end
88
-
89
- context "when sendkey: 'MODIFIER_CODE+KEY_CODE'" do
90
- around do |example|
91
- ConfigHelper.load_config_yml = <<~CONFIG
92
- dummy:
93
- 1:
94
- direction:
95
- sendkey: 'MODIFIER_CODE+KEY_CODE'
96
- plugin:
97
- executors:
98
- sendkey_executor:
99
- device_name: dummy
100
- CONFIG
101
-
102
- example.run
103
-
104
- Config.custom_path = nil
105
- end
106
-
107
- it 'returns true' do
108
- expect(@executor).to be_executable(@event)
109
- end
110
- end
111
-
112
- context "when sendkey: 'INVALID_CODE'" do
113
- around do |example|
114
- ConfigHelper.load_config_yml = <<~CONFIG
115
- dummy:
116
- 1:
117
- direction:
118
- sendkey: 'INVALID_CODE'
119
- plugin:
120
- executors:
121
- sendkey_executor:
122
- device_name: dummy
123
- CONFIG
124
-
125
- example.run
126
-
127
- Config.custom_path = nil
128
- end
129
-
130
- it 'returns true' do
131
- expect(@executor).not_to be_executable(@event)
132
- end
133
- end
134
- end
135
- end
136
- end
137
- end
138
- end
@@ -1,199 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- require './lib/fusuma/plugin/sendkey/keyboard'
6
-
7
- module Fusuma
8
- module Plugin
9
- module Sendkey
10
- RSpec.describe Keyboard do
11
- describe '#new' do
12
- context 'when keyboard is found' do
13
- before do
14
- dummy_keyboard = Fusuma::Device.new(name: 'dummy keyboard')
15
- allow(described_class)
16
- .to receive(:find_device)
17
- .and_return(dummy_keyboard)
18
- allow(Sendkey::Device).to receive(:new).and_return('dummy')
19
- end
20
-
21
- it 'does not raise error' do
22
- expect { described_class.new }.not_to raise_error
23
- end
24
- end
25
-
26
- context 'when keyboard is not found' do
27
- before do
28
- allow(described_class)
29
- .to receive(:find_device)
30
- .and_return(nil)
31
- end
32
-
33
- it 'does not raise error' do
34
- expect { described_class.new }.to raise_error SystemExit
35
- end
36
- end
37
-
38
- context 'when detected device name is Keyboard (Capitarized)' do
39
- before do
40
- other_device = Fusuma::Device.new(name: 'Keyboard', id: 'dummy')
41
-
42
- allow(described_class)
43
- .to receive(:find_device)
44
- .and_return(other_device)
45
- allow(Sendkey::Device).to receive(:new).and_return('dummy')
46
- end
47
-
48
- it 'does not raise error' do
49
- expect { described_class.new }.not_to raise_error
50
- end
51
- end
52
-
53
- context 'when detected device name is KEYBOARD (Upper case)' do
54
- before do
55
- other_device = Fusuma::Device.new(name: 'KEYBOARD', id: 'dummy')
56
- allow(described_class)
57
- .to receive(:find_device)
58
- .and_return(other_device)
59
- allow(Sendkey::Device).to receive(:new).and_return('dummy')
60
- end
61
-
62
- it 'does not raise error' do
63
- expect { described_class.new }.not_to raise_error
64
- end
65
- end
66
-
67
- context 'with given name pattern' do
68
- before do
69
- specified_device = Fusuma::Device.new(
70
- name: 'Awesome KEY/BOARD input device',
71
- id: 'dummy'
72
- )
73
- allow(Fusuma::Device).to receive(:all).and_return([specified_device])
74
- allow(Sendkey::Device).to receive(:new).and_return('dummy')
75
- end
76
-
77
- it 'does not raise error' do
78
- expect { described_class.new(name_pattern: 'Awesome KEY/BOARD') }.not_to raise_error
79
- end
80
- end
81
-
82
- context 'when name pattern (use default) is not given' do
83
- subject { -> { described_class.new(name_pattern: nil) } }
84
-
85
- before do
86
- allow(Sendkey::Device).to receive(:new).and_return('dummy')
87
- end
88
-
89
- context 'when exist device named keyboard(lower-case)' do
90
- before do
91
- specified_device = Fusuma::Device.new(
92
- name: 'keyboard',
93
- id: 'dummy'
94
- )
95
- allow(Fusuma::Device).to receive(:all).and_return([specified_device])
96
- end
97
-
98
- it { is_expected.not_to raise_error }
99
- end
100
-
101
- context 'when exist device named Keyboard(Capital-case)' do
102
- before do
103
- specified_device = Fusuma::Device.new(
104
- name: 'Keyboard',
105
- id: 'dummy'
106
- )
107
- allow(Fusuma::Device).to receive(:all).and_return([specified_device])
108
- end
109
-
110
- it { is_expected.not_to raise_error }
111
- end
112
-
113
- context 'when exist device named KEYBOARD(UPPER case)' do
114
- before do
115
- specified_device = Fusuma::Device.new(
116
- name: 'KEYBOARD',
117
- id: 'dummy'
118
- )
119
- allow(Fusuma::Device).to receive(:all).and_return([specified_device])
120
- end
121
-
122
- it { is_expected.not_to raise_error }
123
- end
124
-
125
- context 'when exist no device named keyboard|Keyboard|KEYBOARD' do
126
- before do
127
- specified_device = Fusuma::Device.new(
128
- name: 'KEY-BOARD',
129
- id: 'dummy'
130
- )
131
- allow(Fusuma::Device).to receive(:all).and_return([specified_device])
132
- end
133
-
134
- it { is_expected.to raise_error(SystemExit) }
135
- end
136
- end
137
- end
138
-
139
- describe '#type' do
140
- before do
141
- allow(described_class)
142
- .to receive(:find_device)
143
- .and_return(Fusuma::Device.new(name: 'dummy keyboard'))
144
-
145
- @device = instance_double(Sendkey::Device)
146
- allow(@device).to receive(:write_event).with(anything)
147
- # allow(@device).to receive(:valid?).with(param: 'KEY_A')
148
-
149
- allow(Sendkey::Device).to receive(:new).and_return(@device)
150
-
151
- @keyboard = described_class.new
152
- end
153
-
154
- it 'presses key KEY_A and release KEY_A' do
155
- expect(@keyboard).to receive(:clear_modifiers).ordered
156
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: true).ordered
157
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: false).ordered
158
- @keyboard.type(param: 'A')
159
- end
160
-
161
- context 'with modifier keys' do
162
- before do
163
- @keys = 'LEFTSHIFT+A'
164
- end
165
-
166
- it 'clear all modifier keys except parameter of sendkey' do
167
- expect(@keyboard).to receive(:clear_modifiers).with(Keyboard::MODIFIER_KEY_CODES - ['KEY_LEFTSHIFT']).ordered
168
- @keyboard.type(param: @keys)
169
- end
170
-
171
- it 'types (Shift)A' do
172
- expect(@keyboard).to receive(:clear_modifiers).ordered
173
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_LEFTSHIFT', press: true).ordered
174
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: true).ordered
175
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: false).ordered
176
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_LEFTSHIFT', press: false).ordered
177
- @keyboard.type(param: @keys)
178
- end
179
- end
180
-
181
- context 'with multiple keys' do
182
- before do
183
- @keys = 'A+B'
184
- end
185
-
186
- it 'types AB' do
187
- expect(@keyboard).to receive(:clear_modifiers).ordered
188
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: true).ordered
189
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_B', press: true).ordered
190
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_B', press: false).ordered
191
- expect(@keyboard).to receive(:key_event).with(keycode: 'KEY_A', press: false).ordered
192
- @keyboard.type(param: @keys)
193
- end
194
- end
195
- end
196
- end
197
- end
198
- end
199
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Fusuma::Plugin::Sendkey do
4
- it 'has a version number' do
5
- expect(Fusuma::Plugin::Sendkey::VERSION).not_to be nil
6
- end
7
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tempfile'
4
- require 'fusuma/config'
5
-
6
- module Fusuma
7
- module ConfigHelper
8
- module_function
9
-
10
- def load_config_yml=(string)
11
- Config.custom_path = Tempfile.open do |temp_file|
12
- temp_file.tap { |f| f.write(string) }
13
- end
14
- end
15
- end
16
- end
data/spec/spec_helper.rb DELETED
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/setup'
4
- require 'helpers/config_helper'
5
-
6
- RSpec.configure do |config|
7
- # Enable flags like --only-failures and --next-failure
8
- config.example_status_persistence_file_path = '.rspec_status'
9
-
10
- # Disable RSpec exposing methods globally on `Module` and `main`
11
- config.disable_monkey_patching!
12
-
13
- config.expect_with :rspec do |c|
14
- c.syntax = :expect
15
- end
16
-
17
- config.include(Fusuma::ConfigHelper)
18
- end