rmonitor 1.0.1 → 2.0.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +49 -40
  4. data/bin/rmonitor +38 -100
  5. data/lib/rmonitor.rb +17 -20
  6. data/lib/rmonitor/actions.rb +30 -0
  7. data/lib/rmonitor/actions/builder.rb +15 -0
  8. data/lib/rmonitor/actions/dsl.rb +23 -0
  9. data/lib/rmonitor/cache.rb +12 -0
  10. data/lib/rmonitor/capabilities.rb +38 -0
  11. data/lib/rmonitor/capabilities/builder.rb +15 -0
  12. data/lib/rmonitor/capabilities/dsl.rb +15 -0
  13. data/lib/rmonitor/commands/cl/base.rb +13 -0
  14. data/lib/rmonitor/commands/cl/invoke.rb +22 -0
  15. data/lib/rmonitor/commands/cl/list.rb +43 -0
  16. data/lib/rmonitor/commands/cl/update.rb +20 -0
  17. data/lib/rmonitor/commands/invoke.rb +23 -0
  18. data/lib/rmonitor/commands/list.rb +13 -0
  19. data/lib/rmonitor/commands/update.rb +18 -0
  20. data/lib/rmonitor/config.rb +27 -0
  21. data/lib/rmonitor/config/builder.rb +21 -0
  22. data/lib/rmonitor/config/dsl.rb +25 -0
  23. data/lib/rmonitor/invoker.rb +9 -0
  24. data/lib/rmonitor/matcher.rb +32 -0
  25. data/lib/rmonitor/profile/builder.rb +15 -0
  26. data/lib/rmonitor/profile/dsl.rb +15 -0
  27. data/lib/rmonitor/selector.rb +14 -0
  28. data/lib/rmonitor/strategies/base.rb +10 -0
  29. data/lib/rmonitor/strategies/optimistic.rb +15 -0
  30. data/lib/rmonitor/strategies/pessimistic.rb +17 -0
  31. data/lib/rmonitor/transformer.rb +38 -0
  32. data/lib/rmonitor/version.rb +1 -1
  33. data/lib/rmonitor/xrandr.rb +16 -0
  34. data/test/actions/builder_test.rb +27 -0
  35. data/test/actions_test.rb +60 -0
  36. data/test/cache_test.rb +30 -0
  37. data/test/capabilities/builder_test.rb +23 -0
  38. data/test/capabilities_test.rb +114 -0
  39. data/test/commands/cl/invoke_test.rb +38 -0
  40. data/test/commands/cl/list_test.rb +36 -0
  41. data/test/commands/cl/update_test.rb +24 -0
  42. data/test/commands/invoke_test.rb +86 -0
  43. data/test/commands/list_test.rb +50 -0
  44. data/test/commands/update_test.rb +67 -0
  45. data/test/config/builder_test.rb +51 -0
  46. data/test/config_test.rb +68 -0
  47. data/test/matcher_test.rb +90 -0
  48. data/test/profile/builder_test.rb +26 -0
  49. data/test/selector_test.rb +30 -0
  50. data/test/strategies/optimistic_test.rb +24 -0
  51. data/test/strategies/pessimistic_test.rb +26 -0
  52. data/test/test_helper.rb +19 -0
  53. data/test/transformer_test.rb +159 -0
  54. data/test/xrandr_test.rb +76 -0
  55. metadata +178 -28
  56. data/.rspec +0 -1
  57. data/Gemfile +0 -3
  58. data/Gemfile.lock +0 -24
  59. data/lib/rmonitor/devices.rb +0 -29
  60. data/lib/rmonitor/helpers/dsl_helpers.rb +0 -38
  61. data/lib/rmonitor/helpers/profile_helpers.rb +0 -48
  62. data/lib/rmonitor/helpers/xrandr_read_helpers.rb +0 -75
  63. data/lib/rmonitor/helpers/xrandr_write_helpers.rb +0 -55
  64. data/lib/rmonitor/profiles.rb +0 -51
  65. data/rmonitor.gemspec +0 -44
  66. data/spec/lib/helpers/dsl_helper_spec.rb +0 -29
  67. data/spec/lib/helpers/profile_helpers_spec.rb +0 -138
  68. data/spec/lib/helpers/xrandr_read_helpers_spec.rb +0 -259
  69. data/spec/lib/helpers/xrandr_write_helpers_spec.rb +0 -158
  70. data/spec/support/device_helper.rb +0 -3
  71. data/spec/support/profile_helper.rb +0 -3
  72. data/spec/support/string_helpers.rb +0 -25
