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.
@@ -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` &lt; <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)
@@ -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