windows 0.0.1
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.
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +64 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.md +26 -0
- data/Rakefile +2 -0
- data/lib/windows.rb +9 -0
- data/lib/windows/core_ext/numeric.rb +5 -0
- data/lib/windows/engines/wmctrl.rb +68 -0
- data/lib/windows/engines/xwindow.rb +82 -0
- data/lib/windows/project.rb +31 -0
- data/lib/windows/structures.rb +7 -0
- data/lib/windows/structures/collection.rb +19 -0
- data/lib/windows/structures/desktop.rb +21 -0
- data/lib/windows/structures/geometry.rb +6 -0
- data/lib/windows/structures/window.rb +6 -0
- data/lib/windows/units/converter.rb +64 -0
- data/lib/windows/units/recognizer.rb +68 -0
- data/lib/windows/units/unit_converter.rb +73 -0
- data/lib/windows/version.rb +3 -0
- data/samples/moving_windows.rb +22 -0
- data/samples/project.rb +10 -0
- data/spec/core_ext/numeric.rb +14 -0
- data/spec/engines/wmctrl_spec.rb +110 -0
- data/spec/engines/xwindow_spec.rb +171 -0
- data/spec/project_spec.rb +68 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/structures/collection_spec.rb +28 -0
- data/spec/structures/desktop_spec.rb +13 -0
- data/spec/support/matchers/delegate.rb +40 -0
- data/spec/unit_converter_spec.rb +80 -0
- data/spec/window_spec.rb +9 -0
- data/windows.gemspec +27 -0
- metadata +219 -0
| @@ -0,0 +1,68 @@ | |
| 1 | 
            +
            module Windows
         | 
| 2 | 
            +
              module Units
         | 
| 3 | 
            +
                module Recognizer
         | 
| 4 | 
            +
                  module Formats
         | 
| 5 | 
            +
                    class Base < Struct.new(:el)
         | 
| 6 | 
            +
                      attr_accessor :unit
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                      def match
         | 
| 9 | 
            +
                        raise "you should implement your match"
         | 
| 10 | 
            +
                      end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      def format
         | 
| 13 | 
            +
                        self.class.to_s.split("::").last.downcase.to_sym
         | 
| 14 | 
            +
                      end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      def return_match(matcher, data,&block)
         | 
| 17 | 
            +
                        data = if data
         | 
| 18 | 
            +
                          matcher.instance_eval &block
         | 
| 19 | 
            +
                          matcher
         | 
| 20 | 
            +
                        else
         | 
| 21 | 
            +
                          nil
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    class Pixel < Base
         | 
| 27 | 
            +
                      # match 50, 50.5, 50.02
         | 
| 28 | 
            +
                      def match
         | 
| 29 | 
            +
                        data = el.kind_of?(Numeric)
         | 
| 30 | 
            +
                        item = return_match(self, data) { @unit = el }
         | 
| 31 | 
            +
                      end
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    class Percent < Base
         | 
| 35 | 
            +
                      # match 50px, 50PX, 50.5px, 50.1PX
         | 
| 36 | 
            +
                      def match
         | 
| 37 | 
            +
                        return false unless el.respond_to?(:match)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        data  = el.match(/(^[\d.]+)(%)/i)
         | 
| 40 | 
            +
                        return_match(self, data) { @unit = Float(data[1]) }
         | 
| 41 | 
            +
                      end
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    RECOGNIZERS = [Pixel, Percent]
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  class Finder < Struct.new(:el)
         | 
| 48 | 
            +
                    include Formats
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    def run
         | 
| 51 | 
            +
                      item = RECOGNIZERS.map do |klass|
         | 
| 52 | 
            +
                        recognizer = klass.new(el)
         | 
| 53 | 
            +
                        recognizer.match
         | 
| 54 | 
            +
                      end.compact.first
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      raise "I don't know how to recognize this unit #{el}" unless item
         | 
| 57 | 
            +
                      item
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  def recognize_unit(el)
         | 
| 62 | 
            +
                    @recognize_unit_engine ||= Finder.new
         | 
| 63 | 
            +
                    @recognize_unit_engine.el = el
         | 
