fusuma-plugin-sendkey 0.6.4 → 0.8.0

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