twig 1.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.
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twig::Options do
4
+ before :each do
5
+ @twig = Twig.new
6
+ end
7
+
8
+ describe '#read_config_file!' do
9
+ before :each do
10
+ File.should_receive(:expand_path).with(Twig::CONFIG_FILE).
11
+ and_return(Twig::CONFIG_FILE)
12
+ end
13
+
14
+ it 'reads and sets a single option' do
15
+ @twig.stub(:branch_names => ['test'])
16
+ file = double('file')
17
+ File.should_receive(:readable?).with(Twig::CONFIG_FILE).and_return(true)
18
+ File.should_receive(:open).with(Twig::CONFIG_FILE).and_yield(file)
19
+ file.should_receive(:read).and_return(%{
20
+ branch: test
21
+ }.gsub(/^\s+/, ''))
22
+ @twig.options[:branch].should be_nil # Precondition
23
+
24
+ @twig.read_config_file!
25
+
26
+ @twig.options[:branch].should == 'test'
27
+ end
28
+
29
+ it 'reads and sets multiple options' do
30
+ @twig.stub(:branch_names => ['test'])
31
+ file = double('file')
32
+ File.should_receive(:readable?).with(Twig::CONFIG_FILE).and_return(true)
33
+ File.should_receive(:open).with(Twig::CONFIG_FILE).and_yield(file)
34
+ file.should_receive(:read).and_return(%{
35
+ branch: test
36
+ except-branch: test-except
37
+ only-branch: test-only
38
+ max-days-old: 30.5
39
+ }.gsub(/^\s+/, ''))
40
+ @twig.options[:branch].should be_nil # Precondition
41
+ @twig.options[:branch_except].should be_nil # Precondition
42
+ @twig.options[:branch_only].should be_nil # Precondition
43
+ @twig.options[:max_days_old].should be_nil # Precondition
44
+
45
+ @twig.read_config_file!
46
+
47
+ @twig.options[:branch].should == 'test'
48
+ @twig.options[:branch_except].should == /test-except/
49
+ @twig.options[:branch_only].should == /test-only/
50
+ @twig.options[:max_days_old].should == 30.5
51
+ end
52
+
53
+ it 'fails gracefully if the config file is not readable' do
54
+ File.should_receive(:readable?).with(Twig::CONFIG_FILE).and_return(false)
55
+ lambda { @twig.read_config_file! }.should_not raise_exception
56
+ end
57
+ end
58
+
59
+ describe '#set_option' do
60
+ context 'when setting a :branch option' do
61
+ before :each do
62
+ @twig.options[:branch].should be_nil # Precondition
63
+ end
64
+
65
+ it 'succeeds' do
66
+ @twig.should_receive(:branch_names).and_return(%[foo bar])
67
+ @twig.set_option(:branch, 'foo')
68
+ @twig.options[:branch].should == 'foo'
69
+ end
70
+
71
+ it 'fails if the branch is unknown' do
72
+ @twig.should_receive(:branch_names).and_return([])
73
+ @twig.should_receive(:abort)
74
+
75
+ @twig.set_option(:branch, 'foo')
76
+
77
+ @twig.options[:branch].should be_nil
78
+ end
79
+ end
80
+
81
+ it 'sets a :branch_except option' do
82
+ @twig.options[:branch_except].should be_nil # Precondition
83
+ @twig.set_option(:branch_except, 'unwanted_prefix_')
84
+ @twig.options[:branch_except].should == /unwanted_prefix_/
85
+ end
86
+
87
+ it 'sets a :branch_only option' do
88
+ @twig.options[:branch_only].should be_nil # Precondition
89
+ @twig.set_option(:branch_only, 'important_prefix_')
90
+ @twig.options[:branch_only].should == /important_prefix_/
91
+ end
92
+
93
+ context 'when setting a :max_days_old option' do
94
+ before :each do
95
+ @twig.options[:max_days_old].should be_nil # Precondition
96
+ end
97
+
98
+ it 'succeeds' do
99
+ @twig.set_option(:max_days_old, 1)
100
+ @twig.options[:max_days_old].should == 1
101
+ end
102
+
103
+ it 'fails if the option is not numeric' do
104
+ @twig.should_receive(:abort)
105
+ @twig.set_option(:max_days_old, 'blargh')
106
+ @twig.options[:max_days_old].should be_nil
107
+ end
108
+ end
109
+
110
+ it 'sets an :unset_property option' do
111
+ @twig.options[:unset_property].should be_nil # Precondition
112
+ @twig.set_option(:unset_property, 'unwanted_property')
113
+ @twig.options[:unset_property].should == 'unwanted_property'
114
+ end
115
+ end
116
+
117
+ describe '#unset_option' do
118
+ it 'unsets an option' do
119
+ @twig.set_option(:max_days_old, 1)
120
+ @twig.options[:max_days_old].should == 1 # Precondition
121
+
122
+ @twig.unset_option(:max_days_old)
123
+ @twig.options[:max_days_old].should be_nil
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twig::Util do
4
+ describe '.numeric?' do
5
+ it 'returns true if an object is numeric' do
6
+ Twig::Util.numeric?(1).should be_true
7
+ Twig::Util.numeric?('1').should be_true
8
+ end
9
+
10
+ it 'returns false if an object is not numeric' do
11
+ Twig::Util.numeric?('x').should be_false
12
+ Twig::Util.numeric?([]).should be_false
13
+ Twig::Util.numeric?({}).should be_false
14
+ end
15
+ end
16
+ end
data/spec/twig_spec.rb ADDED
@@ -0,0 +1,220 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twig do
4
+ describe '#initialize' do
5
+ it 'creates a Twig instance' do
6
+ twig = Twig.new
7
+ twig.options.should == {}
8
+ end
9
+
10
+ it 'creates a Twig instance with arbitrary options' do
11
+ options = {:foo => 'bar'}
12
+ twig = Twig.new(options)
13
+
14
+ twig.options.should == options
15
+ end
16
+ end
17
+
18
+ describe '#current_branch_name' do
19
+ it 'returns the current branch name' do
20
+ twig = Twig.new
21
+ branch_name = 'fix_all_the_things'
22
+ Twig.should_receive(:run).
23
+ with('git symbolic-ref -q HEAD').
24
+ once. # Should memoize
25
+ and_return(Twig::REF_PREFIX + branch_name)
26
+
27
+ 2.times { twig.current_branch_name.should == branch_name }
28
+ end
29
+ end
30
+
31
+ describe '#all_branches' do
32
+ before :each do
33
+ @branch_names = %w[
34
+ fix_some_of_the_things
35
+ fix_some_other_of_the_things
36
+ fix_nothing
37
+ ]
38
+ branch_refs = @branch_names.map { |name| Twig::REF_PREFIX + name }
39
+ @commit_time_strings = ['2001-01-01', '2002-02-02', '2003-03-03' ]
40
+ @commit_time_agos = ['111 days ago', '222 days ago', '333 days ago']
41
+ @command =
42
+ %{git for-each-ref #{Twig::REF_PREFIX} --format="#{Twig::REF_FORMAT}"}
43
+
44
+ @branch_tuples = (0..2).map do |i|
45
+ "#{branch_refs[i]},#{@commit_time_strings[i]},#{@commit_time_agos[i]}"
46
+ end.join("\n")
47
+ end
48
+
49
+ it 'returns an array of branches' do
50
+ Twig.should_receive(:run).with(@command).and_return(@branch_tuples)
51
+ twig = Twig.new
52
+
53
+ branches = twig.all_branches
54
+
55
+ branches[0].name.should == @branch_names[0]
56
+ branches[0].last_commit_time.to_s.
57
+ should =~ %r{#{@commit_time_strings[0]} .* \(111d ago\)}
58
+ branches[1].name.should == @branch_names[1]
59
+ branches[1].last_commit_time.to_s.
60
+ should =~ %r{#{@commit_time_strings[1]} .* \(222d ago\)}
61
+ branches[2].name.should == @branch_names[2]
62
+ branches[2].last_commit_time.to_s.
63
+ should =~ %r{#{@commit_time_strings[2]} .* \(333d ago\)}
64
+ end
65
+
66
+ it 'memoizes the result' do
67
+ Twig.should_receive(:run).with(@command).once.and_return(@branch_tuples)
68
+ twig = Twig.new
69
+
70
+ 2.times { twig.all_branches }
71
+ end
72
+ end
73
+
74
+ describe '#branches' do
75
+ before :each do
76
+ @twig = Twig.new
77
+ branch_names = %w[
78
+ fix_some_of_the_things
79
+ fix_some_other_of_the_things
80
+ fix_nothing
81
+ ]
82
+ commit_times = [
83
+ Twig::CommitTime.new(Time.now - 86400 * 10, '10 days ago'),
84
+ Twig::CommitTime.new(Time.now - 86400 * 20, '20 days ago'),
85
+ Twig::CommitTime.new(Time.now - 86400 * 30, '30 days ago')
86
+ ]
87
+ @branches = [
88
+ Twig::Branch.new(branch_names[0], :last_commit_time => commit_times[0]),
89
+ Twig::Branch.new(branch_names[1], :last_commit_time => commit_times[1]),
90
+ Twig::Branch.new(branch_names[2], :last_commit_time => commit_times[2])
91
+ ]
92
+ @twig.stub(:all_branches => @branches)
93
+ end
94
+
95
+ it 'returns all branches' do
96
+ @twig.branches.should == @branches
97
+ end
98
+
99
+ it 'returns only branches matching a name pattern' do
100
+ @twig.set_option(:branch_only, /fix_some/)
101
+ @twig.branches.map { |branch| branch.name }.
102
+ should == [@branches[0].name, @branches[1].name]
103
+ end
104
+
105
+ it 'returns all branches except those matching a name pattern' do
106
+ @twig.set_option(:branch_except, /fix_some/)
107
+ @twig.branches.map { |branch| branch.name }.should == [@branches[2].name]
108
+ end
109
+
110
+ it 'returns only branches below a certain age' do
111
+ @twig.set_option(:max_days_old, 25)
112
+ @twig.branches.map { |branch| branch.name }.
113
+ should == [@branches[0].name, @branches[1].name]
114
+ end
115
+ end
116
+
117
+ describe '#branch_names' do
118
+ it 'returns an array of branch names' do
119
+ twig = Twig.new
120
+ branch_names = %w[foo bar baz]
121
+ branches = branch_names.map { |name| Twig::Branch.new(name) }
122
+ twig.should_receive(:branches).and_return(branches)
123
+
124
+ twig.branch_names.should == branch_names
125
+ end
126
+ end
127
+
128
+ describe '#list_branches' do
129
+ before :each do
130
+ @twig = Twig.new
131
+ @list_headers = '[branch list headers]'
132
+ commit_times = [
133
+ Twig::CommitTime.new(Time.now, '111 days ago'),
134
+ Twig::CommitTime.new(Time.now, '222 days ago')
135
+ ]
136
+ commit_times[0].stub(:to_i => 2000_01_01 )
137
+ commit_times[0].stub(:to_s =>'2000-01-01')
138
+ commit_times[1].stub(:to_i => 2000_01_02 )
139
+ commit_times[1].stub(:to_s =>'2000-01-02')
140
+ @branches = [
141
+ Twig::Branch.new('foo', :last_commit_time => commit_times[0]),
142
+ Twig::Branch.new('foo', :last_commit_time => commit_times[1])
143
+ ]
144
+ @branch_lines = ['[foo line]', '[bar line]']
145
+ end
146
+
147
+ it 'returns a list of branches, most recently modified first' do
148
+ @twig.should_receive(:branches).at_least(:once).and_return(@branches)
149
+ @twig.should_receive(:branch_list_headers).and_return(@list_headers)
150
+ @twig.should_receive(:branch_list_line).with(@branches[0]).
151
+ and_return(@branch_lines[0])
152
+ @twig.should_receive(:branch_list_line).with(@branches[1]).
153
+ and_return(@branch_lines[1])
154
+ result = @twig.list_branches
155
+
156
+ result.should == "\n" + @list_headers +
157
+ @branch_lines[1] + "\n" + @branch_lines[0]
158
+ end
159
+
160
+ it 'returns a message if all branches were filtered out by options' do
161
+ @twig.stub(:all_branches => %[foo bar])
162
+ @twig.stub(:branches => [])
163
+
164
+ @twig.list_branches.should include(
165
+ 'There are no branches matching your selected options'
166
+ )
167
+ end
168
+
169
+ it 'returns a message if the repo has no branches' do
170
+ @twig.stub(:all_branches => [])
171
+ @twig.stub(:branches => [])
172
+
173
+ @twig.list_branches.should include('This repository has no branches')
174
+ end
175
+ end
176
+
177
+ describe '#get_branch_property' do
178
+ before :each do
179
+ @twig = Twig.new
180
+ @branch = Twig::Branch.new('test')
181
+ end
182
+
183
+ it 'calls `Twig::Branch#get_property`' do
184
+ property_name = 'foo'
185
+ property_value = 'bar'
186
+ Twig::Branch.should_receive(:new).with(@branch.name).and_return(@branch)
187
+ @branch.should_receive(:get_property).with(property_name).
188
+ and_return(property_value)
189
+
190
+ result = @twig.get_branch_property(@branch.name, property_name)
191
+ result.should == property_value
192
+ end
193
+ end
194
+
195
+ describe '#set_branch_property' do
196
+ it 'calls `Twig::Branch#set_property`' do
197
+ twig = Twig.new
198
+ branch = Twig::Branch.new('test')
199
+ property_name = 'foo'
200
+ property_value = 'bar'
201
+ Twig::Branch.should_receive(:new).with(branch.name).and_return(branch)
202
+ branch.should_receive(:set_property).with(property_name, property_value)
203
+
204
+ twig.set_branch_property(branch.name, property_name, property_value)
205
+ end
206
+ end
207
+
208
+ describe '#unset_branch_property' do
209
+ it 'calls `Twig::Branch#unset_property`' do
210
+ twig = Twig.new
211
+ branch = Twig::Branch.new('test')
212
+ property_name = 'foo'
213
+ Twig::Branch.should_receive(:new).with(branch.name).and_return(branch)
214
+ branch.should_receive(:unset_property).with(property_name)
215
+
216
+ twig.unset_branch_property(branch.name, property_name)
217
+ end
218
+ end
219
+
220
+ end
data/twig.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'twig/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'twig'
8
+ spec.version = Twig::VERSION
9
+ spec.date = '2012-12-13'
10
+ spec.authors = ['Ron DeVera']
11
+ spec.email = ["hello@rondevera.com"]
12
+ spec.homepage = 'https://github.com/rondevera/twig'
13
+ spec.summary = %{Track progress on your Git branches.}
14
+ spec.description =
15
+ 'Twig is a command-line tool for tracking progress on your Git ' <<
16
+ 'branches, remembering ticket ids for each branch, and more. Twig ' <<
17
+ 'supports subcommands for managing branches however you want.'
18
+ spec.post_install_message =
19
+ "\n**************************************************************" <<
20
+ "\n* *" <<
21
+ "\n* Welcome to Twig! *" <<
22
+ "\n* *" <<
23
+ "\n* To get started, run `twig` to list your Git branches, and *" <<
24
+ "\n* `twig --help` for more info. *" <<
25
+ "\n* *" <<
26
+ "\n**************************************************************" <<
27
+ "\n\n"
28
+
29
+ spec.files = `git ls-files`.split($/)
30
+ spec.executables = spec.files.grep(%r{^bin/}).map { |file| File.basename(file) }
31
+ spec.require_paths = ['lib']
32
+ spec.test_files = spec.files.grep(%r{^spec/})
33
+
34
+ spec.required_ruby_version = '>= 1.8.7'
35
+ spec.add_runtime_dependency 'json', '~> 1.7.5'
36
+ spec.add_development_dependency 'rake', '~> 0.9.2'
37
+ spec.add_development_dependency 'rspec', '~> 2.11.0'
38
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twig
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Ron DeVera
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-13 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 7
33
+ - 5
34
+ version: 1.7.5
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 63
46
+ segments:
47
+ - 0
48
+ - 9
49
+ - 2
50
+ version: 0.9.2
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 35
62
+ segments:
63
+ - 2
64
+ - 11
65
+ - 0
66
+ version: 2.11.0
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: Twig is a command-line tool for tracking progress on your Git branches, remembering ticket ids for each branch, and more. Twig supports subcommands for managing branches however you want.
70
+ email:
71
+ - hello@rondevera.com
72
+ executables:
73
+ - twig
74
+ - twig-gh-open
75
+ - twig-gh-update
76
+ - twig-help
77
+ extensions: []
78
+
79
+ extra_rdoc_files: []
80
+
81
+ files:
82
+ - .gitignore
83
+ - .rvmrc
84
+ - CONTRIBUTING.md
85
+ - Gemfile
86
+ - HISTORY.md
87
+ - LICENSE.md
88
+ - README.md
89
+ - Rakefile
90
+ - bin/twig
91
+ - bin/twig-gh-open
92
+ - bin/twig-gh-update
93
+ - bin/twig-help
94
+ - install
95
+ - lib/twig.rb
96
+ - lib/twig/branch.rb
97
+ - lib/twig/cli.rb
98
+ - lib/twig/commit_time.rb
99
+ - lib/twig/display.rb
100
+ - lib/twig/options.rb
101
+ - lib/twig/util.rb
102
+ - lib/twig/version.rb
103
+ - spec/spec_helper.rb
104
+ - spec/twig/branch_spec.rb
105
+ - spec/twig/cli_spec.rb
106
+ - spec/twig/commit_time_spec.rb
107
+ - spec/twig/display_spec.rb
108
+ - spec/twig/options_spec.rb
109
+ - spec/twig/util_spec.rb
110
+ - spec/twig_spec.rb
111
+ - twig.gemspec
112
+ has_rdoc: true
113
+ homepage: https://github.com/rondevera/twig
114
+ licenses: []
115
+
116
+ post_install_message: |+
117
+
118
+ **************************************************************
119
+ * *
120
+ * Welcome to Twig! *
121
+ * *
122
+ * To get started, run `twig` to list your Git branches, and *
123
+ * `twig --help` for more info. *
124
+ * *
125
+ **************************************************************
126
+
127
+ rdoc_options: []
128
+
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 57
137
+ segments:
138
+ - 1
139
+ - 8
140
+ - 7
141
+ version: 1.8.7
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: 3
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ requirements: []
152
+
153
+ rubyforge_project:
154
+ rubygems_version: 1.5.2
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Track progress on your Git branches.
158
+ test_files:
159
+ - spec/spec_helper.rb
160
+ - spec/twig/branch_spec.rb
161
+ - spec/twig/cli_spec.rb
162
+ - spec/twig/commit_time_spec.rb
163
+ - spec/twig/display_spec.rb
164
+ - spec/twig/options_spec.rb
165
+ - spec/twig/util_spec.rb
166
+ - spec/twig_spec.rb