| 64 | 
            +
                    @recognize_unit_engine.run
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
            end
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            require 'windows/units/converter'
         | 
| 2 | 
            +
            require 'windows/units/recognizer'
         | 
| 3 | 
            +
            require 'windows/structures'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Windows
         | 
| 6 | 
            +
              module Units
         | 
| 7 | 
            +
                class UnitConverter
         | 
| 8 | 
            +
                  include Units::Converter
         | 
| 9 | 
            +
                  include Units::Recognizer
         | 
| 10 | 
            +
                  include Structures
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  NAMED_GEOMETRY = {
         | 
| 13 | 
            +
                    left:         [0,  0,  '50%',  '100%'],
         | 
| 14 | 
            +
                    right:        ['50%', 0,  '50%',  '100%'],
         | 
| 15 | 
            +
                    bottom:       [0,  '50%', '100%', '50%'],
         | 
| 16 | 
            +
                    top:          [0,  0,  '100%', '50%'], 
         | 
| 17 | 
            +
                    max:          [0,  0,  '100%', '100%'],
         | 
| 18 | 
            +
                    bottom_right: ['50%', '50%', '50%', '50%'],
         | 
| 19 | 
            +
                    bottom_left:  [0, '50%', '50%', '50%'],
         | 
| 20 | 
            +
                    top_right:    ['50%', 0, '50%', '50%'],
         | 
| 21 | 
            +
                    top_left:     [0, 0, '50%', '50%']
         | 
| 22 | 
            +
                  }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def initialize(desktop, *args)
         | 
| 25 | 
            +
                    @width    = desktop.width
         | 
| 26 | 
            +
                    @height   = desktop.height
         | 
| 27 | 
            +
                    @geometry = create_geometry(args)
         | 
| 28 | 
            +
                    @x_offset = desktop.x_offset
         | 
| 29 | 
            +
                    @y_offset = desktop.y_offset
         | 
| 30 | 
            +
                    @x_axis   = [@geometry.x, @geometry.w]
         | 
| 31 | 
            +
                    @y_axis   = [@geometry.y, @geometry.h]
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def convert
         | 
| 35 | 
            +
                    x, w = @x_axis.map do |el|
         | 
| 36 | 
            +
                      item = recognize_unit(el)
         | 
| 37 | 
            +
                      converter(item.unit).to(item.format, base: @width)
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    y, h = @y_axis.map do |el|
         | 
| 41 | 
            +
                      item = recognize_unit(el)
         | 
| 42 | 
            +
                      converter(item.unit).to(item.format, base: @height)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    x = x + @x_offset
         | 
| 46 | 
            +
                    y = y + @y_offset
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    [x, y, w, h]
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  private
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def create_geometry(args)
         | 
| 54 | 
            +
                    return Geometry.new(*args) if args.count > 1
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    if args[0].respond_to?(:to_sym) && geometry_exist?(args[0])
         | 
| 57 | 
            +
                      args = find_geometry(args[0].to_sym)
         | 
| 58 | 
            +
                      return Geometry.new(*args)
         | 
| 59 | 
            +
                    else
         | 
| 60 | 
            +
                      raise "Geometry with name #{args[0]} not exist. You can use #{NAMED_GEOMETRY.keys}"
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def find_geometry(name)
         | 
| 65 | 
            +
                    NAMED_GEOMETRY[name.to_sym]
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  def geometry_exist?(name)
         | 
| 69 | 
            +
                    NAMED_GEOMETRY.keys.include?(name.to_sym)
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__),'../lib'))
         | 
| 2 | 
            +
            require 'windows'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            terminal1 = Windows::Window.new('x-www-browser')
         | 
| 5 | 
            +
            terminal2 = Windows::Window.new('x-www-browser')
         | 
| 6 | 
            +
            terminal3 = Windows::Window.new('x-www-browser')
         | 
| 7 | 
            +
            windows   = [terminal1, terminal2, terminal3]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # first create all windows
         | 
| 10 | 
            +
            windows.each(&:create)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # move with percentage values
         | 
