Compare commits

...

31 Commits

Author SHA1 Message Date
John Bintz
bb85ff7641 ensure layout editing is allowed outside of tmux sessions 2012-03-06 14:25:03 -05:00
Rémi Prévost
9ad83268ee Use yard/rspec Rake tasks 2012-03-05 16:05:21 -05:00
Rémi Prévost
b083bddeeb Bump version to 0.3.2 2012-03-05 14:22:21 -05:00
Rémi Prévost
ab51679e33 Set a TEAMOCIL environment variable on all splits 2012-03-05 14:22:10 -05:00
Rémi Prévost
22e4bc1d43 Use separate files for Teamocil::Layout subclasses 2012-03-03 13:38:53 -05:00
Rémi Prévost
b6acecae20 Add new task to TODO list 2012-02-24 10:16:29 -05:00
Rémi Prévost
50f3580b96 Update copyright notice 2012-02-07 10:31:27 -05:00
Rémi Prévost
30ac196713 Update README with --list option 2012-01-25 20:52:34 -05:00
Rémi Prévost
60ccf7f035 Bump to version 0.3.1 2012-01-21 14:13:07 -05:00
Rémi Prévost
6390d0d7ed Fix encoding header in gemspec file 2012-01-21 14:10:58 -05:00
Rémi Prévost
048daa65a9 Update teamocil in Gemfile.lock 2012-01-21 14:09:41 -05:00
Rémi Prévost
7deae7eff7 Bump version to 0.3 2012-01-21 14:08:51 -05:00
Rémi Prévost
124bdb1961 Add --list option to CLI class 2012-01-21 14:08:01 -05:00
Rémi Prévost
490df3bd99 Use STDERR to output error messages 2012-01-21 14:05:18 -05:00
Rémi Prévost
a43064e439 Add spec for CLI 2012-01-21 13:47:44 -05:00
Rémi Prévost
192281392b Add Travis build status in README 2011-12-26 16:32:05 -05:00
Rémi Prévost
d053706ce6 Add custom Travis command 2011-12-26 16:22:43 -05:00
Rémi Prévost
b44303b80d Add Travis configuration file 2011-12-26 16:20:15 -05:00
Rémi Prévost
4a6abd75a8 Update README.md with GitHub-flavored Markdown syntax highlighting 2011-12-10 08:11:36 -05:00
Rémi Prévost
11af9bfe85 Merge pull request #8 from hollow/master
Fix typo in --layout handling
2011-11-18 05:42:55 -08:00
Benedikt Böhm
dbc1fc55d7 fix typo 2011-11-18 14:17:23 +01:00
Rémi Prévost
51f79bcc1e Bump to 0.2.2 2011-10-26 05:21:53 -04:00
Rémi Prévost
0068baf3cb Fix issue with index variable hoisting 2011-10-26 05:21:07 -04:00
Rémi Prévost
2a2fc58063 Refactor Window#initialize filters and options 2011-10-24 07:43:37 -04:00
Rémi Prévost
7288d0ab57 Add “pkg” to .gitignore 2011-10-23 21:42:42 -04:00
Rémi Prévost
75283ac21f Bump to 0.2.1 2011-10-23 21:41:34 -04:00
Rémi Prévost
459b971a6a Fix bug with split target 2011-10-23 21:41:06 -04:00
Rémi Prévost
68d07cd897 Add a case to check session handling 2011-10-23 20:42:48 -04:00
Rémi Prévost
f2926471bd Update the todo list 2011-10-23 20:15:54 -04:00
Rémi Prévost
cbed2f3e5b Add more specs, yeah! 2011-10-23 20:10:16 -04:00
Rémi Prévost
e4e9f2d1cd Upgrade teamocil in Gemfile 2011-10-23 19:58:40 -04:00
22 changed files with 466 additions and 240 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
.local* .local*
.yardoc .yardoc
doc doc
pkg

2
.travis.yml Normal file
View File

@ -0,0 +1,2 @@
rvm: 1.9.2
script: "bundle exec rake spec"

View File

@ -1,13 +0,0 @@
--title "Teamocil"
--no-cache
--protected
--no-private
--markup "markdown"
--markup-provider "maruku"
--format html
"README.mkd"
"lib/**/*.rb"

View File

