diff --git a/features/layout/registration.feature b/features/layout/registration.feature new file mode 100644 index 0000000..5a71c60 --- /dev/null +++ b/features/layout/registration.feature @@ -0,0 +1,13 @@ +Feature: layout registration + + Scenario: sends the #register message to the layout with the display + Given a file named layout.rb with: + """ + class Layout + def register display + puts display + end + end + """ + When I run uhwm with option -r./layout -l Layout + Then the current output must contain current display diff --git a/features/steps/filesystem_steps.rb b/features/steps/filesystem_steps.rb new file mode 100644 index 0000000..a951c6f --- /dev/null +++ b/features/steps/filesystem_steps.rb @@ -0,0 +1,3 @@ +Given /^a file named ([^ ]+) with:$/ do |path, content| + write_file path, content +end diff --git a/features/steps/output_steps.rb b/features/steps/output_steps.rb index 330452a..46fc2d0 100644 --- a/features/steps/output_steps.rb +++ b/features/steps/output_steps.rb @@ -24,9 +24,18 @@ options: -v, --version enable verbose mode -d, --debug enable debug mode -r, --require PATH require ruby feature + -l, --layout LAYOUT specify layout eoh end Then /^the current output must match \/([^\/]+)\/([a-z]*)$/ do |pattern, options| uhwm_wait_output Regexp.new(pattern, options) end + +Then /^the current output must contain:$/ do |content| + uhwm_wait_output content.to_s +end + +Then /^the current output must contain current display$/ do + uhwm_wait_output ENV['DISPLAY'] +end diff --git a/lib/uh/wm/cli.rb b/lib/uh/wm/cli.rb index cc61bce..c52f073 100644 --- a/lib/uh/wm/cli.rb +++ b/lib/uh/wm/cli.rb @@ -63,6 +63,10 @@ module Uh require feature @env.log "Loaded `#{feature}' ruby feature" end + + opts.on '-l', '--layout LAYOUT', 'specify layout' do |layout| + @env.layout_class = self.class.const_get layout.to_sym + end end end end diff --git a/lib/uh/wm/env.rb b/lib/uh/wm/env.rb index 8c18592..029ab97 100644 --- a/lib/uh/wm/env.rb +++ b/lib/uh/wm/env.rb @@ -12,7 +12,7 @@ module Uh def_delegator :@output, :print attr_reader :output - attr_accessor :verbose, :debug + attr_accessor :verbose, :debug, :layout_class def initialize output @output = output @@ -26,6 +26,15 @@ module Uh !!@debug end + def layout + @layout ||= if layout_class + layout_class.new + else + require 'uh/layout' + ::Uh::Layout.new + end + end + def logger @logger ||= Logger.new(@output).tap do |o| o.level = debug? ? LOGGER_LEVEL_DEBUG : diff --git a/lib/uh/wm/runner.rb b/lib/uh/wm/runner.rb index cf16f54..24c0675 100644 --- a/lib/uh/wm/runner.rb +++ b/lib/uh/wm/runner.rb @@ -10,6 +10,9 @@ module Uh end end + extend Forwardable + def_delegator :@env, :layout + attr_reader :env, :events, :manager def initialize env, manager: nil, stopped: false @@ -29,6 +32,7 @@ module Uh def register_event_hooks register_manager_hooks + register_layout_event_hooks register_key_bindings_hooks end @@ -53,6 +57,12 @@ module Uh end end + def register_layout_event_hooks + @events.on(:connected) do |display| + layout.register display + end + end + def register_key_bindings_hooks @events.on(:key, :q) { stop! } end diff --git a/spec/uh/wm/cli_spec.rb b/spec/uh/wm/cli_spec.rb index 86b4d2e..24cb07c 100644 --- a/spec/uh/wm/cli_spec.rb +++ b/spec/uh/wm/cli_spec.rb @@ -130,6 +130,15 @@ module Uh end end + context 'with layout option' do + let(:arguments) { %w[-l Object] } + + it 'assigns the layout class in the env' do + cli.parse_arguments! + expect(cli.env.layout_class).to eq Object + end + end + context 'with invalid option' do let(:arguments) { %w[--unknown-option] } diff --git a/spec/uh/wm/env_spec.rb b/spec/uh/wm/env_spec.rb index ea41de3..77cf3f3 100644 --- a/spec/uh/wm/env_spec.rb +++ b/spec/uh/wm/env_spec.rb @@ -13,6 +13,10 @@ module Uh expect(env).not_to be_debug end + it 'has no layout_class set' do + expect(env.layout_class).not_to be + end + describe '#verbose?' do context 'when verbose mode is disabled' do before { env.verbose = false } @@ -49,6 +53,24 @@ module Uh end end + describe '#layout' do + context 'when a layout class is set' do + let(:some_layout) { Class.new } + + before { env.layout_class = some_layout } + + it 'returns a new instance of this layout class' do + expect(env.layout).to be_an_instance_of some_layout + end + end + + context 'when a layout class is not set' do + it 'returns an instance of the default layout' do + expect(env.layout).to be_an_instance_of ::Uh::Layout + end + end + end + describe '#logger' do it 'returns a logger' do expect(env.logger).to be_a Logger diff --git a/spec/uh/wm/runner_spec.rb b/spec/uh/wm/runner_spec.rb index 8a9a500..c56d94b 100644 --- a/spec/uh/wm/runner_spec.rb +++ b/spec/uh/wm/runner_spec.rb @@ -1,8 +1,14 @@ +SomeLayout = Class.new do + define_method(:register) { |*args| } +end + module Uh module WM RSpec.describe Runner do - let(:env) { Env.new(StringIO.new) } - subject(:runner) { described_class.new env } + let(:env) do + Env.new(StringIO.new).tap { |o| o.layout_class = SomeLayout } + end + subject(:runner) { described_class.new env } describe '.run' do subject(:run) { described_class.run env, stopped: true } @@ -82,6 +88,12 @@ module Uh runner.events.emit :connected end + it 'registers layout hook for :connected event' do + runner.register_event_hooks + expect(env.layout).to receive(:register).with :display + runner.events.emit :connected, args: :display + end + it 'registers key bindings event hooks' do runner.register_event_hooks expect(runner.events[:key, :q]).not_to be_empty diff --git a/uh-wm.gemspec b/uh-wm.gemspec index 48a48ad..ed98051 100644 --- a/uh-wm.gemspec +++ b/uh-wm.gemspec @@ -14,7 +14,8 @@ Gem::Specification.new do |s| s.test_files = s.files.grep /\A(spec|features)\// s.executables = s.files.grep(/\Abin\//) { |f| File.basename(f) } - s.add_dependency 'uh', '2.0.0.pre' + s.add_dependency 'uh', '2.0.0.pre' + s.add_dependency 'uh-layout', '0.2.0.pre' s.add_development_dependency 'aruba', '~> 0.6' s.add_development_dependency 'cucumber', '~> 2.0'