| 13 | 
            +
            terminal1.move '50%', '50%', '50%', '50%'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # move with special named argument
         | 
| 16 | 
            +
            terminal2.move :top_right
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # move with pixels
         | 
| 19 | 
            +
            terminal3.move 0, 0, 300, 300
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            sleep 5
         | 
| 22 | 
            +
            windows.each(&:close)
         | 
    
        data/samples/project.rb
    ADDED
    
    | @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            $LOAD_PATH.unshift lib = File.expand_path(File.join(File.dirname(__FILE__),'../lib'))
         | 
| 2 | 
            +
            require 'windows'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            p = Windows::Project.new(:default,lib)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            p.open_window('x-www-browser').move(:right)
         | 
| 7 | 
            +
            p.open_window('x-terminal-emulator').move(:bottom)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            sleep 5
         | 
| 10 | 
            +
            p.close
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'windows/core_ext/numeric'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Numeric do
         | 
| 5 | 
            +
              context "#percent" do
         | 
| 6 | 
            +
                it 'return correct value' do
         | 
| 7 | 
            +
                  1000.percent(10).should == 100
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                it 'floor result' do
         | 
| 11 | 
            +
                  999.percent(31.53).should == 314
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,110 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'windows/engines/wmctrl'
         | 
| 3 | 
            +
            require 'time'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe WMCtrl do
         | 
| 6 | 
            +
              let(:fake_window_id) { 1234 }
         | 
| 7 | 
            +
              let(:window)         { Windows::Structures::Window.new(fake_window_id) }
         | 
| 8 | 
            +
              let(:time)           { Time.parse("Sep 13 2011") }
         | 
| 9 | 
            +
              let(:command)        { 'any_command' }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              before :each do
         | 
| 12 | 
            +
                create_windows
         | 
| 13 | 
            +
                create_desktops
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              context "spawn_window" do
         | 
| 17 | 
            +
                it 'should raise exception when command not exist' do
         | 
| 18 | 
            +
                  Process.stub(:spawn).and_raise(Errno::ENOENT)
         | 
| 19 | 
            +
                  expect { subject.spawn_window(command) }.to raise_error "Failed to create window with command: #{command}. Maybe a typo?"
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it "#desktops" do
         | 
| 24 | 
            +
                list = subject.desktops
         | 
| 25 | 
            +
                desktops.zip(list).each do |desktop, desktop_window|
         | 
| 26 | 
            +
                  desktop[:id].should       == desktop_window.id   
         | 
| 27 | 
            +
                  desktop[:workarea].should == desktop_window.geometry         
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                list.should be_instance_of(Windows::Structures::Collection)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              it "#find_desktops" do
         | 
| 34 | 
            +
                desktop = subject.find_desktop(1)
         | 
| 35 | 
            +
                desktop.id.should == 1
         | 
| 36 | 
            +
                desktop.should be_instance_of(Windows::Structures::Desktop)
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              context "#windows" do
         | 
| 40 | 
            +
                it 'return windows' do
         | 
| 41 | 
            +
                  list = subject.windows
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  windows(:sorted).zip(list).each do |stub, window|
         | 
| 44 | 
            +
                    desktop = subject.find_desktop(stub[:desktop])
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    stub[:id].should          == window.id
         | 
| 47 | 
            +
                    stub[:title].should       == window.title
         | 
| 48 | 
            +
                    stub[:desktop].should     == desktop.id
         | 
| 49 | 
            +
                    stub[:geometry][0].should == window.x
         | 
| 50 | 
            +
                    stub[:geometry][1].should == window.y
         | 
| 51 | 
            +
                    stub[:geometry][2].should == window.width
         | 
| 52 | 
            +
                    stub[:geometry][3].should == window.height
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  list.should be_instance_of(Windows::Structures::Collection)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it 'return sorted by :id' do
         | 
| 59 | 
            +
                  expected_ids = windows(:sorted).map {|w| w[:id]}
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  subject.windows.ids.should == expected_ids
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              context "#find_windows" do
         | 
| 66 | 
            +
                it 'should find window by id' do
         | 
| 67 | 
            +
                  subject.find_window(2).id.should == 2
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it 'should return Window' do
         | 
