fusuma 1.11.1 → 2.0.2
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 +4 -4
- data/README.md +49 -7
- data/fusuma.gemspec +6 -16
- data/lib/fusuma.rb +91 -28
- data/lib/fusuma/config.rb +34 -62
- data/lib/fusuma/config/index.rb +39 -6
- data/lib/fusuma/config/searcher.rb +166 -0
- data/lib/fusuma/custom_process.rb +13 -0
- data/lib/fusuma/device.rb +22 -7
- data/lib/fusuma/environment.rb +6 -4
- data/lib/fusuma/hash_support.rb +40 -0
- data/lib/fusuma/libinput_command.rb +17 -21
- data/lib/fusuma/multi_logger.rb +2 -6
- data/lib/fusuma/plugin/base.rb +18 -15
- data/lib/fusuma/plugin/buffers/buffer.rb +3 -2
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +34 -25
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +46 -0
- data/lib/fusuma/plugin/detectors/detector.rb +26 -5
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +109 -58
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +91 -50
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +93 -56
- data/lib/fusuma/plugin/events/event.rb +5 -4
- data/lib/fusuma/plugin/events/records/context_record.rb +27 -0
- data/lib/fusuma/plugin/events/records/gesture_record.rb +9 -6
- data/lib/fusuma/plugin/events/records/index_record.rb +46 -14
- data/lib/fusuma/plugin/events/records/record.rb +1 -1
- data/lib/fusuma/plugin/events/records/text_record.rb +2 -1
- data/lib/fusuma/plugin/executors/command_executor.rb +21 -6
- data/lib/fusuma/plugin/executors/executor.rb +45 -3
- data/lib/fusuma/plugin/filters/filter.rb +1 -1
- data/lib/fusuma/plugin/filters/libinput_device_filter.rb +6 -7
- data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +2 -2
- data/lib/fusuma/plugin/inputs/input.rb +64 -8
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +19 -9
- data/lib/fusuma/plugin/inputs/timer_input.rb +63 -0
- data/lib/fusuma/plugin/manager.rb +22 -29
- data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +10 -8
- data/lib/fusuma/plugin/parsers/parser.rb +8 -9
- data/lib/fusuma/string_support.rb +16 -0
- data/lib/fusuma/version.rb +1 -1
- data/spec/helpers/config_helper.rb +20 -0
- data/spec/lib/config/searcher_spec.rb +97 -0
- data/spec/lib/config_spec.rb +112 -0
- data/spec/lib/custom_process_spec.rb +28 -0
- data/spec/lib/device_spec.rb +98 -0
- data/spec/lib/dummy_config.yml +31 -0
- data/spec/lib/fusuma_spec.rb +103 -0
- data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +181 -0
- data/spec/lib/libinput-list-devices_magic_trackpad.txt +51 -0
- data/spec/lib/libinput-list-devices_razer_razer_blade.txt +252 -0
- data/spec/lib/libinput-list-devices_thejinx0r.txt +361 -0
- data/spec/lib/libinput-list-devices_unavailable.txt +36 -0
- data/spec/lib/libinput_command_spec.rb +167 -0
- data/spec/lib/plugin/base_spec.rb +74 -0
- data/spec/lib/plugin/buffers/buffer_spec.rb +80 -0
- data/spec/lib/plugin/buffers/dummy_buffer.rb +20 -0
- data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +172 -0
- data/spec/lib/plugin/detectors/detector_spec.rb +43 -0
- data/spec/lib/plugin/detectors/dummy_detector.rb +24 -0
- data/spec/lib/plugin/detectors/pinch_detector_spec.rb +119 -0
- data/spec/lib/plugin/detectors/rotate_detector_spec.rb +125 -0
- data/spec/lib/plugin/detectors/swipe_detector_spec.rb +118 -0
- data/spec/lib/plugin/events/event_spec.rb +30 -0
- data/spec/lib/plugin/events/records/gesture_record_spec.rb +22 -0
- data/spec/lib/plugin/events/records/record_spec.rb +31 -0
- data/spec/lib/plugin/events/records/text_record_spec.rb +26 -0
- data/spec/lib/plugin/executors/command_executor_spec.rb +57 -0
- data/spec/lib/plugin/executors/executor_spec.rb +160 -0
- data/spec/lib/plugin/filters/filter_spec.rb +92 -0
- data/spec/lib/plugin/filters/libinput_filter_spec.rb +120 -0
- data/spec/lib/plugin/inputs/input_spec.rb +70 -0
- data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +120 -0
- data/spec/lib/plugin/inputs/timer_input_spec.rb +40 -0
- data/spec/lib/plugin/manager_spec.rb +27 -0
- data/spec/lib/plugin/parsers/parser_spec.rb +45 -0
- data/spec/spec_helper.rb +20 -0
- metadata +90 -167
- data/.github/FUNDING.yml +0 -8
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- data/.github/pull_request_template.md +0 -9
- data/.github/stale.yml +0 -18
- data/.gitignore +0 -17
- data/.reek.yml +0 -96
- data/.rspec +0 -2
- data/.rubocop.yml +0 -37
- data/.rubocop_todo.yml +0 -40
- data/.travis.yml +0 -11
- data/CHANGELOG.md +0 -456
- data/CODE_OF_CONDUCT.md +0 -74
- data/CONTRIBUTING.md +0 -72
- data/Gemfile +0 -6
- data/Rakefile +0 -15
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './input'
|
4
|
+
|
5
|
+
module Fusuma
|
6
|
+
module Plugin
|
7
|
+
module Inputs
|
8
|
+
# libinput commands wrapper
|
9
|
+
class TimerInput < Input
|
10
|
+
DEFAULT_INTERVAL = 0.3
|
11
|
+
def config_param_types
|
12
|
+
{
|
13
|
+
interval: [Float]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :pid
|
18
|
+
|
19
|
+
def io
|
20
|
+
@io ||= begin
|
21
|
+
reader, writer = create_io
|
22
|
+
@pid = start(reader, writer)
|
23
|
+
|
24
|
+
reader
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start(reader, writer)
|
29
|
+
pid = fork do
|
30
|
+
timer_loop(reader, writer)
|
31
|
+
end
|
32
|
+
Process.detach(pid)
|
33
|
+
writer.close
|
34
|
+
pid
|
35
|
+
end
|
36
|
+
|
37
|
+
def timer_loop(reader, writer)
|
38
|
+
reader.close
|
39
|
+
begin
|
40
|
+
loop do
|
41
|
+
sleep interval
|
42
|
+
writer.puts 'timer'
|
43
|
+
end
|
44
|
+
rescue Errno::EPIPE
|
45
|
+
exit 0
|
46
|
+
rescue StandardError => e
|
47
|
+
MultiLogger.error e
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def create_io
|
54
|
+
IO.pipe
|
55
|
+
end
|
56
|
+
|
57
|
+
def interval
|
58
|
+
config_params(:interval) || DEFAULT_INTERVAL
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../
|
3
|
+
require_relative '../multi_logger'
|
4
|
+
require_relative '../string_support'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -21,8 +21,19 @@ module Fusuma
|
|
21
21
|
def require_siblings_from_gems
|
22
22
|
search_key = File.join(plugin_dir_name, '*.rb')
|
23
23
|
Gem.find_latest_files(search_key).each do |siblings_plugin|
|
24
|
-
|
24
|
+
next unless siblings_plugin =~ %r{fusuma-plugin-(.+).*/lib/#{plugin_dir_name}/\1_.+.rb}
|
25
|
+
|
26
|
+
match_data = siblings_plugin.match(%r{(.*)/(.*)/lib/(.*)})
|
27
|
+
gemspec_path = Dir.glob("#{match_data[1]}/#{match_data[2]}/*.gemspec").first
|
28
|
+
raise "Not Found: #{match_data[1]}/#{match_data[2]}/*.gemspec" unless gemspec_path
|
29
|
+
|
30
|
+
gemspec = Gem::Specification.load(gemspec_path)
|
31
|
+
fusuma_gemspec_path = File.expand_path('../../../fusuma.gemspec', __dir__)
|
32
|
+
fusuma_gemspec = Gem::Specification.load(fusuma_gemspec_path)
|
33
|
+
if gemspec.dependencies.find { |d| d.name == 'fusuma' }&.match?(fusuma_gemspec)
|
25
34
|
require siblings_plugin
|
35
|
+
else
|
36
|
+
MultiLogger.warn "#{gemspec.name} #{gemspec.version} is incompatible with running #{fusuma_gemspec.name} #{fusuma_gemspec.version}"
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
@@ -58,14 +69,14 @@ module Fusuma
|
|
58
69
|
end
|
59
70
|
|
60
71
|
def require_base_plugins
|
61
|
-
require_relative './base
|
62
|
-
require_relative './events/event
|
63
|
-
require_relative './inputs/input
|
64
|
-
require_relative './filters/filter
|
65
|
-
require_relative './parsers/parser
|
66
|
-
require_relative './buffers/buffer
|
67
|
-
require_relative './detectors/detector
|
68
|
-
require_relative './executors/executor
|
72
|
+
require_relative './base'
|
73
|
+
require_relative './events/event'
|
74
|
+
require_relative './inputs/input'
|
75
|
+
require_relative './filters/filter'
|
76
|
+
require_relative './parsers/parser'
|
77
|
+
require_relative './buffers/buffer'
|
78
|
+
require_relative './detectors/detector'
|
79
|
+
require_relative './executors/executor'
|
69
80
|
end
|
70
81
|
|
71
82
|
def plugins
|
@@ -90,21 +101,3 @@ module Fusuma
|
|
90
101
|
end
|
91
102
|
end
|
92
103
|
end
|
93
|
-
|
94
|
-
# support camerize and underscore
|
95
|
-
class String
|
96
|
-
def camerize
|
97
|
-
split('_').map do |w|
|
98
|
-
w[0].upcase!
|
99
|
-
w
|
100
|
-
end.join
|
101
|
-
end
|
102
|
-
|
103
|
-
def underscore
|
104
|
-
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
105
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
106
|
-
.gsub('::', '/')
|
107
|
-
.tr('-', '_')
|
108
|
-
.downcase
|
109
|
-
end
|
110
|
-
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../events/records/record
|
4
|
-
require_relative '../events/records/gesture_record
|
3
|
+
require_relative '../events/records/record'
|
4
|
+
require_relative '../events/records/gesture_record'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -15,7 +15,7 @@ module Fusuma
|
|
15
15
|
def parse_record(record)
|
16
16
|
case line = record.to_s
|
17
17
|
when /GESTURE_SWIPE|GESTURE_PINCH/
|
18
|
-
gesture, status, finger,
|
18
|
+
gesture, status, finger, delta = parse_libinput(line)
|
19
19
|
else
|
20
20
|
return
|
21
21
|
end
|
@@ -23,7 +23,7 @@ module Fusuma
|
|
23
23
|
Events::Records::GestureRecord.new(status: status,
|
24
24
|
gesture: gesture,
|
25
25
|
finger: finger,
|
26
|
-
|
26
|
+
delta: delta)
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -32,8 +32,8 @@ module Fusuma
|
|
32
32
|
_device, event_name, _time, other = line.strip.split(nil, 4)
|
33
33
|
finger, other = other.split(nil, 2)
|
34
34
|
|
35
|
-
|
36
|
-
[*detect_gesture(event_name), finger,
|
35
|
+
delta = parse_delta(other)
|
36
|
+
[*detect_gesture(event_name), finger, delta]
|
37
37
|
end
|
38
38
|
|
39
39
|
def detect_gesture(event_name)
|
@@ -41,11 +41,13 @@ module Fusuma
|
|
41
41
|
[Regexp.last_match(1).downcase, Regexp.last_match(2).downcase]
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
44
|
+
def parse_delta(line)
|
45
45
|
return if line.nil?
|
46
46
|
|
47
|
-
move_x, move_y,
|
47
|
+
move_x, move_y, unaccelerated_x, unaccelerated_y, _, zoom, _, rotate =
|
48
|
+
line.tr('/|(|)', ' ').split
|
48
49
|
Events::Records::GestureRecord::Delta.new(move_x.to_f, move_y.to_f,
|
50
|
+
unaccelerated_x.to_f, unaccelerated_y.to_f,
|
49
51
|
zoom.to_f, rotate.to_f)
|
50
52
|
end
|
51
53
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../base
|
3
|
+
require_relative '../base'
|
4
4
|
|
5
5
|
module Fusuma
|
6
6
|
module Plugin
|
@@ -13,15 +13,14 @@ module Fusuma
|
|
13
13
|
# @param event [Event]
|
14
14
|
# @return [Event]
|
15
15
|
def parse(event)
|
16
|
-
event.
|
17
|
-
next if e.tag != source
|
16
|
+
return event if event.tag != source
|
18
17
|
|
19
|
-
|
20
|
-
|
18
|
+
new_record = parse_record(event.record)
|
19
|
+
return event if new_record.nil?
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
event.record = new_record
|
22
|
+
event.tag = tag
|
23
|
+
event
|
25
24
|
end
|
26
25
|
|
27
26
|
# Set source for tag from config.yml.
|
@@ -31,7 +30,7 @@ module Fusuma
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def tag
|
34
|
-
self.class.name.split('::').last.underscore
|
33
|
+
@tag ||= self.class.name.split('::').last.underscore
|
35
34
|
end
|
36
35
|
|
37
36
|
# parse Record object
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# support camerize and underscore
|
4
|
+
class String
|
5
|
+
def camelize
|
6
|
+
split('_').map(&:capitalize).join
|
7
|
+
end
|
8
|
+
|
9
|
+
def underscore
|
10
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
11
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
12
|
+
.gsub('::', '/')
|
13
|
+
.tr('-', '_')
|
14
|
+
.downcase
|
15
|
+
end
|
16
|
+
end
|
data/lib/fusuma/version.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
require './lib/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
|
+
|
16
|
+
def clear_config_yml
|
17
|
+
Config.custom_path = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/config'
|
5
|
+
require './lib/fusuma/config/searcher'
|
6
|
+
|
7
|
+
# spec for Config
|
8
|
+
module Fusuma
|
9
|
+
RSpec.describe Config::Searcher do
|
10
|
+
let(:keymap) do
|
11
|
+
{
|
12
|
+
'swipe' => {
|
13
|
+
3 => {
|
14
|
+
'left' => { 'command' => 'alt+Left' },
|
15
|
+
'right' => { 'command' => 'alt+Right' }
|
16
|
+
},
|
17
|
+
4 => {
|
18
|
+
'left' => { 'command' => 'super+Left' },
|
19
|
+
'right' => { 'command' => 'super+Right' }
|
20
|
+
}
|
21
|
+
},
|
22
|
+
'pinch' => {
|
23
|
+
'in' => { 'command' => 'ctrl+plus' },
|
24
|
+
'out' => { 'command' => 'ctrl+minus' }
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:keymap_without_finger) do
|
30
|
+
{
|
31
|
+
'swipe' => {
|
32
|
+
'left' => { 'command' => 'alt+Left' }
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '.custom_path=' do
|
38
|
+
before { Singleton.__init__(Config) }
|
39
|
+
it 'should reload keymap file' do
|
40
|
+
keymap = Config.instance.keymap
|
41
|
+
Config.custom_path = './spec/lib/dummy_config.yml'
|
42
|
+
custom_keymap = Config.instance.keymap
|
43
|
+
expect(keymap).not_to eq custom_keymap
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.search' do
|
48
|
+
let(:index) { nil }
|
49
|
+
subject { Config::Searcher.new.search(index, location: keymap.deep_symbolize_keys) }
|
50
|
+
context 'index correct order' do
|
51
|
+
let(:index) { Config::Index.new %w[pinch in command] }
|
52
|
+
it { is_expected.to eq 'ctrl+plus' }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'index include skippable key' do
|
56
|
+
let(:index) do
|
57
|
+
Config::Index.new [
|
58
|
+
Config::Index::Key.new('pinch'),
|
59
|
+
Config::Index::Key.new(2, skippable: true),
|
60
|
+
Config::Index::Key.new('out'),
|
61
|
+
Config::Index::Key.new('command')
|
62
|
+
]
|
63
|
+
end
|
64
|
+
it { expect(Config::Searcher.skip { subject }).to eq 'ctrl+minus' }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'index include skippable key at first' do
|
68
|
+
let(:index) do
|
69
|
+
Config::Index.new [
|
70
|
+
Config::Index::Key.new(:hoge, skippable: true),
|
71
|
+
Config::Index::Key.new(:fuga, skippable: true),
|
72
|
+
Config::Index::Key.new('pinch'),
|
73
|
+
Config::Index::Key.new('in'),
|
74
|
+
Config::Index::Key.new(:piyo, skippable: true),
|
75
|
+
Config::Index::Key.new('command')
|
76
|
+
]
|
77
|
+
end
|
78
|
+
it { expect(Config::Searcher.skip { subject }).to eq 'ctrl+plus' }
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'index incorrect order' do
|
82
|
+
let(:index) { Config::Index.new %w[in pinch 2 command] }
|
83
|
+
it { is_expected.not_to eq 'ctrl+plus' }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'private_method: :cache' do
|
88
|
+
it 'should cache command' do
|
89
|
+
key = %w[event_type finger direction command].join(',')
|
90
|
+
value = 'shourtcut string'
|
91
|
+
searcher = Config::Searcher.new
|
92
|
+
searcher.send(:cache, key) { value }
|
93
|
+
expect(searcher.send(:cache, key)).to eq value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require './lib/fusuma/config'
|
5
|
+
|
6
|
+
# spec for Config
|
7
|
+
module Fusuma
|
8
|
+
RSpec.describe Config do
|
9
|
+
let(:keymap) do
|
10
|
+
{
|
11
|
+
'swipe' => {
|
12
|
+
3 => {
|
13
|
+
'left' => { 'command' => 'alt+Left' },
|
14
|
+
'right' => { 'command' => 'alt+Right' }
|
15
|
+
},
|
16
|
+
4 => {
|
17
|
+
'left' => { 'command' => 'super+Left' },
|
18
|
+
'right' => { 'command' => 'super+Right' }
|
19
|
+
}
|
20
|
+
},
|
21
|
+
'pinch' => {
|
22
|
+
'in' => { 'command' => 'ctrl+plus' },
|
23
|
+
'out' => { 'command' => 'ctrl+minus' }
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:keymap_without_finger) do
|
29
|
+
{
|
30
|
+
'swipe' => {
|
31
|
+
'left' => { 'command' => 'alt+Left' }
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '.custom_path=' do
|
37
|
+
before { Singleton.__init__(Config) }
|
38
|
+
it 'should reload keymap file' do
|
39
|
+
keymap = Config.instance.keymap
|
40
|
+
Config.custom_path = './spec/lib/dummy_config.yml'
|
41
|
+
custom_keymap = Config.instance.keymap
|
42
|
+
expect(keymap).not_to eq custom_keymap
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#reload' do
|
47
|
+
before { Singleton.__init__(Config) }
|
48
|
+
it 'set Seacher' do
|
49
|
+
old = Config.instance.searcher
|
50
|
+
Config.instance.reload
|
51
|
+
expect(Config.instance.searcher).not_to eq(old)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#validate' do
|
56
|
+
context 'with valid yaml' do
|
57
|
+
before do
|
58
|
+
string = <<~CONFIG
|
59
|
+
swipe:
|
60
|
+
3:
|
61
|
+
left:
|
62
|
+
command: echo 'swipe left'
|
63
|
+
|
64
|
+
CONFIG
|
65
|
+
@file_path = Tempfile.open do |temp_file|
|
66
|
+
temp_file.tap { |f| f.write(string) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should return Hash' do
|
71
|
+
Config.instance.validate(@file_path)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with invalid yaml' do
|
76
|
+
before do
|
77
|
+
string = <<~CONFIG
|
78
|
+
this is not yaml
|
79
|
+
CONFIG
|
80
|
+
@file_path = Tempfile.open do |temp_file|
|
81
|
+
temp_file.tap { |f| f.write(string) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'raise InvalidFileError' do
|
86
|
+
expect { Config.instance.validate(@file_path) }.to raise_error(Config::InvalidFileError)
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with duplicated key' do
|
90
|
+
before do
|
91
|
+
string = <<~CONFIG
|
92
|
+
pinch:
|
93
|
+
2:
|
94
|
+
in:
|
95
|
+
command: "xdotool keydown ctrl click 4 keyup ctrl" # threshold: 0.5, interval: 0.5
|
96
|
+
2:
|
97
|
+
out:
|
98
|
+
command: "xdotool keydown ctrl click 5 keyup ctrl" # threshold: 0.5, interval: 0.5
|
99
|
+
CONFIG
|
100
|
+
@file_path = Tempfile.open do |temp_file|
|
101
|
+
temp_file.tap { |f| f.write(string) }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'raise InvalidFileError' do
|
106
|
+
expect { Config.instance.validate(@file_path) }.to raise_error(Config::InvalidFileError)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|