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