@ -1,7 +1,7 @@
PATH PATH
remote: . remote: .
specs: specs:
teamocil (0.1.11) teamocil (0.3.2)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
@ -19,7 +19,7 @@ GEM
diff-lcs (~> 1.1.2) diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0) rspec-mocks (2.6.0)
syntax (1.0.0) syntax (1.0.0)
yard (0.7.2) yard (0.7.5)
PLATFORMS PLATFORMS
ruby ruby

View File

@ -1,3 +1,3 @@
Copyright 2011 Rémi Prévost. Copyright 2011-2012 Rémi Prévost.
You may use this work without restrictions, as long as this notice is included. You may use this work without restrictions, as long as this notice is included.
The work is provided "as is" without warranty of any kind, neither express nor implied. The work is provided "as is" without warranty of any kind, neither express nor implied.

View File

@ -2,19 +2,24 @@
Teamocil is a simple tool used to automatically create sessions, windows and splits in [tmux](http://tmux.sourceforge.net/) with YAML files. Teamocil is a simple tool used to automatically create sessions, windows and splits in [tmux](http://tmux.sourceforge.net/) with YAML files.
[![Build Status](https://secure.travis-ci.org/remiprev/teamocil.png)](http://travis-ci.org/remiprev/teamocil)
## Usage ## Usage
```bash
$ gem install teamocil $ gem install teamocil
$ mkdir ~/.teamocil $ mkdir ~/.teamocil
$ teamocil --edit sample $ teamocil --edit sample
$ tmux $ tmux
$ teamocil sample $ teamocil sample
```
## Options ## Options
* `--here` opens the session in the current window, it doesnt create an empty first window. * `--here` opens the session in the current window, it doesnt create an empty first window.
* `--layout` takes a custom file path to a YAML layout file. * `--layout` takes a custom file path to a YAML layout file.
* `--edit` opens the layout file (whether or not `--layout` is used) with `$EDITOR`. * `--edit` opens the layout file (whether or not `--layout` is used) with `$EDITOR`.
* `--list` lists all available layouts.
## Layout file structure ## Layout file structure
@ -30,10 +35,12 @@ You can wrap your entire layout file in a `session` and Teamocil will rename the
#### Example #### Example
```yaml
session: session:
name: my-awesome-session name: "my-awesome-session"
windows: windows:
[windows list] [windows list]
```
### Windows ### Windows
@ -49,27 +56,27 @@ If you are not using a top-level `session` key, then the first key of your layou
#### Example #### Example
```yaml
windows: windows:
- name: my-first-window - name: "my-first-window"
options: options:
synchronize-panes: true synchronize-panes: true
root: ~/Projects/foo-www root: "~/Projects/foo-www"
filters: filters:
before: before:
- "echo 'Lets use ruby-1.9.2 for each split in this window.'" - "echo 'Lets use ruby-1.9.2 for each split in this window.'"
- "rvm use 1.9.2" - "rvm use 1.9.2"
splits: splits:
[splits list] [splits list]
- name: my-second-window - name: "my-second-window"
root: ~/Projects/foo-api root: "~/Projects/foo-api"
filters:
after: "rvm use 1.9.2"
splits: splits:
[splits list] [splits list]
- name: my-third-window - name: "my-third-window"
root: ~/Projects/foo-daemons root: "~/Projects/foo-daemons"
splits: splits:
[splits list] [splits list]
```
### Splits ### Splits
@ -84,9 +91,10 @@ Every window must define an array of splits that will be created within it. A ve
#### Example #### Example
```yaml
windows: windows:
- name: my-first-window - name: "my-first-window"
root: ~/Projects/foo-www root: "~/Projects/foo-www"
filters: filters:
before: "rvm use 1.9.2" before: "rvm use 1.9.2"
after: "echo 'I am done initializing this split.'" after: "echo 'I am done initializing this split.'"
@ -95,9 +103,10 @@ Every window must define an array of splits that will be created within it. A ve
- cmd: "bundle exec rails server --port 4000" - cmd: "bundle exec rails server --port 4000"
width: 50 width: 50
- cmd: - cmd:
- sudo service memcached start - "sudo service memcached start"
- sudo service mongodb start - "sudo service mongodb start"
height: 50 height: 50
```
## Layout examples ## Layout examples
@ -107,15 +116,16 @@ See more example files in the `examples` directory.
#### Content of `~/.teamocil/sample-1.yml` #### Content of `~/.teamocil/sample-1.yml`
```yaml
windows: windows:
- name: sample-two-splits - name: "sample-two-splits"
root: ~/Code/sample/www root: "~/Code/sample/www"
splits: splits:
- cmd: - cmd: ["pwd", "ls -la"]
- pwd - cmd: "rails server --port 3000"
- ls -la
- cmd: rails server --port 3000
width: 50 width: 50
```
#### Result of `$ teamocil sample-1` #### Result of `$ teamocil sample-1`
@ -135,19 +145,21 @@ See more example files in the `examples` directory.
#### Content of `~/.teamocil/sample-2.yml` #### Content of `~/.teamocil/sample-2.yml`
```yaml
windows: windows:
- name: sample-four-splits - name: "sample-four-splits"
root: ~/Code/sample/www root: "~/Code/sample/www"
splits: splits:
- cmd: pwd - cmd: "pwd"
- cmd: pwd - cmd: "pwd"
width: 50 width: 50
- cmd: pwd - cmd: "pwd"
height: 50 height: 50
target: bottom-right target: "bottom-right"
- cmd: pwd - cmd: "pwd"
height: 50 height: 50
target: bottom-left target: "bottom-left"
```
#### Result of `$ teamocil sample-2` #### Result of `$ teamocil sample-2`
@ -169,13 +181,14 @@ See more example files in the `examples` directory.
To get autocompletion when typing `teamocil <Tab>` in a zsh session, add this line to your `~/.zshrc` file: To get autocompletion when typing `teamocil <Tab>` in a zsh session, add this line to your `~/.zshrc` file:
```zsh
compctl -g '~/.teamocil/*(:t:r)' teamocil compctl -g '~/.teamocil/*(:t:r)' teamocil
```
## Todo list ## Todo list
* Support tmux options for windows and splits (eg. `synchronize-panes`) * Making sure the layout is valid before executing it (ie. throw exceptions).
* Making sure the layout is valid before executing it * Add more specs.
* Refactor the `Layout` class to make it “test-friendly”
## Contributors ## Contributors
@ -184,6 +197,8 @@ Feel free to contribute and submit issues/pull requests [on GitHub](https://gith
* Samuel Garneau ([garno](https://github.com/garno)) * Samuel Garneau ([garno](https://github.com/garno))
* Jimmy Bourassa ([jbourassa](https://github.com/jbourassa)) * Jimmy Bourassa ([jbourassa](https://github.com/jbourassa))
Take a look at the `spec` folder before you do, and make sure `bundle exec rake spec` passes after your modifications :)
## License ## License
Teamocil is © 2011 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [LITL license](http://litl.info/). See the `LICENSE` file. Teamocil is © 2011-2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [LITL license](http://litl.info/). See the `LICENSE` file.

View File

@ -1,11 +1,28 @@
require "bundler"
Bundler.require(:development)
require "bundler/gem_tasks" require "bundler/gem_tasks"
require "rspec/core/rake_task"
desc "Run specs" task :default => :spec
task :spec do # {{{
sh "bundle exec rspec --color --format=nested #{Dir.glob(File.join(File.dirname(__FILE__), "spec/**/*_spec.rb")).join(" ")}" desc "Run all specs"
RSpec::Core::RakeTask.new(:spec) do |task| # {{{
task.pattern = "spec/**/*_spec.rb"
task.rspec_opts = "--colour --format=documentation"
end # }}} end # }}}
desc "Generate documentation" desc "Generate YARD Documentation"
task :doc do # {{{ YARD::Rake::YardocTask.new do |task| # {{{
sh "bundle exec yard doc" task.options = [
"-o", File.expand_path("../doc", __FILE__),
"--readme=README.md",
"--markup=markdown",
"--markup-provider=maruku",
"--no-private",
"--no-cache",
"--protected",
"--title=Teamocil",
]
task.files = ["lib/**/*.rb"]
end # }}} end # }}}

View File

@ -1,5 +1,5 @@
module Teamocil module Teamocil
VERSION = "0.2" VERSION = "0.3.2"
autoload :Layout, "teamocil/layout" autoload :Layout, "teamocil/layout"
autoload :CLI, "teamocil/cli" autoload :CLI, "teamocil/cli"
end end

View File

@ -5,34 +5,44 @@ module Teamocil
# This class handles interaction with the `tmux` utility. # This class handles interaction with the `tmux` utility.
class CLI class CLI
attr_accessor :layout, :layouts
# Initialize a new run of `tmux` # Initialize a new run of `tmux`
# #
# @param argv [Hash] the command line parameters hash (usually `ARGV`). # @param argv [Hash] the command line parameters hash (usually `ARGV`).
# @param env [Hash] the environment variables hash (usually `ENV`). # @param env [Hash] the environment variables hash (usually `ENV`).
def initialize(argv, env) # {{{ def initialize(argv, env) # {{{
bail "You must be in a tmux session to use teamocil" unless env["TMUX"] parse_options! argv
layout_path = File.join("#{env["HOME"]}", ".teamocil")
if @options.include?(:list)
@layouts = get_layouts(layout_path)
return print_layouts
end
parse_options!
if @options.include?(:layout) if @options.include?(:layout)
file = options[:layout] file = @options[:layout]
else else
file = ::File.join("#{env["HOME"]}/.teamocil", "#{argv[0]}.yml") file = ::File.join(layout_path, "#{argv[0]}.yml")
end end
if @options[:edit] if @options[:edit]
::FileUtils.touch file unless File.exists?(file) ::FileUtils.touch file unless File.exists?(file)
system("$EDITOR \"#{file}\"")
Kernel.system("$EDITOR \"#{file}\"")
else else
bail "There is no file \"#{file}\"" unless File.exists?(file) bail "There is no file \"#{file}\"" unless File.exists?(file)
bail "You must be in a tmux session to use teamocil" unless env["TMUX"]
parsed_layout = YAML.load_file(file) parsed_layout = YAML.load_file(file)
layout = Teamocil::Layout.new(parsed_layout, @options) @layout = Teamocil::Layout.new(parsed_layout, @options)
layout.compile! @layout.compile!
layout.execute_commands(layout.generate_commands) @layout.execute_commands(@layout.generate_commands)
end end
end # }}} end # }}}
# Parse the command line options # Parse the command line options
def parse_options! # {{{ def parse_options!(args) # {{{
@options = {} @options = {}
opts = ::OptionParser.new do |opts| opts = ::OptionParser.new do |opts|
opts.banner = "Usage: teamocil [options] <layout> opts.banner = "Usage: teamocil [options] <layout>
@ -47,19 +57,36 @@ module Teamocil
@options[:edit] = true @options[:edit] = true
end end
opts.on("--layout [LAYOUT]", "Use a specific layout file, instead of ~/.teamocil/<layout>.yml") do |layout| opts.on("--layout [LAYOUT]", "Use a specific layout file, instead of `~/.teamocil/<layout>.yml`") do |layout|
@options[:layout] = layout @options[:layout] = layout
end end
opts.on("--list", "List all available layouts in `~/.teamocil/`") do
@options[:list] = true
end end
opts.parse!
end
opts.parse! args
end # }}}
# Return an array of available layouts
#
# @param path [String] the path used to look for layouts
def get_layouts(path) # {{{
Dir.glob(File.join(path, "*.yml")).map { |file| File.basename(file).gsub(/\..+$/, "") }.sort
end # }}}
# Print each layout on a single line
def print_layouts # {{{
STDOUT.puts @layouts.join("\n")
exit 0
end # }}} end # }}}
# Print an error message and exit the utility # Print an error message and exit the utility
# #
# @param msg [Mixed] something to print before exiting. # @param msg [Mixed] something to print before exiting.
def bail(msg) # {{{ def bail(msg) # {{{
puts "[teamocil] #{msg}" STDERR.puts "[teamocil] #{msg}"
exit 1 exit 1
end # }}} end # }}}

View File

@ -2,135 +2,11 @@ module Teamocil
# This class act as a wrapper around a tmux YAML layout file # This class act as a wrapper around a tmux YAML layout file
class Layout class Layout
autoload :Session, "teamocil/layout/session"
autoload :Window, "teamocil/layout/window"
autoload :Split, "teamocil/layout/split"
# This class represents a session within tmux attr_reader :session
class Session
attr_reader :options, :windows, :name
# Initialize a new tmux session
#
# @param options [Hash] the options, mostly passed by the CLI
# @param attrs [Hash] the session data from the layout file
def initialize(options, attrs={}) # {{{
@name = attrs["name"]
@windows = attrs["windows"].each_with_index.map { |window, index| Window.new(self, index, window) }
@options = options
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
commands << "tmux rename-session \"#{@name}\"" unless @name.nil?
commands << @windows.map(&:generate_commands)
commands << "tmux select-pane -t 0"
commands
end # }}}
end
# This class represents a window within tmux
class Window
attr_reader :filters, :root, :splits, :options, :index, :name
# Initialize a new tmux window
#
# @param session [Session] the session where the window is initialized
# @param index [Fixnnum] the window index
# @param attrs [Hash] the window data from the layout file
def initialize(session, index, attrs={}) # {{{
@name = attrs["name"]
@root = attrs["root"]
@options = attrs["options"]
@filters = attrs["filters"]
@splits = attrs["splits"].each_with_index.map { |split, index| Split.new(self, index, split) }
@index = index
@session = session
@options ||= {}
@filters ||= {}
@filters["before"] ||= []
@filters["after"] ||= []
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
if @session.options.include?(:here) and @index == 0
commands << "tmux rename-window \"#{@name}\""
else
commands << "tmux new-window -n \"#{@name}\""
end
commands << @splits.map(&:generate_commands)
@options.each_pair do |option, value|
value = "on" if value === true
value = "off" if value === false
commands << "tmux set-window-option #{option} #{value}"
end
commands
end # }}}
end
# This class represents a split within a tmux window
class Split
attr_reader :width, :height, :cmd, :index, :target
# Initialize a new tmux split
#
# @param session [Session] the window where the split is initialized
# @param index [Fixnnum] the split index
# @param attrs [Hash] the split data from the layout file
def initialize(window, index, attrs={}) # {{{
@height = attrs["height"]
@width = attrs["width"]
@cmd = attrs["cmd"]
@target = attrs["target"]
@window = window
@index = index
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
# Is it a vertical or horizontal split?
unless @index == 0
if !@width.nil?
commands << "tmux split-window -h -p #{@width}"
elsif !@height.nil?
commands << "tmux split-window -p #{@height}"
else
commands << "tmux split-window"
end
commands << " -t #{@target}" unless @target.nil?
end
# Wrap all commands around filters
@cmd = [@window.filters["before"]] + [@cmd] + [@window.filters["after"]]
# If a `root` key exist, start each split in this directory
@cmd.unshift "cd \"#{@window.root}\"" unless @window.root.nil?
# Execute each split command
@cmd.flatten.compact.each do |command|
commands << "tmux send-keys -t #{@index} \"#{command}\""
commands << "tmux send-keys -t #{@index} Enter"
end
commands
end # }}}
end
# Initialize a new layout from a hash # Initialize a new layout from a hash
# #

View File

@ -0,0 +1,31 @@
module Teamocil
class Layout
# This class represents a session within tmux
class Session
attr_reader :options, :windows, :name
# Initialize a new tmux session
#
# @param options [Hash] the options, mostly passed by the CLI
# @param attrs [Hash] the session data from the layout file
def initialize(options, attrs={}) # {{{
@name = attrs["name"]
@windows = attrs["windows"].each_with_index.map { |window, window_index| Window.new(self, window_index, window) }
@options = options
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
commands << "tmux rename-session \"#{@name}\"" unless @name.nil?
commands << @windows.map(&:generate_commands)
commands << "tmux select-pane -t 0"
commands
end # }}}
end
end
end

View File

@ -0,0 +1,64 @@
module Teamocil
class Layout
# This class represents a split within a tmux window
class Split
attr_reader :width, :height, :cmd, :index, :target
# Initialize a new tmux split
#
# @param session [Session] the window where the split is initialized
# @param index [Fixnnum] the split index
# @param attrs [Hash] the split data from the layout file
def initialize(window, index, attrs={}) # {{{
@height = attrs["height"]
@width = attrs["width"]
@cmd = attrs["cmd"]
@target = attrs["target"]
@window = window
@index = index
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
# Is it a vertical or horizontal split?
init_command = ""
unless @index == 0
if !@width.nil?
init_command = "tmux split-window -h -p #{@width}"
elsif !@height.nil?
init_command = "tmux split-window -p #{@height}"
else
init_command = "tmux split-window"
end
init_command << " -t #{@target}" unless @target.nil?
commands << init_command
end
# Wrap all commands around filters
@cmd = [@window.filters["before"]] + [@cmd] + [@window.filters["after"]]
# If a `root` key exist, start each split in this directory
@cmd.unshift "cd \"#{@window.root}\"" unless @window.root.nil?
# Set the TEAMOCIL environment variable
@cmd.unshift "export TEAMOCIL=1"
# Execute each split command
@cmd.flatten.compact.each do |command|
commands << "tmux send-keys -t #{@index} \"#{command}\""
commands << "tmux send-keys -t #{@index} Enter"
end
commands
end # }}}
end
end
end

View File

@ -0,0 +1,55 @@
module Teamocil
class Layout
# This class represents a window within tmux
class Window
attr_reader :filters, :root, :splits, :options, :index, :name
# Initialize a new tmux window
#
# @param session [Session] the session where the window is initialized
# @param index [Fixnnum] the window index
# @param attrs [Hash] the window data from the layout file
def initialize(session, index, attrs={}) # {{{
@name = attrs["name"]
@root = attrs["root"]
@options = attrs["options"] || {}
@splits = attrs["splits"] || []
@splits = @splits.each_with_index.map { |split, split_index| Split.new(self, split_index, split) }
@filters = attrs["filters"] || {}
@filters["before"] ||= []
@filters["after"] ||= []
@index = index
@session = session
end # }}}
# Generate commands to send to tmux
#
# @return [Array]
def generate_commands # {{{
commands = []
if @session.options.include?(:here) and @index == 0
commands << "tmux rename-window \"#{@name}\""
else
commands << "tmux new-window -n \"#{@name}\""
end
commands << @splits.map(&:generate_commands)
@options.each_pair do |option, value|
value = "on" if value === true
value = "off" if value === false
commands << "tmux set-window-option #{option} #{value}"
end
commands
end # }}}
end
end
end

43
spec/cli_spec.rb Normal file
View File

@ -0,0 +1,43 @@
require File.join(File.dirname(__FILE__), "spec_helper.rb")
describe Teamocil::CLI do
context "executing" do
context "not in tmux" do
before do # {{{
@fake_env = { "TMUX" => 1, "HOME" => File.join(File.dirname(__FILE__), "fixtures") }
end # }}}
it "should allow editing" do # {{{
FileUtils.stub(:touch)
Kernel.should_receive(:system).with(any_args())
@cli = Teamocil::CLI.new(["--edit", "my-layout"], @fake_env)
end # }}}
end
context "in tmux" do
before do # {{{
@fake_env = { "TMUX" => 1, "HOME" => File.join(File.dirname(__FILE__), "fixtures") }
end # }}}
it "creates a layout" do # {{{
@cli = Teamocil::CLI.new(["sample"], @fake_env)
@cli.layout.session.name.should == "sample"
@cli.layout.session.windows.length.should == 2
@cli.layout.session.windows.first.name.should == "foo"
@cli.layout.session.windows.last.name.should == "bar"
end # }}}
it "lists available layouts" do # {{{
@cli = Teamocil::CLI.new(["--list"], @fake_env)
@cli.layouts.should == ["sample", "sample-2"]
end # }}}
end
end
end

10
spec/fixtures/.teamocil/sample-2.yml vendored Normal file
View File

@ -0,0 +1,10 @@
session:
name: sample-2
root: ~
windows:
- name: "foo"
splits:
- cmd: "pwd"
- name: "bar"
splits:
- cmd: "pwd"

10
spec/fixtures/.teamocil/sample.yml vendored Normal file
View File

@ -0,0 +1,10 @@
session:
name: sample
root: ~
windows:
- name: "foo"
splits:
- cmd: "pwd"
- name: "bar"
splits:
- cmd: "pwd"

View File

@ -13,6 +13,7 @@ two-windows:
- cmd: - cmd:
- "echo 'bar'" - "echo 'bar'"
- "echo 'bar in an array'" - "echo 'bar in an array'"
target: bottom-right
- cmd: "echo 'bar again'" - cmd: "echo 'bar again'"
width: 50 width: 50
@ -32,3 +33,11 @@ two-windows-with-filters:
- cmd: "echo 'foo'" - cmd: "echo 'foo'"
- cmd: "echo 'foo again'" - cmd: "echo 'foo again'"
width: 50 width: 50
three-windows-within-a-session:
session:
name: "my awesome session"
windows:
- name: "first window"
- name: "second window"
- name: "third window"

View File

@ -2,15 +2,19 @@ require File.join(File.dirname(__FILE__), "spec_helper.rb")
describe Teamocil::Layout do describe Teamocil::Layout do
context "initializing" do
end
context "compiling" do context "compiling" do
before :each do # {{{ before do # {{{
@layout = Teamocil::Layout.new(layouts["two-windows"], {}) @layout = Teamocil::Layout.new(layouts["two-windows"], {})
end # }}} end # }}}
it "creates windows" do # {{{
session = @layout.compile!
session.windows.each do |window|
window.should be_an_instance_of Teamocil::Layout::Window
end
end # }}}
it "creates windows with names" do # {{{ it "creates windows with names" do # {{{
session = @layout.compile! session = @layout.compile!
session.windows[0].name.should == "foo" session.windows[0].name.should == "foo"
@ -23,6 +27,13 @@ describe Teamocil::Layout do
session.windows[1].root.should == "/bar" session.windows[1].root.should == "/bar"
end # }}} end # }}}
it "creates splits" do # {{{
session = @layout.compile!
session.windows.first.splits.each do |split|
split.should be_an_instance_of Teamocil::Layout::Split
end
end # }}}
it "creates splits with dimensions" do # {{{ it "creates splits with dimensions" do # {{{
session = @layout.compile! session = @layout.compile!
session.windows.first.splits[0].width.should == nil session.windows.first.splits[0].width.should == nil
@ -57,5 +68,31 @@ describe Teamocil::Layout do
session.windows.first.filters["after"].last.should == "echo second after filter" session.windows.first.filters["after"].last.should == "echo second after filter"
end # }}} end # }}}
it "should handle blank filters" do # {{{
session = @layout.compile!
session.windows.first.filters.should have_key "after"
session.windows.first.filters.should have_key "before"
session.windows.first.filters["after"].should be_empty
session.windows.first.filters["before"].should be_empty
end # }}}
it "should handle splits without a target" do # {{{
session = @layout.compile!
session.windows.last.splits.last.target.should == nil
end # }}}
it "should handle splits with a target" do # {{{
session = @layout.compile!
session.windows.last.splits.first.target.should == "bottom-right"
end # }}}
it "should handle windows within a session" do # {{{
layout = Teamocil::Layout.new(layouts["three-windows-within-a-session"], {})
session = layout.compile!
session.windows.length.should == 3
session.name.should == "my awesome session"
end # }}}
end end
end end

20
spec/mock/cli.rb Normal file
View File

@ -0,0 +1,20 @@
module Teamocil
module Mock
module CLI
def self.included(base) # {{{
base.class_eval do
# Do not print anything
def print_layouts
# Nothing
end
end
end # }}}
end
end
end
Teamocil::CLI.send :include, Teamocil::Mock::CLI

20
spec/mock/layout.rb Normal file
View File

@ -0,0 +1,20 @@
module Teamocil
module Mock
module Layout
def self.included(base) # {{{
base.class_eval do
# Do not execute anything
def execute_commands(commands)
# Nothing
end
end
end # }}}
end
end
end
Teamocil::Layout.send :include, Teamocil::Mock::Layout

View File

@ -2,6 +2,8 @@ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
require 'yaml' require 'yaml'
require 'teamocil' require 'teamocil'
require File.join(File.dirname(__FILE__), "./mock/layout.rb")
require File.join(File.dirname(__FILE__), "./mock/cli.rb")
module Helpers module Helpers

View File

@ -1,4 +1,5 @@
# -*- encoding: utf-8 -*- # encoding: utf-8
$:.push File.expand_path("../lib", __FILE__) $:.push File.expand_path("../lib", __FILE__)
require "teamocil" require "teamocil"
@ -24,5 +25,4 @@ spec = Gem::Specification.new do |s|
s.add_development_dependency "rspec" s.add_development_dependency "rspec"
s.add_development_dependency "yard" s.add_development_dependency "yard"
s.add_development_dependency "maruku" s.add_development_dependency "maruku"
end end