| 71 | 
            +
                  subject.find_window(2).should be_instance_of Windows::Structures::Window
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              it '#active_window' do
         | 
| 76 | 
            +
                subject.active_window.active.should be_true
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              private
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              def desktops
         | 
| 82 | 
            +
                unless @desktops
         | 
| 83 | 
            +
                  klass = Windows::Structures::Desktop
         | 
| 84 | 
            +
                  @desktops = []
         | 
| 85 | 
            +
                  @desktops.push({id: 1, workarea: [0, 0, 800, 600]})
         | 
| 86 | 
            +
                  @desktops.push({id: 2, workarea: [0, 0, 1200, 1000]})
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
                @desktops
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              def windows(sorted = false)
         | 
| 92 | 
            +
                unless @windows
         | 
| 93 | 
            +
                klass = Windows::Structures::Window
         | 
| 94 | 
            +
                @windows = []
         | 
| 95 | 
            +
                @windows.push({id: 1, title: 'bash', desktop: 1, geometry: [0,0,100,200]})
         | 
| 96 | 
            +
                @windows.push({id: 3, title: 'torr', desktop: 2, geometry: [100,100,400,800]})
         | 
| 97 | 
            +
                @windows.push({id: 2, title: 'list', desktop: 1, geometry: [50,50,200,400], active: true})
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
                sorted ? @windows.sort_by{|w| w[:id]} : @windows 
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              def create_windows
         | 
| 103 | 
            +
                subject.stub(:list_windows).and_return(windows)
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              def create_desktops
         | 
| 107 | 
            +
                subject.stub(:list_desktops).and_return(desktops)
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            end
         | 
| @@ -0,0 +1,171 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'time'
         | 
| 3 | 
            +
            require 'windows/engines/xwindow'
         | 
| 4 | 
            +
            require 'windows/structures/window'
         | 
| 5 | 
            +
            require 'windows/structures/desktop'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Windows
         | 
| 8 | 
            +
              module Engines
         | 
| 9 | 
            +
                class WMCtrl
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            class DummyEngine
         | 
| 15 | 
            +
              def action(*args)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def spawn_window(command)
         | 
| 19 | 
            +
                fake_window
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def find_window(id)
         | 
| 23 | 
            +
                fake_window
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def fake_window
         | 
| 27 | 
            +
                Windows::Structures::Window.new(1234, 'fake window', fake_desktop)
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              private
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def fake_desktop
         | 
| 33 | 
            +
                Windows::Structures::Desktop.new(9876, [0,0,800,600])
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
            class DummyWindow < Struct.new(:id, :title);end
         | 
| 37 | 
            +
            class DummyDesktop < Struct.new(:x_offset, :y_offset, :width, :height);end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            describe Windows::Engines::XWindow do
         | 
| 40 | 
            +
              subject { Windows::Engines::XWindow.new(command, options, engine)}
         | 
| 41 | 
            +
              let(:engine)  { DummyEngine.new }
         | 
| 42 | 
            +
              let(:command) { 'ls' }
         | 
| 43 | 
            +
              let(:time)    { Time.parse("Sep 13 2011")}
         | 
| 44 | 
            +
              let(:options) { Hash.new }
         | 
| 45 | 
            +
              let(:window)  { engine.fake_window }
         | 
| 46 | 
            +
              let(:id)      { window.id }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              it { should delegate(:title).to(:window) }
         | 
| 49 | 
            +
              it { should delegate(:desktop).to(:window) }
         | 
| 50 | 
            +
              it { should delegate(:x).to(:window) }
         | 
| 51 | 
            +
              it { should delegate(:y).to(:window) }
         | 
| 52 | 
            +
              it { should delegate(:width).to(:window) }
         | 
| 53 | 
            +
              it { should delegate(:height).to(:window) } 
         | 
| 54 | 
            +
              it { should respond_to :command= }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it '#move' do
         | 
| 57 | 
            +
                args = [100, 200, 500, 400]
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                subject.should_receive(:undock).ordered
         | 
| 60 | 
            +
                engine.should_receive(:action).with(id, :move_resize, 0, *args).ordered
         | 
