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.
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