list-tool 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/clt +12 -0
- data/lib/list_tool/app/commands/add_item_command.rb +39 -0
- data/lib/list_tool/app/commands/add_list_command.rb +30 -0
- data/lib/list_tool/app/commands/delete_item_command.rb +39 -0
- data/lib/list_tool/app/commands/delete_list_command.rb +32 -0
- data/lib/list_tool/app/commands/help_command.rb +24 -0
- data/lib/list_tool/app/commands/rename_list_command.rb +34 -0
- data/lib/list_tool/app/commands/replace_item_command.rb +34 -0
- data/lib/list_tool/app/commands/show_items_command.rb +35 -0
- data/lib/list_tool/app/commands/show_lists_command.rb +26 -0
- data/lib/list_tool/app/commands/unknown_command.rb +26 -0
- data/lib/list_tool/app/commands/use_command.rb +31 -0
- data/lib/list_tool/app/commands/version_command.rb +24 -0
- data/lib/list_tool/app/commands.rb +43 -0
- data/lib/list_tool/app/printer.rb +41 -0
- data/lib/list_tool/app/runner.rb +54 -0
- data/lib/list_tool/app/string.rb +9 -0
- data/lib/list_tool/app.rb +9 -0
- data/lib/list_tool/data.rb +75 -0
- data/lib/list_tool/file_manager.rb +27 -0
- data/lib/list_tool/item.rb +23 -0
- data/lib/list_tool/json_parser.rb +11 -0
- data/lib/list_tool/list.rb +88 -0
- data/lib/list_tool/lister.rb +81 -0
- data/lib/list_tool/version.rb +3 -0
- data/lib/list_tool.rb +19 -0
- data/list_tool.gemspec +31 -0
- data/spec/fixtures/data.json +18 -0
- data/spec/list_tool/app/commands/add_item_command_spec.rb +108 -0
- data/spec/list_tool/app/commands/add_list_command_spec.rb +74 -0
- data/spec/list_tool/app/commands/delete_item_command_spec.rb +116 -0
- data/spec/list_tool/app/commands/delete_list_command_spec.rb +89 -0
- data/spec/list_tool/app/commands/help_command_spec.rb +41 -0
- data/spec/list_tool/app/commands/rename_list_command_spec.rb +95 -0
- data/spec/list_tool/app/commands/replace_item_command_spec.rb +97 -0
- data/spec/list_tool/app/commands/show_items_command_spec.rb +111 -0
- data/spec/list_tool/app/commands/show_lists_command_spec.rb +48 -0
- data/spec/list_tool/app/commands/unknown_command_spec.rb +31 -0
- data/spec/list_tool/app/commands/use_command_spec.rb +79 -0
- data/spec/list_tool/app/commands/version_comand_spec.rb +41 -0
- data/spec/list_tool/app/commands_spec.rb +80 -0
- data/spec/list_tool/app/printer_spec.rb +54 -0
- data/spec/list_tool/app/runner_spec.rb +166 -0
- data/spec/list_tool/app/string_spec.rb +32 -0
- data/spec/list_tool/data_spec.rb +257 -0
- data/spec/list_tool/file_manager_spec.rb +84 -0
- data/spec/list_tool/item_spec.rb +42 -0
- data/spec/list_tool/json_parser_spec.rb +14 -0
- data/spec/list_tool/list_spec.rb +221 -0
- data/spec/list_tool/lister_spec.rb +186 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/factory.rb +33 -0
- metadata +213 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ListTool::Item do
|
4
|
+
let (:item){ListTool::Item.new(Factory.item)}
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
|
8
|
+
context 'hash given' do
|
9
|
+
context 'success' do
|
10
|
+
it 'stores text' do
|
11
|
+
expect(item.text).to eq 'item1'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'failure' do
|
16
|
+
it 'raises ArgumentError' do
|
17
|
+
expect{ ListTool::Item.new({"text" => 123}) }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'string given' do
|
23
|
+
it 'stores text' do
|
24
|
+
expect(ListTool::Item.new('text').text).to eq 'text'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'wrong argument given' do
|
29
|
+
it 'raises ArgumentError' do
|
30
|
+
expect{ListTool::Item.new(123)}.to raise_error(ArgumentError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#to_json' do
|
37
|
+
it 'returns correct json' do
|
38
|
+
expect(item.to_json).to eq "{\"text\":\"item1\"}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ListTool::JsonParser do
|
4
|
+
|
5
|
+
describe '.parse' do
|
6
|
+
it 'parses json' do
|
7
|
+
json = "{\"test\":0}"
|
8
|
+
allow(JSON).to receive(:parse).with(json).and_return({'test'=>0})
|
9
|
+
|
10
|
+
expect( ListTool::JsonParser.parse(json) ).to eq({"test" => 0})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ListTool::List do
|
4
|
+
|
5
|
+
let (:list) { ListTool::List.new(Factory.list) }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
|
9
|
+
it 'stores items' do
|
10
|
+
expect(list.items[0]).to be_an_instance_of(ListTool::Item)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'hash given' do
|
14
|
+
|
15
|
+
context 'correct' do
|
16
|
+
it 'stores list name' do
|
17
|
+
expect(list.name).to eq 'Todolist'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'stores 2 items' do
|
21
|
+
expect(list.items.length).to eq 2
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'incorrect' do
|
27
|
+
context 'name is not a string' do
|
28
|
+
it 'raises ArgumentError' do
|
29
|
+
expect{ListTool::List.new({'name' => 123, 'items' => []})}.to raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'items is not an array or nil' do
|
34
|
+
it 'raises ArgumentError' do
|
35
|
+
expect{ListTool::List.new({'name' => 'name', 'items' => 'not an array'})}.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'items is nil' do
|
40
|
+
it 'creates list with no items' do
|
41
|
+
expect(ListTool::List.new({'name' => 'name'}).items.length).to be 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'string given' do
|
49
|
+
let (:list) { ListTool::List.new('name') }
|
50
|
+
|
51
|
+
it 'creates blank list' do
|
52
|
+
expect(list.items).to be_empty
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'stores name' do
|
56
|
+
expect(list.name).to eq 'name'
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'wrong argument given' do
|
62
|
+
it 'raises ArgumentError' do
|
63
|
+
expect{ListTool::List.new(123)}.to raise_error(ArgumentError)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
describe '#clear!' do
|
71
|
+
it "clears items array" do
|
72
|
+
list.clear!
|
73
|
+
expect(list.items).to be_empty
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
describe '#rename' do
|
79
|
+
context 'argument is a string' do
|
80
|
+
it 'renames list' do
|
81
|
+
list.rename('new name')
|
82
|
+
expect(list.name).to eq 'new name'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns old name' do
|
86
|
+
expect( list.rename('new name') ).to eq 'Todolist'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'argument is not a string' do
|
91
|
+
it 'raises ArgumentError' do
|
92
|
+
expect{list.rename(123)}.to raise_error(ArgumentError)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#add_item' do
|
98
|
+
it 'adds item to self' do
|
99
|
+
list.add_item('new item')
|
100
|
+
expect(list.items.length).to eq 3
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns not nil' do
|
104
|
+
expect(list.add_item('new item')).not_to be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#delete_item' do
|
109
|
+
|
110
|
+
context 'success' do
|
111
|
+
it 'removes item with given number' do
|
112
|
+
list.delete_item(1)
|
113
|
+
expect(list.items[1]).to be_nil
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'returns not nil' do
|
117
|
+
expect( list.delete_item(1) ).not_to be_nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'no item with given number' do
|
122
|
+
it 'returns nil' do
|
123
|
+
expect( list.delete_item(3) ).to be_nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#change_item' do
|
129
|
+
context 'success' do
|
130
|
+
it 'replaces text of speified item' do
|
131
|
+
list.change_item(1, 'new_text')
|
132
|
+
expect(list.items[1].text).to eq 'new_text'
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'returns not nil' do
|
136
|
+
expect( list.change_item(1, 'new_text') ).not_to be_nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'failure' do
|
141
|
+
|
142
|
+
context 'no item with given index' do
|
143
|
+
it 'returns nil' do
|
144
|
+
expect( list.change_item(3, 'test') ).to be_nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'index is not an integer' do
|
149
|
+
it 'raises ArgumentError' do
|
150
|
+
expect{ list.change_item('abc', 'test') }.to raise_error(ArgumentError)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'new_text is not a string' do
|
155
|
+
it 'raises ArgumentError' do
|
156
|
+
expect{ list.change_item(0, 1) }.to raise_error(ArgumentError)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#move_item' do
|
164
|
+
|
165
|
+
context 'correct pos given' do
|
166
|
+
it 'moves item up' do
|
167
|
+
list.move_item(1, :up)
|
168
|
+
expect(list.items[0].text).to eq 'item2'
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'moves item down' do
|
172
|
+
list.move_item(0, :down)
|
173
|
+
expect(list.items[1].text).to eq 'item1'
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'returns not nil' do
|
177
|
+
expect( list.move_item(1, :up) ).not_to be_nil
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'incorrect pos given' do
|
182
|
+
|
183
|
+
context 'too high pos' do
|
184
|
+
it 'does nothing when moving up' do
|
185
|
+
items = list.items.dup
|
186
|
+
list.move_item(2, :up)
|
187
|
+
expect(list.items).to eq items
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'does nothing when moving down' do
|
191
|
+
items = list.items.dup
|
192
|
+
list.move_item(2, :down)
|
193
|
+
expect(list.items).to eq items
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'too low pos' do
|
198
|
+
it 'does nothing when moving up' do
|
199
|
+
items = list.items.dup
|
200
|
+
list.move_item(0, :up)
|
201
|
+
expect(list.items).to eq items
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'does nothing when moving down' do
|
205
|
+
items = list.items.dup
|
206
|
+
list.move_item(-1, :down)
|
207
|
+
expect(list.items).to eq items
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
describe '#to_json' do
|
215
|
+
it 'returns json representation of list' do
|
216
|
+
json_str = "{\"name\":\"Todolist\",\"items\":[{\"text\":\"item1\"},{\"text\":\"item2\"}]}"
|
217
|
+
expect(list.to_json).to eq json_str
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe ListTool::Lister do
|
4
|
+
let(:lister){ ListTool::Lister.from_hash(Factory.data) }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
|
8
|
+
it 'creates Lister with empty data' do
|
9
|
+
expect(ListTool::Data).to receive(:new).with no_args
|
10
|
+
ListTool::Lister.new
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe '.from_hash' do
|
17
|
+
it 'creates new Lister from given hash' do
|
18
|
+
expect( lister.lists ).to eq( {'Todolist'=>2, 'Wishlist'=>0} )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
describe '.from_json' do
|
24
|
+
it 'creates new Lister from given json string' do
|
25
|
+
allow( ListTool::JsonParser ).to receive(:parse).and_return(Factory.data)
|
26
|
+
|
27
|
+
lister = ListTool::Lister.from_json( Factory.json )
|
28
|
+
expect( lister.lists ).to eq( {'Todolist'=>2, 'Wishlist'=>0} )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe '#lists' do
|
34
|
+
it 'returna a hash of list names and item counts' do
|
35
|
+
expect( lister.lists ).to eq( {'Todolist'=>2, 'Wishlist'=>0} )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
describe '#load' do
|
41
|
+
let (:lister){ListTool::Lister.new}
|
42
|
+
|
43
|
+
it 'loads data from given file' do
|
44
|
+
json = Factory.json
|
45
|
+
allow( ListTool::FileManager ).to receive(:load).and_return( json )
|
46
|
+
allow( ListTool::JsonParser ).to receive(:parse).with(json).and_return( Factory.data )
|
47
|
+
lister.load('data_file')
|
48
|
+
expect( lister.lists ).to eq( {'Todolist'=>2, 'Wishlist'=>0} )
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns self' do
|
52
|
+
allow( ListTool::FileManager ).to receive(:load)
|
53
|
+
allow( ListTool::JsonParser ).to receive(:parse)
|
54
|
+
allow( ListTool::Data ).to receive(:new).and_return( ListTool::Data.new() )
|
55
|
+
expect( lister.load('data_file') ).to eq lister
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
describe '#save' do
|
61
|
+
let (:lister){ListTool::Lister.new}
|
62
|
+
let(:filename){ 'test_file' }
|
63
|
+
|
64
|
+
it 'calls FileManager.save to save its data to file' do
|
65
|
+
data = ListTool::Data.new
|
66
|
+
lister.instance_variable_set(:@data, data)
|
67
|
+
expect( ListTool::FileManager ).to receive(:save).with(filename, data)
|
68
|
+
lister.save(filename)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
describe '#list' do
|
74
|
+
|
75
|
+
context 'success' do
|
76
|
+
context 'no options' do
|
77
|
+
it 'returns hash with list name and array of item texts' do
|
78
|
+
expect( lister.list(0) ).to eq( {name: 'Todolist', items: ['item1', 'item2']} )
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'list number not given' do
|
83
|
+
it 'returns contents of default list' do
|
84
|
+
expect( lister.list ).to eq( {name: 'Todolist', items: ['item1', 'item2']} )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'failure' do
|
90
|
+
context 'no list with given index' do
|
91
|
+
it 'returns nil' do
|
92
|
+
expect( lister.list(2) ).to be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'default list not set and list not given' do
|
97
|
+
it 'raises NoDefaultListError' do
|
98
|
+
lister = ListTool::Lister.new
|
99
|
+
expect{ lister.list }.to raise_error(ListTool::NoDefaultListError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
describe '#inspect' do
|
108
|
+
it "returns '#<ListTool:obj_id>'" do
|
109
|
+
expect( lister.inspect ).to eq "#<ListTool::Lister:0x#{lister.__id__.to_s(16)}>"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
describe '#method_missing' do
|
115
|
+
|
116
|
+
context 'success' do
|
117
|
+
|
118
|
+
it 'returns self' do
|
119
|
+
expect( lister.add_item('text') ).to eq lister
|
120
|
+
end
|
121
|
+
|
122
|
+
context '_list method given' do
|
123
|
+
it 'deligates method call to @data' do
|
124
|
+
data = lister.instance_variable_get(:@data)
|
125
|
+
expect( data ).to receive(:add_list).with('new_list')
|
126
|
+
lister.add_list('new_list')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context '_item method given' do
|
131
|
+
|
132
|
+
context 'list number not specified' do
|
133
|
+
it 'deligates method call to default list' do
|
134
|
+
default_list = lister.instance_variable_get(:@data).default_list
|
135
|
+
expect( default_list ).to receive(:add_item).with('new_item')
|
136
|
+
|
137
|
+
lister.add_item('new_item')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'list number specified' do
|
142
|
+
it 'deligates method call to specified list' do
|
143
|
+
list = lister.instance_variable_get(:@data).lists[0]
|
144
|
+
expect( list ).to receive(:add_item).with('new_item')
|
145
|
+
|
146
|
+
lister.add_item('new_item', list: 0)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'failure' do
|
155
|
+
|
156
|
+
context 'call to unknown method' do
|
157
|
+
it 'raises NoMethodError' do
|
158
|
+
message = "undefined method 'no_such_method' for #{lister.inspect}"
|
159
|
+
expect{lister.no_such_method}.to raise_error(NoMethodError, message)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'no list with specified number' do
|
164
|
+
it 'returns nil' do
|
165
|
+
expect( lister.add_item('new_item', list: 3) ).to be_nil
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'method returned nil' do
|
170
|
+
it 'returns nil' do
|
171
|
+
expect( lister.delete_item(3) ).to be_nil
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'list number not specified and default list not set' do
|
176
|
+
it 'raises NoDefaultListError' do
|
177
|
+
lister = ListTool::Lister.new
|
178
|
+
expect{ lister.add_item('new item') }.to raise_error(ListTool::NoDefaultListError)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# require 'simplecov'
|
2
|
+
# SimpleCov.start
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require_relative '../lib/list_tool'
|
6
|
+
require_relative 'support/factory'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
config.mock_framework = :rspec
|
12
|
+
|
13
|
+
# Run specs in random order to surface order dependencies. If you find an
|
14
|
+
# order dependency and want to debug it, you can fix the order by providing
|
15
|
+
# the seed, which is printed after each run.
|
16
|
+
# --seed 1234
|
17
|
+
config.order = 'random'
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Factory
|
4
|
+
|
5
|
+
def self.blank_data
|
6
|
+
{'lists'=>[]}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.raw_data
|
10
|
+
File.read(File.join('spec', 'fixtures', 'data.json'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.json
|
14
|
+
data.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.data
|
18
|
+
JSON.parse raw_data
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.list
|
22
|
+
data['lists'][0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.blank_list
|
26
|
+
data['lists'][1]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.item
|
30
|
+
list['items'][0]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|