list-tool 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/bin/clt +12 -0
  10. data/lib/list_tool/app/commands/add_item_command.rb +39 -0
  11. data/lib/list_tool/app/commands/add_list_command.rb +30 -0
  12. data/lib/list_tool/app/commands/delete_item_command.rb +39 -0
  13. data/lib/list_tool/app/commands/delete_list_command.rb +32 -0
  14. data/lib/list_tool/app/commands/help_command.rb +24 -0
  15. data/lib/list_tool/app/commands/rename_list_command.rb +34 -0
  16. data/lib/list_tool/app/commands/replace_item_command.rb +34 -0
  17. data/lib/list_tool/app/commands/show_items_command.rb +35 -0
  18. data/lib/list_tool/app/commands/show_lists_command.rb +26 -0
  19. data/lib/list_tool/app/commands/unknown_command.rb +26 -0
  20. data/lib/list_tool/app/commands/use_command.rb +31 -0
  21. data/lib/list_tool/app/commands/version_command.rb +24 -0
  22. data/lib/list_tool/app/commands.rb +43 -0
  23. data/lib/list_tool/app/printer.rb +41 -0
  24. data/lib/list_tool/app/runner.rb +54 -0
  25. data/lib/list_tool/app/string.rb +9 -0
  26. data/lib/list_tool/app.rb +9 -0
  27. data/lib/list_tool/data.rb +75 -0
  28. data/lib/list_tool/file_manager.rb +27 -0
  29. data/lib/list_tool/item.rb +23 -0
  30. data/lib/list_tool/json_parser.rb +11 -0
  31. data/lib/list_tool/list.rb +88 -0
  32. data/lib/list_tool/lister.rb +81 -0
  33. data/lib/list_tool/version.rb +3 -0
  34. data/lib/list_tool.rb +19 -0
  35. data/list_tool.gemspec +31 -0
  36. data/spec/fixtures/data.json +18 -0
  37. data/spec/list_tool/app/commands/add_item_command_spec.rb +108 -0
  38. data/spec/list_tool/app/commands/add_list_command_spec.rb +74 -0
  39. data/spec/list_tool/app/commands/delete_item_command_spec.rb +116 -0
  40. data/spec/list_tool/app/commands/delete_list_command_spec.rb +89 -0
  41. data/spec/list_tool/app/commands/help_command_spec.rb +41 -0
  42. data/spec/list_tool/app/commands/rename_list_command_spec.rb +95 -0
  43. data/spec/list_tool/app/commands/replace_item_command_spec.rb +97 -0
  44. data/spec/list_tool/app/commands/show_items_command_spec.rb +111 -0
  45. data/spec/list_tool/app/commands/show_lists_command_spec.rb +48 -0
  46. data/spec/list_tool/app/commands/unknown_command_spec.rb +31 -0
  47. data/spec/list_tool/app/commands/use_command_spec.rb +79 -0
  48. data/spec/list_tool/app/commands/version_comand_spec.rb +41 -0
  49. data/spec/list_tool/app/commands_spec.rb +80 -0
  50. data/spec/list_tool/app/printer_spec.rb +54 -0
  51. data/spec/list_tool/app/runner_spec.rb +166 -0
  52. data/spec/list_tool/app/string_spec.rb +32 -0
  53. data/spec/list_tool/data_spec.rb +257 -0
  54. data/spec/list_tool/file_manager_spec.rb +84 -0
  55. data/spec/list_tool/item_spec.rb +42 -0
  56. data/spec/list_tool/json_parser_spec.rb +14 -0
  57. data/spec/list_tool/list_spec.rb +221 -0
  58. data/spec/list_tool/lister_spec.rb +186 -0
  59. data/spec/spec_helper.rb +18 -0
  60. data/spec/support/factory.rb +33 -0
  61. 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
@@ -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