kood 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 +47 -0
- data/.yardopts +4 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +9 -0
- data/Rakefile +40 -0
- data/bin/kood +4 -0
- data/kood.gemspec +26 -0
- data/lib/kood-plugin-example.rb +10 -0
- data/lib/kood.rb +14 -0
- data/lib/kood/adapter/git.rb +56 -0
- data/lib/kood/adapter/user_config.rb +36 -0
- data/lib/kood/board.rb +160 -0
- data/lib/kood/card.rb +128 -0
- data/lib/kood/cli.rb +121 -0
- data/lib/kood/cli/board.rb +139 -0
- data/lib/kood/cli/card.rb +188 -0
- data/lib/kood/cli/edit.rb +40 -0
- data/lib/kood/cli/helpers/shell.rb +124 -0
- data/lib/kood/cli/helpers/table.rb +195 -0
- data/lib/kood/cli/list.rb +70 -0
- data/lib/kood/cli/plugin.rb +37 -0
- data/lib/kood/cli/switch.rb +10 -0
- data/lib/kood/core.rb +95 -0
- data/lib/kood/errors.rb +8 -0
- data/lib/kood/extensions/grit.rb +65 -0
- data/lib/kood/list.rb +36 -0
- data/lib/kood/version.rb +3 -0
- data/man/kood-board.1 +74 -0
- data/man/kood-board.1.html +150 -0
- data/man/kood-board.1.ronn +65 -0
- data/man/kood-card.1 +40 -0
- data/man/kood-card.1.html +140 -0
- data/man/kood-card.1.ronn +52 -0
- data/spec/kood/cli_spec.rb +280 -0
- data/spec/spec_helper.rb +67 -0
- data/test/kood/cli_test.rb +67 -0
- metadata +198 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
kood(1) -- sample help page
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
## SYNOPSIS
|
|
5
|
+
|
|
6
|
+
`kood` [<format>...] <file>...<br>
|
|
7
|
+
`kood` `-m`|`--man` <file>...<br>
|
|
8
|
+
`kood` `-S`|`--server` <file>...<br>
|
|
9
|
+
`kood` `--pipe` <file><br>
|
|
10
|
+
`kood` < <file>
|
|
11
|
+
|
|
12
|
+
## DESCRIPTION
|
|
13
|
+
|
|
14
|
+
**Kood** is a CLI for taskboards with a minimal self-hosted web interface.
|
|
15
|
+
|
|
16
|
+
## FILES
|
|
17
|
+
|
|
18
|
+
Sed posuere consectetur est at lobortis. Fusce dapibus, tellus ac cursus commodo,
|
|
19
|
+
tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Curabitur
|
|
20
|
+
blandit tempus porttitor. Duis mollis, est non commodo luctus, nisi erat porttitor
|
|
21
|
+
ligula, eget lacinia odio sem nec elit. Cum sociis natoque penatibus et magnis dis
|
|
22
|
+
parturient montes, nascetur ridiculus mus. Praesent commodo cursus magna, vel
|
|
23
|
+
scelerisque nisl consectetur et. Curabitur blandit tempus porttitor.
|
|
24
|
+
|
|
25
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper nulla
|
|
26
|
+
non metus auctor fringilla. Aenean eu leo quam. Pellentesque ornare sem lacinia
|
|
27
|
+
quam venenatis vestibulum. Curabitur blandit tempus porttitor.
|
|
28
|
+
|
|
29
|
+
## OPTIONS
|
|
30
|
+
|
|
31
|
+
These options control things.
|
|
32
|
+
|
|
33
|
+
* `-s`, `--sample`:
|
|
34
|
+
Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
|
|
35
|
+
Maecenas faucibus mollis interdum. Curabitur blandit tempus porttitor.
|
|
36
|
+
|
|
37
|
+
* `-L`, `--lorem`:
|
|
38
|
+
Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
|
|
39
|
+
Cras mattis consectetur purus sit amet fermentum.
|
|
40
|
+
|
|
41
|
+
* `--pipe`:
|
|
42
|
+
Don't generate files, write generated output to standard output. This is the
|
|
43
|
+
default behavior when ronn source text is piped in on standard input and no
|
|
44
|
+
<file> arguments are provided.
|
|
45
|
+
|
|
46
|
+
Miscellaneous options:
|
|
47
|
+
|
|
48
|
+
* `-e`, `--example`:
|
|
49
|
+
Porta risus etiam consectetur vestibulum.
|
|
50
|
+
|
|
51
|
+
## EXAMPLES
|
|
52
|
+
|
|
53
|
+
Vestibulum id ligula porta felis euismod semper:
|
|
54
|
+
|
|
55
|
+
$ kood --clone my-board new-board
|
|
56
|
+
$ kood --c my-board new-board
|
|
57
|
+
$ kood --assigned user@server status
|
|
58
|
+
|
|
59
|
+
## BUGS
|
|
60
|
+
|
|
61
|
+
**Kood** is a work in progress.
|
|
62
|
+
|
|
63
|
+
## SEE ALSO
|
|
64
|
+
|
|
65
|
+
kood-card(1), kood-status(1)
|
data/man/kood-card.1
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
|
3
|
+
.
|
|
4
|
+
.TH "KOOD\-CARD" "1" "January 2013" "" ""
|
|
5
|
+
.
|
|
6
|
+
.SH "NAME"
|
|
7
|
+
\fBkood\-card\fR \- sample help page
|
|
8
|
+
.
|
|
9
|
+
.SH "SYNOPSIS"
|
|
10
|
+
A brief synopsis of how to invoke your app on the command line\. This should be similar to what the default banner is in OptionParser or what is output by GLI after the “Usage:” bit\.
|
|
11
|
+
.
|
|
12
|
+
.SH "DESCRIPTION"
|
|
13
|
+
A longer description of what your app does, why the user might use it, and any additional details\. This section should be targeted at new users and written to help them understand how to use your app\.
|
|
14
|
+
.
|
|
15
|
+
.SH "OPTIONS"
|
|
16
|
+
A bullet list documenting each option\. This is a chance to explain in more detail how the options work and what effect they have on your app’s behavior\.
|
|
17
|
+
.
|
|
18
|
+
.SH "EXAMPLES"
|
|
19
|
+
One or more examples of using the app, including brief text explaining each example\.
|
|
20
|
+
.
|
|
21
|
+
.SH "FILES"
|
|
22
|
+
A list of files on the filesystem that the app uses (for example, todo would document the default to\-do list file’s location here)\.
|
|
23
|
+
.
|
|
24
|
+
.SH "ENVIRONMENT"
|
|
25
|
+
A bullet list of any environment variables that affect the app’s behavior\.
|
|
26
|
+
.
|
|
27
|
+
.SH "BUGS"
|
|
28
|
+
Known bugs or odd behaviors\.
|
|
29
|
+
.
|
|
30
|
+
.SH "LICENSE"
|
|
31
|
+
The name of the license and a reference to the full license text (you do not need to reproduce the entire license here)\.
|
|
32
|
+
.
|
|
33
|
+
.SH "AUTHOR"
|
|
34
|
+
The authors of your app and their email addresses\.
|
|
35
|
+
.
|
|
36
|
+
.SH "COPYRIGHT"
|
|
37
|
+
The copyright information for your app\.
|
|
38
|
+
.
|
|
39
|
+
.SH "SEE ALSO"
|
|
40
|
+
Links to other commands or places on the Web that are relevant for your app\.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
|
|
6
|
+
<title>kood-card(1) - sample help page</title>
|
|
7
|
+
<style type='text/css' media='all'>
|
|
8
|
+
/* style: man */
|
|
9
|
+
body#manpage {margin:0}
|
|
10
|
+
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
|
11
|
+
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
|
12
|
+
.mp h2 {margin:10px 0 0 0}
|
|
13
|
+
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
|
14
|
+
.mp h3 {margin:0 0 0 4ex}
|
|
15
|
+
.mp dt {margin:0;clear:left}
|
|
16
|
+
.mp dt.flush {float:left;width:8ex}
|
|
17
|
+
.mp dd {margin:0 0 0 9ex}
|
|
18
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
|
19
|
+
.mp pre {margin-bottom:20px}
|
|
20
|
+
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
|
21
|
+
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
|
22
|
+
.mp img {display:block;margin:auto}
|
|
23
|
+
.mp h1.man-title {display:none}
|
|
24
|
+
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
|
25
|
+
.mp h2 {font-size:16px;line-height:1.25}
|
|
26
|
+
.mp h1 {font-size:20px;line-height:2}
|
|
27
|
+
.mp {text-align:justify;background:#fff}
|
|
28
|
+
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
|
29
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
|
30
|
+
.mp u {text-decoration:underline}
|
|
31
|
+
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
|
32
|
+
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
|
33
|
+
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
|
34
|
+
.mp b.man-ref {font-weight:normal;color:#434241}
|
|
35
|
+
.mp pre {padding:0 4ex}
|
|
36
|
+
.mp pre code {font-weight:normal;color:#434241}
|
|
37
|
+
.mp h2+pre,h3+pre {padding-left:0}
|
|
38
|
+
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
|
39
|
+
ol.man-decor {width:100%}
|
|
40
|
+
ol.man-decor li.tl {text-align:left}
|
|
41
|
+
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
|
42
|
+
ol.man-decor li.tr {text-align:right;float:right}
|
|
43
|
+
</style>
|
|
44
|
+
</head>
|
|
45
|
+
<!--
|
|
46
|
+
The following styles are deprecated and will be removed at some point:
|
|
47
|
+
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
|
48
|
+
|
|
49
|
+
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
|
50
|
+
.man-navigation should be used instead.
|
|
51
|
+
-->
|
|
52
|
+
<body id='manpage'>
|
|
53
|
+
<div class='mp' id='man'>
|
|
54
|
+
|
|
55
|
+
<div class='man-navigation' style='display:none'>
|
|
56
|
+
<a href="#NAME">NAME</a>
|
|
57
|
+
<a href="#SYNOPSIS">SYNOPSIS</a>
|
|
58
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
|
59
|
+
<a href="#OPTIONS">OPTIONS</a>
|
|
60
|
+
<a href="#EXAMPLES">EXAMPLES</a>
|
|
61
|
+
<a href="#FILES">FILES</a>
|
|
62
|
+
<a href="#ENVIRONMENT">ENVIRONMENT</a>
|
|
63
|
+
<a href="#BUGS">BUGS</a>
|
|
64
|
+
<a href="#LICENSE">LICENSE</a>
|
|
65
|
+
<a href="#AUTHOR">AUTHOR</a>
|
|
66
|
+
<a href="#COPYRIGHT">COPYRIGHT</a>
|
|
67
|
+
<a href="#SEE-ALSO">SEE ALSO</a>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<ol class='man-decor man-head man head'>
|
|
71
|
+
<li class='tl'>kood-card(1)</li>
|
|
72
|
+
<li class='tc'></li>
|
|
73
|
+
<li class='tr'>kood-card(1)</li>
|
|
74
|
+
</ol>
|
|
75
|
+
|
|
76
|
+
<h2 id="NAME">NAME</h2>
|
|
77
|
+
<p class="man-name">
|
|
78
|
+
<code>kood-card</code> - <span class="man-whatis">sample help page</span>
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
|
82
|
+
|
|
83
|
+
<p>A brief synopsis of how to invoke your app on the command line. This should be similar to
|
|
84
|
+
what the default banner is in OptionParser or what is output by GLI after the “Usage:” bit.</p>
|
|
85
|
+
|
|
86
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
|
87
|
+
|
|
88
|
+
<p>A longer description of what your app does, why the user might use it, and any additional
|
|
89
|
+
details. This section should be targeted at new users and written to help them understand
|
|
90
|
+
how to use your app.</p>
|
|
91
|
+
|
|
92
|
+
<h2 id="OPTIONS">OPTIONS</h2>
|
|
93
|
+
|
|
94
|
+
<p>A bullet list documenting each option. This is a chance to explain in more detail how the
|
|
95
|
+
options work and what effect they have on your app’s behavior.</p>
|
|
96
|
+
|
|
97
|
+
<h2 id="EXAMPLES">EXAMPLES</h2>
|
|
98
|
+
|
|
99
|
+
<p>One or more examples of using the app, including brief text explaining each example.</p>
|
|
100
|
+
|
|
101
|
+
<h2 id="FILES">FILES</h2>
|
|
102
|
+
|
|
103
|
+
<p>A list of files on the filesystem that the app uses (for example, todo would document the
|
|
104
|
+
default to-do list file’s location here).</p>
|
|
105
|
+
|
|
106
|
+
<h2 id="ENVIRONMENT">ENVIRONMENT</h2>
|
|
107
|
+
|
|
108
|
+
<p>A bullet list of any environment variables that affect the app’s behavior.</p>
|
|
109
|
+
|
|
110
|
+
<h2 id="BUGS">BUGS</h2>
|
|
111
|
+
|
|
112
|
+
<p>Known bugs or odd behaviors.</p>
|
|
113
|
+
|
|
114
|
+
<h2 id="LICENSE">LICENSE</h2>
|
|
115
|
+
|
|
116
|
+
<p>The name of the license and a reference to the full license text (you do not need to
|
|
117
|
+
reproduce the entire license here).</p>
|
|
118
|
+
|
|
119
|
+
<h2 id="AUTHOR">AUTHOR</h2>
|
|
120
|
+
|
|
121
|
+
<p>The authors of your app and their email addresses.</p>
|
|
122
|
+
|
|
123
|
+
<h2 id="COPYRIGHT">COPYRIGHT</h2>
|
|
124
|
+
|
|
125
|
+
<p>The copyright information for your app.</p>
|
|
126
|
+
|
|
127
|
+
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
|
128
|
+
|
|
129
|
+
<p>Links to other commands or places on the Web that are relevant for your app.</p>
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
<ol class='man-decor man-foot man foot'>
|
|
133
|
+
<li class='tl'></li>
|
|
134
|
+
<li class='tc'>January 2013</li>
|
|
135
|
+
<li class='tr'>kood-card(1)</li>
|
|
136
|
+
</ol>
|
|
137
|
+
|
|
138
|
+
</div>
|
|
139
|
+
</body>
|
|
140
|
+
</html>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
kood-card(1) -- sample help page
|
|
2
|
+
================================
|
|
3
|
+
|
|
4
|
+
## SYNOPSIS
|
|
5
|
+
|
|
6
|
+
A brief synopsis of how to invoke your app on the command line. This should be similar to
|
|
7
|
+
what the default banner is in OptionParser or what is output by GLI after the “Usage:” bit.
|
|
8
|
+
|
|
9
|
+
## DESCRIPTION
|
|
10
|
+
|
|
11
|
+
A longer description of what your app does, why the user might use it, and any additional
|
|
12
|
+
details. This section should be targeted at new users and written to help them understand
|
|
13
|
+
how to use your app.
|
|
14
|
+
|
|
15
|
+
## OPTIONS
|
|
16
|
+
|
|
17
|
+
A bullet list documenting each option. This is a chance to explain in more detail how the
|
|
18
|
+
options work and what effect they have on your app’s behavior.
|
|
19
|
+
|
|
20
|
+
## EXAMPLES
|
|
21
|
+
|
|
22
|
+
One or more examples of using the app, including brief text explaining each example.
|
|
23
|
+
|
|
24
|
+
## FILES
|
|
25
|
+
|
|
26
|
+
A list of files on the filesystem that the app uses (for example, todo would document the
|
|
27
|
+
default to-do list file’s location here).
|
|
28
|
+
|
|
29
|
+
## ENVIRONMENT
|
|
30
|
+
|
|
31
|
+
A bullet list of any environment variables that affect the app’s behavior.
|
|
32
|
+
|
|
33
|
+
## BUGS
|
|
34
|
+
|
|
35
|
+
Known bugs or odd behaviors.
|
|
36
|
+
|
|
37
|
+
## LICENSE
|
|
38
|
+
|
|
39
|
+
The name of the license and a reference to the full license text (you do not need to
|
|
40
|
+
reproduce the entire license here).
|
|
41
|
+
|
|
42
|
+
## AUTHOR
|
|
43
|
+
|
|
44
|
+
The authors of your app and their email addresses.
|
|
45
|
+
|
|
46
|
+
## COPYRIGHT
|
|
47
|
+
|
|
48
|
+
The copyright information for your app.
|
|
49
|
+
|
|
50
|
+
## SEE ALSO
|
|
51
|
+
|
|
52
|
+
Links to other commands or places on the Web that are relevant for your app.
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe Kood::CLI do
|
|
5
|
+
before do
|
|
6
|
+
%w{ refs/heads HEAD }.each { |f| Kood.repo.git.fs_delete(f) }
|
|
7
|
+
Kood.clear_repo # Force kood to create the master branch again
|
|
8
|
+
Kood::Config.clear_instance
|
|
9
|
+
Kood::Shell.set_terminal_size
|
|
10
|
+
Adapter::UserConfigFile.clear_conf
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "kood board" do
|
|
14
|
+
it "complains if any boards exist" do
|
|
15
|
+
kood('boards').must_equal "No boards were found."
|
|
16
|
+
end
|
|
17
|
+
it "creates on `board foo`" do
|
|
18
|
+
kood('board foo').must_equal "Board created and selected."
|
|
19
|
+
kood('boards').must_equal "* foo (private)"
|
|
20
|
+
end
|
|
21
|
+
it "forces unique IDs" do
|
|
22
|
+
kood('board foo')
|
|
23
|
+
kood('board foo').must_equal "A board with this ID already exists."
|
|
24
|
+
end
|
|
25
|
+
it "complains if an invalid character is used in the board ID" do
|
|
26
|
+
kood('board foo:').must_equal "Board ID is invalid."
|
|
27
|
+
kood('board "foo bar"').must_equal "Board ID is invalid."
|
|
28
|
+
kood('board foo@bar').must_equal "Board ID is invalid."
|
|
29
|
+
end
|
|
30
|
+
it "displays a list on `boards`" do
|
|
31
|
+
kood('board foo', 'board bar')
|
|
32
|
+
kood('boards').must_equal "* foo (private)\n bar (private)"
|
|
33
|
+
end
|
|
34
|
+
it "deletes on `board foo --delete`" do
|
|
35
|
+
kood('board foo', 'board bar')
|
|
36
|
+
kood('board bar -d').must_equal "Board deleted."
|
|
37
|
+
|
|
38
|
+
# Same result is excepted if the board has contents
|
|
39
|
+
kood('b bar', 'sw bar', 'l lorem', 'c ipsum -l lorem', 'b sw foo')
|
|
40
|
+
kood('board bar -d').must_equal "Board deleted."
|
|
41
|
+
end
|
|
42
|
+
it "deletes the current board on `board --delete`" do
|
|
43
|
+
kood('board foo')
|
|
44
|
+
kood('board --delete').must_equal "Board deleted."
|
|
45
|
+
|
|
46
|
+
# Same result is excepted if the board has contents
|
|
47
|
+
kood('b foo', 'l lorem', 'c ipsum -l lorem')
|
|
48
|
+
kood('board foo -d').must_equal "Board deleted."
|
|
49
|
+
end
|
|
50
|
+
it "complains to delete an inexistent board" do
|
|
51
|
+
kood('board foo -d').must_equal "The specified board does not exist."
|
|
52
|
+
end
|
|
53
|
+
it "switches to board on `board switch`" do
|
|
54
|
+
kood('board foo', 'board bar')
|
|
55
|
+
kood('switch bar').must_equal "Board switched to bar."
|
|
56
|
+
kood('boards').must_equal " foo (private)\n* bar (private)"
|
|
57
|
+
kood('select bar').must_equal "Board switched to bar." # Alias
|
|
58
|
+
end
|
|
59
|
+
it "creates an external board on `board foo --repo`" do
|
|
60
|
+
kood('board foo -r /tmp/example-git/').must_equal "Board created and selected."
|
|
61
|
+
kood('boards').must_equal "* foo (private at /tmp/example-git/)"
|
|
62
|
+
end
|
|
63
|
+
# TODO Test the push, pull and sync commands
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe "kood list" do
|
|
67
|
+
before do
|
|
68
|
+
kood('board foo')
|
|
69
|
+
end
|
|
70
|
+
it "complains if any lists exist" do
|
|
71
|
+
kood('lists').must_equal "No lists were found."
|
|
72
|
+
end
|
|
73
|
+
it "creates on `list bar`" do
|
|
74
|
+
kood('list bar').must_equal "List created."
|
|
75
|
+
kood('lists').must_equal "bar"
|
|
76
|
+
end
|
|
77
|
+
it "forces unique IDs in one board" do
|
|
78
|
+
kood('list bar')
|
|
79
|
+
kood('list bar').must_equal "A list with this ID already exists."
|
|
80
|
+
end
|
|
81
|
+
it "does not force unique IDs between boards" do
|
|
82
|
+
kood('list bar', 'board test', 'switch test')
|
|
83
|
+
kood('list bar').must_equal "List created."
|
|
84
|
+
end
|
|
85
|
+
it "displays a list on `lists`" do
|
|
86
|
+
kood('list hello', 'list world')
|
|
87
|
+
kood('lists').must_equal "hello\nworld"
|
|
88
|
+
end
|
|
89
|
+
it "deletes on `list bar --delete`" do
|
|
90
|
+
kood('list bar')
|
|
91
|
+
kood('list bar -d').must_equal "List deleted."
|
|
92
|
+
end
|
|
93
|
+
it "complains to delete an inexistent list" do
|
|
94
|
+
kood('list bar -d').must_equal "The specified list does not exist."
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe "kood card" do
|
|
99
|
+
before do
|
|
100
|
+
kood('board foo', 'board bar', 'list hello', 'list world')
|
|
101
|
+
end
|
|
102
|
+
it "creates on `card 'Sample card' -l hello`" do
|
|
103
|
+
kood('card "Sample card" --list hello').must_equal "Card created."
|
|
104
|
+
kood('cards').must_include "Sample card"
|
|
105
|
+
end
|
|
106
|
+
it "deletes on `card 'Sample card' --delete`" do
|
|
107
|
+
kood('card "Sample card" -l hello')
|
|
108
|
+
kood('card "Sample card" -d').must_equal "Card deleted."
|
|
109
|
+
kood('cards').wont_include "Sample card"
|
|
110
|
+
end
|
|
111
|
+
it "complains to delete an inexistent card" do
|
|
112
|
+
kood('card none -d').must_equal "The specified card does not exist."
|
|
113
|
+
end
|
|
114
|
+
it "complains to delete when there are several matches" do
|
|
115
|
+
kood('card "foo 0" -l hello', 'card "foo 1" -l hello')
|
|
116
|
+
kood('card "foo" -d').must_equal "Multiple cards match the given criteria."
|
|
117
|
+
kood('card "bar" -l hello', 'card "bar" -l hello')
|
|
118
|
+
kood('card "bar" -d').must_equal "Multiple cards match the given criteria."
|
|
119
|
+
end
|
|
120
|
+
it "complains to show an inexistent card" do
|
|
121
|
+
kood('card "Sample card"').must_equal "The specified card does not exist."
|
|
122
|
+
end
|
|
123
|
+
it "displays information on `card 'Sample card'`" do
|
|
124
|
+
kood('card "Sample card" --list hello')
|
|
125
|
+
kood('card "Sample card"').must_include "\u2503 Sample card"
|
|
126
|
+
end
|
|
127
|
+
it "displays information given partial title`" do
|
|
128
|
+
kood('card fo --list hello', 'card foo -l hello', 'card lorem -l hello')
|
|
129
|
+
kood('card fo').must_include "\u2503 fo"
|
|
130
|
+
kood('card foo').must_include "\u2503 foo"
|
|
131
|
+
kood('card f').must_include "\u2503 fo"
|
|
132
|
+
kood('card Fo').must_include "\u2503 fo" # Case-insentive comparison
|
|
133
|
+
kood('card F').must_include "\u2503 fo"
|
|
134
|
+
kood('card l.*e').must_include "\u2503 lorem"
|
|
135
|
+
kood('card z').must_include "The specified card does not exist."
|
|
136
|
+
end
|
|
137
|
+
it "displays an empty board if any cards exist" do
|
|
138
|
+
res = kood('cards')
|
|
139
|
+
res.must_include "foo" # Board title
|
|
140
|
+
res.must_include "hello" # One of the lists
|
|
141
|
+
res.wont_include "bar" # The other board
|
|
142
|
+
end
|
|
143
|
+
it "supports titles with non-ascii characters" do
|
|
144
|
+
kood('card "hello ümlaut ✔" --list hello')
|
|
145
|
+
kood('card "hello ümlaut ✔"').must_include "hello ümlaut ✔"
|
|
146
|
+
end
|
|
147
|
+
it "supports setting several attributes at once" do
|
|
148
|
+
kood('c lorem -l hello --set title:"Lorem Ipsum" content:"Content"')
|
|
149
|
+
out = kood('card lorem')
|
|
150
|
+
out.must_include "Lorem Ipsum"
|
|
151
|
+
out.must_include "Content"
|
|
152
|
+
end
|
|
153
|
+
it "supports setting custom attributes with different types" do
|
|
154
|
+
kood('c lorem -l hello --set foo:bar priority:1 hello_world:-0.42')
|
|
155
|
+
out = kood('card lorem')
|
|
156
|
+
out.must_include "Foo: bar"
|
|
157
|
+
out.must_include "Priority: 1"
|
|
158
|
+
out.must_include "Hello world: -0.42"
|
|
159
|
+
end
|
|
160
|
+
it "prevents the user from overriding the value of the 'list' and 'more' attributes" do
|
|
161
|
+
kood('c lorem -l hello --set list_id:world list:world more:example')
|
|
162
|
+
out = kood('card lorem')
|
|
163
|
+
out.must_include "List: world" # This means custom user attributes were set
|
|
164
|
+
out.must_include "More: example" # instead of modifying the default attributes
|
|
165
|
+
end
|
|
166
|
+
it "unsets attributes on `card sample --unset content:foo`" do
|
|
167
|
+
kood('c lorem -l hello -s content:ex foo:bar')
|
|
168
|
+
kood('c lorem --unset content foo').must_equal "Card updated."
|
|
169
|
+
kood('c lorem').wont_match /content.*foo/i
|
|
170
|
+
end
|
|
171
|
+
it "prevents the user from unsetting the 'title', 'list' and 'more' attributes" do
|
|
172
|
+
out = kood('c lorem -l hello --unset title list list_id more')
|
|
173
|
+
out.must_equal("Card created.\nNo changes to persist.")
|
|
174
|
+
end
|
|
175
|
+
it "adds participants to a card on `card sample --add participants foo`" do
|
|
176
|
+
user_name = `git config --get user.name `.chomp
|
|
177
|
+
user_email = `git config --get user.email`.chomp
|
|
178
|
+
kood("c lorem -l hello --add participants #{ user_name.split.first }")
|
|
179
|
+
kood('c lorem').must_include "Participants: #{ user_name } <#{ user_email }>"
|
|
180
|
+
end
|
|
181
|
+
it "adds elements to custom array attributes" do
|
|
182
|
+
kood('c lorem -l hello --add foo one two three')
|
|
183
|
+
kood('c lorem').must_include "Foo: one, two, three"
|
|
184
|
+
end
|
|
185
|
+
it "removes participants from a card on `c sample --remove participants foo`" do
|
|
186
|
+
first_name = `git config --get user.name `.chomp.split.first
|
|
187
|
+
kood("c lorem -l hello -a participants #{ first_name } José")
|
|
188
|
+
kood("c lorem --remove participants #{ first_name }")
|
|
189
|
+
kood('c lorem').must_include "Participants: José"
|
|
190
|
+
kood("c lorem --remove participants José") # For now, for non-potential members it
|
|
191
|
+
kood('c lorem').wont_include "Participants" # needs to be an exact match
|
|
192
|
+
end
|
|
193
|
+
it "removes elements from custom array attributes" do
|
|
194
|
+
kood('c lorem -l hello --add foo one two three', 'c lorem -r foo one two')
|
|
195
|
+
kood('c lorem').must_include "Foo: three"
|
|
196
|
+
kood("c lorem --remove foo three")
|
|
197
|
+
kood('c lorem').must_include "Foo: " # This may change in the future
|
|
198
|
+
kood("c lorem --unset foo")
|
|
199
|
+
kood('c lorem').wont_include "Foo"
|
|
200
|
+
end
|
|
201
|
+
it "copies to the same list on `card 'Sample card' --copy`" do
|
|
202
|
+
kood('card sample -l hello')
|
|
203
|
+
kood('card sample -c').must_equal "Card copied."
|
|
204
|
+
kood('card jambaz -l world')
|
|
205
|
+
kood('card').gsub("\n","").must_match /hello.*world.*sample.*jambaz.*sample/
|
|
206
|
+
end
|
|
207
|
+
it "copies to another list on `card 'Sample card' --copy list`" do
|
|
208
|
+
kood('card sample -l hello')
|
|
209
|
+
kood('card sample -c world').must_equal "Card copied."
|
|
210
|
+
kood('card jambaz -l world')
|
|
211
|
+
kood('card').gsub("\n","").must_match /hello.*world.*sample.*sample.*jambaz/
|
|
212
|
+
end
|
|
213
|
+
it "supports the combination of the copy and delete options" do
|
|
214
|
+
kood('card sample -l hello')
|
|
215
|
+
old_id = kood('card sample').match(/\u2503 (.*) \(created/).captures[0]
|
|
216
|
+
out = kood('card')
|
|
217
|
+
|
|
218
|
+
kood("card #{ old_id } -cd").must_equal "Card copied.\nCard deleted."
|
|
219
|
+
new_id = kood('card sample').match(/\u2503 (.*) \(created/).captures[0]
|
|
220
|
+
kood('card').must_equal out.gsub(old_id.slice(0, 8), new_id.slice(0, 8))
|
|
221
|
+
end
|
|
222
|
+
it "also displays labels on `cards`" do
|
|
223
|
+
# Without colors
|
|
224
|
+
kood('c sample -l hello --add labels bug docs user-story tech-story foo bar')
|
|
225
|
+
kood('c').must_include "sample #bug, #docs, #user-story, #tech-story, #foo, #bar"
|
|
226
|
+
|
|
227
|
+
# With colors
|
|
228
|
+
colors = [31, 36, 35, 32, 34] # red, cyan, magenta, green, blue
|
|
229
|
+
colors.map! { |c| "\e[#{ c }m#{ "\u2501"*3 }\e[0m" }
|
|
230
|
+
kood_colored('cards').must_include ["\u2501", colors, "\u2501\u254B"].join
|
|
231
|
+
|
|
232
|
+
# When there isn't enough space for all labels, a grey label is added
|
|
233
|
+
Kood::Shell.set_terminal_size(30)
|
|
234
|
+
colors = [31, 36].map! { |c| "\e[#{ c }m#{ "\u2501"*3 }\e[0m" }
|
|
235
|
+
more_labels = "\e[30m\e[1m#{ "\u2501"*3 }\e[0m"
|
|
236
|
+
kood_colored('c').must_include ["\u2501", colors, more_labels, "\u2501\u254B"].join
|
|
237
|
+
end
|
|
238
|
+
# TODO Test for utf-8 in card descriptions
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
describe "kood edit" do
|
|
242
|
+
before do
|
|
243
|
+
kood('board foo', 'list bar', 'card hello --list bar')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "complains if no EDITOR is set" do
|
|
247
|
+
set_env(KOOD_EDITOR: "", EDITOR: "")
|
|
248
|
+
kood('edit hello').must_equal "To edit a card set $EDITOR or $KOOD_EDITOR."
|
|
249
|
+
end
|
|
250
|
+
it "edits the card with KOOD_EDITOR as highest priority" do
|
|
251
|
+
set_env(KOOD_EDITOR: "kood_editor", EDITOR: "editor")
|
|
252
|
+
kood('edit hello').must_match /^Could not run `kood_editor cards\/.*\.md`\.$/
|
|
253
|
+
end
|
|
254
|
+
it "edits the card with EDITOR as 2nd highest priority" do
|
|
255
|
+
set_env(KOOD_EDITOR: "", EDITOR: "editor")
|
|
256
|
+
kood('edit hello').must_match /^Could not run `editor cards\/.*\.md`\.$/
|
|
257
|
+
end
|
|
258
|
+
it "notices if the editor exited without changes" do
|
|
259
|
+
set_env(KOOD_EDITOR: "true") # true is a unix command that returns nothing
|
|
260
|
+
out = "The editor exited without changes. Run `kood update` to persist changes."
|
|
261
|
+
kood('edit hello').must_equal out
|
|
262
|
+
kood('card hello -e').must_equal out # Alias
|
|
263
|
+
|
|
264
|
+
# Just to make sure it actually opens the file. Since edit uses `system`, programs
|
|
265
|
+
# like `cat` will print to stdout and we can't capture the output here
|
|
266
|
+
set_env(KOOD_EDITOR: "ruby -e \"exit 1 unless File.read(ARGV[0]).include?('title')\"")
|
|
267
|
+
kood('edit hello').wont_match "Could not run"
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it "complains if an unknown option is typed" do
|
|
272
|
+
kood('--unknown').must_equal "Unknown switches '--unknown'"
|
|
273
|
+
end
|
|
274
|
+
it "complains if an unknown command is typed" do
|
|
275
|
+
kood('unknown').must_equal "Could not find task \"unknown\"."
|
|
276
|
+
end
|
|
277
|
+
# it "supports third-party plugins" do # TODO
|
|
278
|
+
# kood('example foo').must_equal "Hello from example"
|
|
279
|
+
# end
|
|
280
|
+
end
|