@@ -0,0 +1,50 @@
1
+ require "test_helper"
2
+ require "fakefs/safe"
3
+
4
+ describe RMonitor::Commands::List do
5
+
6
+ before :each do
7
+ FakeFS.activate!
8
+
9
+ RMonitor::Config.config_path = nil
10
+
11
+ FileUtils.mkdir_p File.dirname DEFAULT_CONFIG_PATH
12
+
13
+ File.write DEFAULT_CONFIG_PATH, <<-CONFIG
14
+ profile "docked" do
15
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
16
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
17
+ end
18
+
19
+ profile "default" do
20
+ device "eDP1", :mode => "1920x1080"
21
+ end
22
+ CONFIG
23
+ end
24
+
25
+ after :each do
26
+ FakeFS.deactivate!
27
+ end
28
+
29
+ describe "#execute" do
30
+
31
+ it "should return a list of all profiles" do
32
+ expected = RMonitor::Config::Builder.define do
33
+ profile "docked" do
34
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
35
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
36
+ end
37
+
38
+ profile "default" do
39
+ device "eDP1", :mode => "1920x1080"
40
+ end
41
+ end
42
+
43
+ actual = RMonitor::Commands::List.new.execute
44
+
45
+ assert_equal expected, actual
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,67 @@
1
+ require "test_helper"
2
+ require "fakefs/safe"
3
+
4
+ describe RMonitor::Commands::Update do
5
+
6
+ before :each do
7
+ FakeFS.activate!
8
+
9
+ RMonitor::Config.config_path = nil
10
+
11
+ FileUtils.mkdir_p File.dirname DEFAULT_CONFIG_PATH
12
+
13
+ File.write DEFAULT_CONFIG_PATH, <<-CONFIG
14
+ profile "docked" do
15
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
16
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
17
+ end
18
+
19
+ profile "default" do
20
+ device "eDP1", :mode => "1920x1080"
21
+ end
22
+ CONFIG
23
+ end
24
+
25
+ after :each do
26
+ FakeFS.deactivate!
27
+ end
28
+
29
+ describe "#execute" do
30
+
31
+ it "should throw an exception when no profiles are invokable" do
32
+ invoker = MiniTest::Mock.new
33
+
34
+ invoker.expect :invoke, <<-XRANDR, ["xrandr"]
35
+ Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 1920 x 1080
36
+ LVDS1 connected (normal left inverted right x axis y axis)
37
+ 1920x1080 60.0
38
+ XRANDR
39
+
40
+ cache = RMonitor::Cache.new(:invoker => invoker)
41
+
42
+ assert_raises RMonitor::NoInvokableProfileError do
43
+ RMonitor::Commands::Update.new(:invoker => cache).execute
44
+ end
45
+ end
46
+
47
+ it "should invoke the first invokable profile when one exist" do
48
+ invoker = MiniTest::Mock.new
49
+
50
+ invoker.expect :invoke, <<-XRANDR, ["xrandr"]
51
+ Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 1920 x 1080
52
+ eDP1 connected (normal left inverted right x axis y axis)
53
+ 1920x1080 60.0
54
+ XRANDR
55
+
56
+ invoker.expect :invoke, nil, ["xrandr --output eDP1 --mode 1920x1080"]
57
+
58
+ cache = RMonitor::Cache.new(:invoker => invoker)
59
+
60
+ RMonitor::Commands::Update.new(:invoker => cache).execute
61
+
62
+ invoker.verify
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,51 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Config::Builder do
4
+
5
+ describe "::define" do
6
+
7
+ it "should return an array of profiles and their desired capabilities" do
8
+ actual = RMonitor::Config::Builder.define do
9
+ profile "docked" do
10
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
11
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
12
+ end
13
+
14
+ profile "default" do
15
+ device "eDP1", :mode => "1920x1080"
16
+ end
17
+ end
18
+
19
+ expected = [{
20
+ :name => "docked",
21
+ :devices => [
22
+ {:name => "HDMI1", :mode => "1920x1080", :rate => "60.0"},
23
+ {:name => "HDMI2", :mode => "1920x1080", :rate => "60.0"}
24
+ ]
25
+ }, {
26
+ :name => "default",
27
+ :devices => [
28
+ {:name => "eDP1", :mode => "1920x1080"}
29
+ ]
30
+ }]
31
+
32
+ assert_equal expected, actual
33
+ end
34
+
35
+ it "should attach methods to the :only_if :not_if options" do
36
+ profiles = RMonitor::Config::Builder.define do
37
+ def foo; end
38
+ def bar; end
39
+
40
+ profile "default", :only_if => :foo, :not_if => :bar do
41
+ device "eDP1", :mode => "1920x1080"
42
+ end
43
+ end
44
+
45
+ assert_kind_of Method, profiles.first[:only_if]
46
+ assert_kind_of Method, profiles.first[:not_if]
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,68 @@
1
+ require "test_helper"
2
+ require "fakefs/safe"
3
+ require "fileutils"
4
+
5
+ describe RMonitor::Config do
6
+
7
+ before :each do
8
+ FakeFS.activate!
9
+
10
+ RMonitor::Config.config_path = nil
11
+ end
12
+
13
+ after :each do
14
+ FakeFS.deactivate!
15
+ end
16
+
17
+ describe "#read" do
18
+
19
+ it "should by default return the content of #{DEFAULT_CONFIG_PATH}" do
20
+ FileUtils.mkdir_p File.dirname DEFAULT_CONFIG_PATH
21
+ File.write DEFAULT_CONFIG_PATH, "foo"
22
+
23
+ assert_equal "foo", RMonitor::Config.new.read
24
+ end
25
+
26
+ it "should supported reading from arbritary locations as well" do
27
+ RMonitor::Config.config_path = "/config.rb"
28
+ File.write "/config.rb", "foo"
29
+
30
+ assert_equal "foo", RMonitor::Config.new.read
31
+ end
32
+
33
+ end
34
+
35
+ describe "#profiles" do
36
+
37
+ it "should build and return the profiles contained in the config" do
38
+ FileUtils.mkdir_p File.dirname DEFAULT_CONFIG_PATH
39
+ File.write DEFAULT_CONFIG_PATH, <<-CONFIG
40
+ profile "docked" do
41
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
42
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
43
+ end
44
+
45
+ profile "default" do
46
+ device "eDP1", :mode => "1920x1080"
47
+ end
48
+ CONFIG
49
+
50
+ expected = RMonitor::Config::Builder.define do
51
+ profile "docked" do
52
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
53
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
54
+ end
55
+
56
+ profile "default" do
57
+ device "eDP1", :mode => "1920x1080"
58
+ end
59
+ end
60
+
61
+ actual = RMonitor::Config.new.profiles
62
+
63
+ assert_equal expected, actual
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,90 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Matcher do
4
+
5
+ describe "#invokable?" do
6
+
7
+ it "should return false when the device name is lacking" do
8
+ profile = RMonitor::Profile::Builder.define "foo" do
9
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
10
+ end
11
+
12
+ capabilities = RMonitor::Capabilities::Builder.define do
13
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
14
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
15
+ end
16
+
17
+ assert_equal false, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
18
+ end
19
+
20
+ it "should return false when the desired mode is missing" do
21
+ profile = RMonitor::Profile::Builder.define "foo" do
22
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
23
+ end
24
+
25
+ capabilities = RMonitor::Capabilities::Builder.define do
26
+ device "LVDS1", :mode => "820x640", :rate => "60.0"
27
+ end
28
+
29
+ assert_equal false, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
30
+ end
31
+
32
+ it "should return false when the desired rate is missing" do
33
+ profile = RMonitor::Profile::Builder.define "foo" do
34
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
35
+ end
36
+
37
+ capabilities = RMonitor::Capabilities::Builder.define do
38
+ device "LVDS1", :mode => "1920x1080", :rate => "30.0"
39
+ end
40
+
41
+ assert_equal false, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
42
+ end
43
+
44
+ it "should return false if :only_if returns false" do
45
+ def foo
46
+ false
47
+ end
48
+
49
+ profile = RMonitor::Profile::Builder.define "foo", :only_if => method(:foo) do
50
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
51
+ end
52
+
53
+ capabilities = RMonitor::Capabilities::Builder.define do
54
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
55
+ end
56
+
57
+ assert_equal false, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
58
+ end
59
+
60
+ it "should return false if :not_if returns true" do
61
+ def foo
62
+ true
63
+ end
64
+
65
+ profile = RMonitor::Profile::Builder.define "foo", :not_if => method(:foo) do
66
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
67
+ end
68
+
69
+ capabilities = RMonitor::Capabilities::Builder.define do
70
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
71
+ end
72
+
73
+ assert_equal false, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
74
+ end
75
+
76
+ it "should otherwise return true" do
77
+ profile = RMonitor::Profile::Builder.define "foo" do
78
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
79
+ end
80
+
81
+ capabilities = RMonitor::Capabilities::Builder.define do
82
+ device "LVDS1", :mode => "1920x1080", :rate => "60.0"
83
+ end
84
+
85
+ assert_equal true, RMonitor::Matcher.new(:capabilities => capabilities).invokable?(profile)
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,26 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Profile::Builder do
4
+
5
+ describe "::define" do
6
+
7
+ it "should return a profiles and its desired capabilities" do
8
+ actual = RMonitor::Profile::Builder.define "docked" do
9
+ device "HDMI1", :mode => "1920x1080", :rate => "60.0"
10
+ device "HDMI2", :mode => "1920x1080", :rate => "60.0"
11
+ end
12
+
13
+ expected = {
14
+ :name => "docked",
15
+ :devices => [
16
+ {:name => "HDMI1", :mode => "1920x1080", :rate => "60.0"},
17
+ {:name => "HDMI2", :mode => "1920x1080", :rate => "60.0"}
18
+ ]
19
+ }
20
+
21
+ assert_equal expected, actual
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,30 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Selector do
4
+
5
+ describe "#first_invokable" do
6
+
7
+ it "should return the first invokable profile" do
8
+ profiles = [ # A bunch of dummy objects, representing profiles
9
+ Object.new,
10
+ Object.new,
11
+ Object.new
12
+ ]
13
+
14
+ matcher = MiniTest::Mock.new
15
+
16
+ matcher.expect :invokable?, false, [profiles[0]]
17
+ matcher.expect :invokable?, true, [profiles[1]]
18
+ matcher.expect :invokable?, false, [profiles[2]]
19
+
20
+ selector = RMonitor::Selector.new(
21
+ :profiles => profiles,
22
+ :matcher => matcher
23
+ )
24
+
25
+ assert_equal profiles[1], selector.first_invokable
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,24 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Strategies::Optimistic do
4
+
5
+ describe "#execute" do
6
+
7
+ it "should invoke actions as a single system call" do
8
+ invoker = MiniTest::Mock.new
9
+ invoker.expect :invoke, nil, ["xrandr --output LVDS1 --off --output HDMI1 --output HDMI2"]
10
+
11
+ actions = RMonitor::Actions::Builder.define do
12
+ off "LVDS1"
13
+ on "HDMI1"
14
+ on "HDMI2"
15
+ end
16
+
17
+ RMonitor::Strategies::Optimistic.new(:invoker => invoker).execute(actions)
18
+
19
+ invoker.verify
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,26 @@
1
+ require "test_helper"
2
+
3
+ describe RMonitor::Strategies::Optimistic do
4
+
5
+ describe "#execute" do
6
+
7
+ it "should invoke actions as multiple system call" do
8
+ invoker = MiniTest::Mock.new
9
+ invoker.expect :invoke, nil, ["xrandr --output LVDS1 --off"]
10
+ invoker.expect :invoke, nil, ["xrandr --output HDMI1"]
11
+ invoker.expect :invoke, nil, ["xrandr --output HDMI2"]
12
+
13
+ actions = RMonitor::Actions::Builder.define do
14
+ off "LVDS1"
15
+ on "HDMI1"
16
+ on "HDMI2"
17
+ end
18
+
19
+ RMonitor::Strategies::Pessimistic.new(:invoker => invoker).execute(actions)
20
+
21
+ invoker.verify
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,19 @@
1
+ require "codeclimate-test-reporter"
2
+
3
+ CodeClimate::TestReporter.start
4
+
5
+ require "rmonitor"
6
+ require "minitest/autorun"
7
+ require "minitest/reporters"
8
+
9
+ DEFAULT_CONFIG_PATH = File.expand_path "~/.config/rmonitor/config.rb"
10
+
11
+ Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new
12
+
13
+ module Minitest::Assertions
14
+ def assert_subset_of(collection, subset)
15
+ subset.each do |element|
16
+ assert_includes collection, element
17
+ end
18
+ end
19
+ end