mite.cmd 0.1.10
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 +5 -0
- data/LICENSE +20 -0
- data/README.textile +162 -0
- data/Rakefile +33 -0
- data/TODO +4 -0
- data/VERSION +1 -0
- data/bin/mite +13 -0
- data/lib/mite_cmd.rb +34 -0
- data/lib/mite_cmd/application.rb +180 -0
- data/lib/mite_cmd/autocomplete.rb +48 -0
- data/lib/mite_ext.rb +53 -0
- data/lib/string_ext.rb +50 -0
- data/mite.cmd.gemspec +75 -0
- data/spec/mite_cmd/application_spec.rb +532 -0
- data/spec/mite_cmd/autocomplete_spec.rb +106 -0
- data/spec/mite_cmd_spec.rb +51 -0
- data/spec/mite_ext_spec.rb +99 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/string_ext_spec.rb +67 -0
- data/vendor/yolk-mite-rb-0.0.3/CHANGES.txt +11 -0
- data/vendor/yolk-mite-rb-0.0.3/LICENSE +20 -0
- data/vendor/yolk-mite-rb-0.0.3/README.textile +70 -0
- data/vendor/yolk-mite-rb-0.0.3/Rakefile +24 -0
- data/vendor/yolk-mite-rb-0.0.3/VERSION.yml +4 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite-rb.rb +105 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/customer.rb +9 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/project.rb +16 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/service.rb +7 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/time_entry.rb +54 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/time_entry_group.rb +36 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/tracker.rb +34 -0
- data/vendor/yolk-mite-rb-0.0.3/lib/mite/user.rb +19 -0
- metadata +92 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe MiteCmd::Autocomplete, 'new' do
|
4
|
+
it "should set calling_script" do
|
5
|
+
autocomplete = MiteCmd::Autocomplete.new('/usr/local/bin/mite')
|
6
|
+
autocomplete.instance_variable_get('@calling_script').should == '/usr/local/bin/mite'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe MiteCmd::Autocomplete do
|
11
|
+
before(:each) do
|
12
|
+
@autocomplete = MiteCmd::Autocomplete.new '/usr/local/bin/test_command'
|
13
|
+
@autocomplete.completion_table = {
|
14
|
+
0 => ['argument1', 'argument1a', 'argument1b', 'argument1c'],
|
15
|
+
1 => ['Homer', 'Simpsons', 'Holy', 'Holy Moly', 'Holy Grail'],
|
16
|
+
2 => ['I love spaces']
|
17
|
+
}
|
18
|
+
ENV['COMP_LINE'] = "./test_command argument1 Holy \"I love spaces\""
|
19
|
+
ENV['COMP_POINT'] = '27'
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'argument_string' do
|
23
|
+
it "should return a string of all arguments without the calling script" do
|
24
|
+
@autocomplete.argument_string.should == 'argument1 Holy "I love spaces"'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'partial_argument_string' do
|
29
|
+
it "should return the arguments part of the bash line" do
|
30
|
+
@autocomplete.partial_argument_string.should == 'argument1 Holy'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to handle unmatched quotes" do
|
34
|
+
ENV['COMP_LINE'] = "./test_command \"arg "
|
35
|
+
ENV['COMP_POINT'] = '20'
|
36
|
+
@autocomplete.partial_argument_string.should == '"arg "'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'args' do
|
41
|
+
it "should return an array of arguments" do
|
42
|
+
@autocomplete.args.should == ['argument1', 'Holy', 'I love spaces']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'cursor_position' do
|
47
|
+
it "should return the cursor position as integer" do
|
48
|
+
@autocomplete.cursor_position.should == 27
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'current_word' do
|
53
|
+
it "should return the current word at the cursor position" do
|
54
|
+
@autocomplete.current_word.should == 'Holy'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be able to handle unmatched quotes" do
|
58
|
+
ENV['COMP_LINE'] = "./test_command \"arg "
|
59
|
+
ENV['COMP_POINT'] = '20'
|
60
|
+
@autocomplete.current_word.should == 'arg '
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return nil if the last word has been completed" do
|
64
|
+
ENV['COMP_LINE'] = "./test_command arg0 "
|
65
|
+
ENV['COMP_POINT'] = '20'
|
66
|
+
@autocomplete.current_word.should == nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'current_argument_index' do
|
71
|
+
it "should return the index of the argument at the cursor position" do
|
72
|
+
@autocomplete.current_argument_index.should == 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should default to 0 if there are no args yet" do
|
76
|
+
ENV['COMP_LINE'] = "./test_command "
|
77
|
+
ENV['COMP_POINT'] = '15'
|
78
|
+
@autocomplete.current_argument_index.should == 0
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should return the size of the existing arguments plus 1 if the cursor position is at the end" do
|
82
|
+
ENV['COMP_LINE'] = "./test_command arg_index0 arg_index1 "
|
83
|
+
ENV['COMP_POINT'] = '37'
|
84
|
+
@autocomplete.current_argument_index.should == 2
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'suggestions' do
|
89
|
+
it "should return the suggested values from the completion table at the current argument index" do
|
90
|
+
@autocomplete.suggestions.should == ['Holy', 'Holy Moly', 'Holy Grail']
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should ignore the case of the typed argument" do
|
94
|
+
# COMP_POINT 27 v
|
95
|
+
ENV['COMP_LINE'] = "/.test_command argument1 holy \"I love spaces\""
|
96
|
+
ENV['COMP_POINT'] = '27'
|
97
|
+
@autocomplete.suggestions.should == ['Holy', 'Holy Moly', 'Holy Grail']
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return an empty array if the current argument index is out of range" do
|
101
|
+
@autocomplete.stub!(:current_argument_index).and_return 50
|
102
|
+
@autocomplete.suggestions.should == []
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe MiteCmd, 'load_configuration' do
|
4
|
+
def fake_configuration
|
5
|
+
File.stub!(:exist?).and_return true
|
6
|
+
File.stub!(:read).and_return :yaml_data
|
7
|
+
YAML.stub!(:load).and_return({:account => 'demo', :apikey => '123'})
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'configuration file exists' do
|
11
|
+
before(:each) do
|
12
|
+
fake_configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set the account name for Mite" do
|
16
|
+
Mite.should_receive(:account=).with 'demo'
|
17
|
+
MiteCmd.load_configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set the apikey for Mite" do
|
21
|
+
Mite.should_receive(:key=).with '123'
|
22
|
+
MiteCmd.load_configuration
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'configuration file does not exist' do
|
27
|
+
before(:each) do
|
28
|
+
File.stub!(:exist?).and_return false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise an error if the configuration file is missing" do
|
32
|
+
lambda {
|
33
|
+
MiteCmd.load_configuration
|
34
|
+
}.should raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe MiteCmd, 'run' do
|
40
|
+
it "should create a new instance of the Application class using the given arguments" do
|
41
|
+
MiteCmd::Application.should_receive(:new).with(['arg1', 'arg2']).and_return stub('application', :run => nil)
|
42
|
+
MiteCmd.run(['arg1', 'arg2'])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should call run on the new instance" do
|
46
|
+
application = stub('application')
|
47
|
+
MiteCmd::Application.stub!(:new).and_return application
|
48
|
+
application.should_receive :run
|
49
|
+
MiteCmd.run([])
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Mite, 'account_url' do
|
4
|
+
it "should return the url for this account" do
|
5
|
+
Mite.account = 'demo'
|
6
|
+
Mite.account_url.should == 'http://demo.mite.yo.lk'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Mite::TimeEntry, 'formatted_time' do
|
11
|
+
it "should output minutes formatted in h:mm" do
|
12
|
+
time_entry = Mite::TimeEntry.new
|
13
|
+
time_entry.stub!(:minutes).and_return 12
|
14
|
+
time_entry.formatted_time.should == '0:12'
|
15
|
+
time_entry.stub!(:minutes).and_return 2
|
16
|
+
time_entry.formatted_time.should == '0:02'
|
17
|
+
time_entry.stub!(:minutes).and_return 61
|
18
|
+
time_entry.formatted_time.should == '1:01'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should use the minutes from the tracker if there is a tracker running for this time entry" do
|
22
|
+
time_entry = Mite::TimeEntry.new
|
23
|
+
time_entry.stub!(:tracking?).and_return true
|
24
|
+
time_entry.stub!(:tracker).and_return stub('tracking', :minutes => 123)
|
25
|
+
time_entry.formatted_time.should == '2:03'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Mite::TimeEntry, 'formatted_revenue' do
|
30
|
+
it "should output the revenue in a readable money format" do
|
31
|
+
time_entry = Mite::TimeEntry.new
|
32
|
+
time_entry.stub!(:revenue).and_return 1050
|
33
|
+
time_entry.formatted_revenue.should == '10.50 $'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should output an empty string if revenue is nil" do
|
37
|
+
time_entry = Mite::TimeEntry.new
|
38
|
+
time_entry.revenue = nil
|
39
|
+
time_entry.formatted_revenue.should == ''
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Mite::TimeEntry, 'inspect' do
|
44
|
+
before(:each) do
|
45
|
+
@time_entry = Mite::TimeEntry.new
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'with time' do
|
49
|
+
before(:each) do
|
50
|
+
@time_entry.stub!(:minutes).and_return 15
|
51
|
+
@time_entry.stub!(:revenue).and_return nil
|
52
|
+
@time_entry.stub!(:service).and_return nil
|
53
|
+
@time_entry.stub!(:project).and_return nil
|
54
|
+
@time_entry.stub!(:note).and_return nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should output the current formatted_minutes colorized in lightred" do
|
58
|
+
@time_entry.inspect.should == "\e[1;31;49m0:15\e[0m"
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'and revenue' do
|
62
|
+
it "should append the current formatted_revenue colorized in lightgreen" do
|
63
|
+
@time_entry.stub!(:revenue).and_return 1500
|
64
|
+
@time_entry.inspect.should be_include("\e[1;32;49m15.00 $\e[0m")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'and service' do
|
69
|
+
it "should append the service name" do
|
70
|
+
@time_entry.stub!(:service).and_return stub('service', :name => 'programming')
|
71
|
+
@time_entry.inspect.should be_include("doing programming")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'and project' do
|
76
|
+
it "should append the project name" do
|
77
|
+
@time_entry.stub!(:project).and_return stub('project', :name => 'mite command line client')
|
78
|
+
@time_entry.inspect.should be_include("for mite command line client")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'and a note' do
|
83
|
+
it "should append the note" do
|
84
|
+
@time_entry.stub!(:note).and_return 'would be more fun in pair programming'
|
85
|
+
@time_entry.inspect.should be_include("would be more fun in pair programming")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Mite::Tracker, 'inspect' do
|
93
|
+
it "should call inspect on its time entry" do
|
94
|
+
time_entry = stub('time_entry')
|
95
|
+
Mite::TimeEntry.stub!(:find).and_return time_entry
|
96
|
+
time_entry.should_receive(:inspect)
|
97
|
+
Mite::Tracker.new.inspect
|
98
|
+
end
|
99
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe String, 'quote' do
|
4
|
+
it "should wrap a string in quotes" do
|
5
|
+
'Gimme quotes'.quote.should == '"Gimme quotes"'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe String, 'quote_if_spaced' do
|
10
|
+
it "should wrap a string in quotes if it contains spaces" do
|
11
|
+
'I want quotes'.quote_if_spaced.should == '"I want quotes"'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should leave the string unmodified if it doesn't contain spaces" do
|
15
|
+
'I_hate_spaces_and_quotes'.quote_if_spaced.should == 'I_hate_spaces_and_quotes'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe String, 'close_unmatched_quotes' do
|
20
|
+
it "should close unmatched quotes" do
|
21
|
+
'"arg '.close_unmatched_quotes.should == '"arg "'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should leave an healthy string intact" do
|
25
|
+
'I am happy.'.close_unmatched_quotes.should == 'I am happy.'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe String, 'colorize' do
|
30
|
+
describe 'defaults' do
|
31
|
+
it "should use default background" do
|
32
|
+
'1995'.colorize.should == "\e[0;39;49m1995\e[0m"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should use default foreground" do
|
36
|
+
'1995'.colorize.should == "\e[0;39;49m1995\e[0m"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should default to no effect" do
|
40
|
+
'1995'.colorize.should == "\e[0;39;49m1995\e[0m"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'empty string' do
|
45
|
+
it "should return the empty string" do
|
46
|
+
''.colorize.should == ''
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
[:black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default].each do |color|
|
51
|
+
it "should set #{color} as foreground color" do
|
52
|
+
'The seventies'.colorize(:color => color).should == "\e[0;#{String::BASH_COLOR[color]};49mThe seventies\e[0m"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should set #{color} as background color" do
|
56
|
+
'The eighties'.colorize(:background => color).should == "\e[0;39;#{String::BASH_COLOR[color]+10}mThe eighties\e[0m"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should set the effect code to bright with light#{color} as foreground" do
|
60
|
+
'The nineties'.colorize(:color => "light#{color}".to_sym).should == "\e[1;#{String::BASH_COLOR[color]};49mThe nineties\e[0m"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should take a foreground color like #{color} as shorthand argument" do
|
64
|
+
'The year 2000'.colorize(color.to_sym).should == "\e[0;#{String::BASH_COLOR[color]};49mThe year 2000\e[0m"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Yolk Sebastian Munz & Julia Soergel GbR
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,70 @@
|
|
1
|
+
The official ruby library for interacting with the "RESTful API":http://mite.yo.lk/en/api of "mite":http://mite.yo.lk/en, a sleek time tracking webapp.
|
2
|
+
|
3
|
+
h3. Install
|
4
|
+
|
5
|
+
As a ruby gem from github:
|
6
|
+
|
7
|
+
sudo gem install yolk-mite-rb -s http://gems.github.com
|
8
|
+
|
9
|
+
mite-rb requires activeresource and activesupport gems in a current version (2.3.2) to be installed.
|
10
|
+
|
11
|
+
h3. Documentation
|
12
|
+
|
13
|
+
The first thing you need to set is the account name. This is the same as the web address (subdomain) for your account. For example if you use mite from the domain demo.mite.yo.lk:
|
14
|
+
|
15
|
+
Mite.account = 'demo'
|
16
|
+
|
17
|
+
Then, you should set the authentication. You can either use your login credentials (email and password) with HTTP Basic Authentication or your mite.api key. In both cases you must enable the mite.api in your user settings.
|
18
|
+
|
19
|
+
With basic authentication:
|
20
|
+
|
21
|
+
Mite.authenticate('rick@techno-weenie.net', 'spacemonkey')
|
22
|
+
|
23
|
+
or, use your api key:
|
24
|
+
|
25
|
+
Mite.key = 'cdfeasdaabcdefgssaeabcdefg'
|
26
|
+
|
27
|
+
You should read the complete mite.api documentation at http://mite.yo.lk/en/api
|
28
|
+
|
29
|
+
h4. Project
|
30
|
+
|
31
|
+
Find all active projects of the current account
|
32
|
+
|
33
|
+
Mite::Project.all
|
34
|
+
|
35
|
+
Find single project by ID
|
36
|
+
|
37
|
+
Mite::Project.find(1209)
|
38
|
+
|
39
|
+
Creating a Project
|
40
|
+
|
41
|
+
project = Mite::Project.new(:name => 'Playing with the mite.api')
|
42
|
+
project.save
|
43
|
+
|
44
|
+
or
|
45
|
+
|
46
|
+
project = Mite::Project.create(:name => 'Playing with the mite.api')
|
47
|
+
|
48
|
+
Updating a Project
|
49
|
+
|
50
|
+
project = Mite::Project.find(1209)
|
51
|
+
project.name = "mite.api"
|
52
|
+
project.customer = Mite::Customer.find(384)
|
53
|
+
project.save
|
54
|
+
|
55
|
+
Get the customer of an project
|
56
|
+
|
57
|
+
project = Mite::Project.find(1209)
|
58
|
+
project.customer
|
59
|
+
|
60
|
+
Deleting a project
|
61
|
+
|
62
|
+
project = Mite::Project.find(1209)
|
63
|
+
project.destroy
|
64
|
+
|
65
|
+
Restore a destroyed project
|
66
|
+
(will only work for aprox. 12 hours after the object was destroyed)
|
67
|
+
|
68
|
+
project = Mite::Project.undo_destroy(1209)
|
69
|
+
|
70
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
task :default => [:spec]
|
2
|
+
|
3
|
+
$gem_name = "mite-rb"
|
4
|
+
|
5
|
+
desc "Run specs"
|
6
|
+
task :spec do
|
7
|
+
sh "spec spec/* --format specdoc --color"
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'jeweler'
|
12
|
+
Jeweler::Tasks.new do |s|
|
13
|
+
s.name = $gem_name
|
14
|
+
s.summary = "The official ruby library for interacting with the RESTful API of mite, a sleek time tracking webapp."
|
15
|
+
s.email = "sebastian@yo.lk"
|
16
|
+
s.homepage = "http://github.com/yolk/mite-rb"
|
17
|
+
s.description = "The official ruby library for interacting with the RESTful mite.api."
|
18
|
+
s.authors = ["Sebastian Munz"]
|
19
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.2"])
|
20
|
+
s.add_dependency(%q<activeresource>, [">= 2.3.2"])
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
24
|
+
end
|