| 61 | 
            +
                subject.move(*args)
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              context 'close' do
         | 
| 65 | 
            +
                it 'should delegate to engine' do
         | 
| 66 | 
            +
                  engine.should_receive(:action).with(id, :close)
         | 
| 67 | 
            +
                  subject.close
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it 'should :id, :created_at set to false' do
         | 
| 71 | 
            +
                  subject.create
         | 
| 72 | 
            +
                  subject.close
         | 
| 73 | 
            +
                  subject.id.should == false
         | 
| 74 | 
            +
                  subject.created_at.should == false
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              it '#focus' do
         | 
| 79 | 
            +
                engine.should_receive(:action).with(id, :activate)
         | 
| 80 | 
            +
                subject.focus  
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              it '#undock' do
         | 
| 84 | 
            +
                args = ["remove", "maximized_vert", "maximized_horz"]
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                engine.should_receive(:action).with(id, :change_state, *args)
         | 
| 87 | 
            +
                subject.undock
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              context "#create" do
         | 
| 91 | 
            +
                before(:each) do
         | 
| 92 | 
            +
                  Time.stub!(:now).and_return(time)
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                it 'should assign id' do
         | 
| 96 | 
            +
                  subject.create
         | 
| 97 | 
            +
                  subject.id.should == engine.fake_window.id 
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it 'should assign created_at' do
         | 
| 101 | 
            +
                  subject.create
         | 
| 102 | 
            +
                  subject.created_at.should == time
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                it 'should return false when window is already created' do
         | 
| 106 | 
            +
                  subject.create
         | 
| 107 | 
            +
                  subject.create.should be_false
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                it 'should not spawn new window when it exist' do
         | 
| 111 | 
            +
                  engine.should_receive(:find_window).with(command).and_return(window)
         | 
| 112 | 
            +
                  engine.should_not_receive(:spawn_window).with(command)
         | 
| 113 | 
            +
                  subject.create
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              context '#window' do
         | 
| 118 | 
            +
                context "when window is not created" do
         | 
| 119 | 
            +
                  it 'should create window' do
         | 
| 120 | 
            +
                    subject.should_receive(:create)
         | 
| 121 | 
            +
                    subject.window
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                context "when window is created" do
         | 
| 126 | 
            +
                  before do
         | 
| 127 | 
            +
                    subject.create
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  it 'should delegate to engine' do
         | 
| 131 | 
            +
                    engine.should_receive(:find_window).with(id)
         | 
| 132 | 
            +
                    subject.window
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              it '#on_top' do
         | 
| 138 | 
            +
                engine.should_receive(:action).with(id, :change_state, "add", "above")
         | 
| 139 | 
            +
                subject.on_top
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              it '#not_on_top' do
         | 
| 143 | 
            +
                engine.should_receive(:action).with(id, :change_state, "remove", "above")
         | 
| 144 | 
            +
                subject.not_on_top
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              context "#action" do
         | 
| 148 | 
            +
                it 'should delegate to engine' do
         | 
| 149 | 
            +
                  args = [0, 0, 0, 100, 200]
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  engine.should_receive(:action).with(id, *args)
         | 
| 152 | 
            +
                  subject.action(*args)
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                it 'should return self' do
         | 
| 156 | 
            +
                  subject.action.should == subject
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
              end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
              it '#maximize' do
         | 
| 161 | 
            +
                engine.should_receive(:action).with(id, :change_state, "add", "maximized_vert", "maximized_horz")
         | 
| 162 | 
            +
                subject.maximize
         | 
| 163 | 
            +
              end
         | 
| 164 | 
            +
             
         | 
| 165 | 
            +
              context "initialize" do
         | 
| 166 | 
            +
                it "should use WMCtrl as default engine" do
         | 
| 167 | 
            +
                  object = subject.class.new(command, options, nil)
         | 
| 168 | 
            +
                  object.engine.should be_instance_of(Windows::Engines::WMCtrl)
         | 
| 169 | 
            +
                end
         | 
| 170 | 
            +
              end
         | 
| 171 | 
            +
            end
         |