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,80 @@
1
+ require_relative '../../spec_helper.rb'
2
+
3
+ describe ListTool::App::Commands do
4
+ subject { ListTool::App::Commands }
5
+
6
+ it 'stores command list' do
7
+ commands = ListTool::App.constants.map {|c| ListTool::App.const_get(c)} - [ListTool::App::Commands, ListTool::App::Printer, ListTool::App::Runner]
8
+ expect(subject::COMMANDS).to eq commands
9
+ end
10
+
11
+ describe '.process' do
12
+ let(:lister) {ListTool::Lister.new}
13
+ let(:printer) { ListTool::App::Printer }
14
+
15
+ context 'success' do
16
+
17
+ it 'gets command from argv' do
18
+ expect(argv = []).to receive(:shift).with(no_args)
19
+ allow(subject::COMMANDS).to receive(:each)
20
+ subject.process(argv, lister)
21
+ end
22
+
23
+ context 'no command given' do
24
+ it 'uses "h" command' do
25
+ expect(argv = []).to receive(:<<).with('h')
26
+ allow(subject::COMMANDS).to receive(:each)
27
+ subject.process(argv, lister)
28
+ end
29
+ end
30
+
31
+ it "passes command commands' .match? method" do
32
+ ListTool::App::Commands::COMMANDS.each do |cmd|
33
+ expect(cmd).to receive(:match?).with('some_command')
34
+ end
35
+ subject.process(['some_command'], lister)
36
+ end
37
+
38
+ it "executes matched command" do
39
+ expect(ListTool::App::ShowListsCommand).to receive(:parse)
40
+ expect(ListTool::App::ShowListsCommand).to receive(:execute)
41
+ subject.process(['sl'], lister)
42
+ end
43
+
44
+ it "don't execute unmatched commands" do
45
+ ListTool::App::Commands::COMMANDS.each do |cmd|
46
+ expect(cmd).not_to receive(:parse) unless cmd == ListTool::App::AddListCommand
47
+ expect(cmd).not_to receive(:execute) unless cmd == ListTool::App::AddListCommand
48
+ end
49
+ allow(ListTool::App::AddListCommand).to receive(:prase)
50
+ allow(ListTool::App::AddListCommand).to receive(:execute)
51
+
52
+ subject.process(['al', 'list_name'], lister)
53
+ end
54
+
55
+ end
56
+
57
+ context 'failure' do
58
+
59
+ context 'when first argument is not an array' do
60
+ it 'raises ArgumentError' do
61
+ expect{ subject.process 'not_an_array', lister, printer }.to raise_error(ArgumentError)
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+
70
+ describe '.help' do
71
+ it 'returns a string' do
72
+ expect(subject.help).to be_a String
73
+ end
74
+
75
+ it 'gets help messages from all commands' do
76
+ ListTool::App::Commands::COMMANDS.each { |cmd| expect(cmd).to receive(:help).and_return("") }
77
+ subject.help
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,54 @@
1
+ require_relative '../../spec_helper.rb'
2
+
3
+ describe ListTool::App::Printer do
4
+ subject { ListTool::App::Printer }
5
+
6
+ describe '.error' do
7
+ it 'prints error message' do
8
+ expect(subject).to receive(:puts).with( "#{"ERROR".red}: some error\n" )
9
+ subject.error(StandardError.new('some error'))
10
+ end
11
+ end
12
+
13
+
14
+ describe '.print_items' do
15
+ it 'prints list of items with indexes (starting with 1)' do
16
+ expect(subject).to receive(:puts).with( "Printing #{'testlist'.green}:\n 1. item1\n 2. item2\n" )
17
+ subject.print_items( {name: 'testlist', items: ['item1', 'item2']} )
18
+ end
19
+ end
20
+
21
+
22
+ describe '.print_lists' do
23
+ it 'prints list of lists with indexes (starting with 1)' do
24
+ expect(subject).to receive(:puts).with( "Printing lists:\n 1. list1 (1)\n 2. list2 (2)\n" )
25
+ subject.print_lists( {'list1' => 1, 'list2' => 2} )
26
+ end
27
+ end
28
+
29
+
30
+ describe '.print_usage' do
31
+ it 'gets help messages from commands' do
32
+ allow( subject ).to receive(:puts)
33
+ ListTool::App::Commands::COMMANDS.each do |cmd|
34
+ expect(cmd).to receive(:help).and_return("")
35
+ end
36
+ subject.print_usage
37
+ end
38
+
39
+ it 'prints usage info' do
40
+ allow( ListTool::App::Commands::COMMANDS ).to receive(:each)
41
+ expect( subject ).to receive(:puts)
42
+ subject.print_usage
43
+ end
44
+ end
45
+
46
+
47
+ describe '.print_version' do
48
+ it 'prints version of program' do
49
+ expect( subject ).to receive(:puts).with("clt version #{ListTool::VERSION}")
50
+ subject.print_version
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,166 @@
1
+ require_relative '../../spec_helper.rb'
2
+
3
+ describe ListTool::App::Runner do
4
+ subject { ListTool::App::Runner.new }
5
+
6
+ describe '#initialize' do
7
+ it 'stores data directory path' do
8
+ expect( subject.instance_variable_get(:@datadir) ). to eq File.join(Dir.home, '.clt/')
9
+ end
10
+
11
+ it 'stores data file name' do
12
+ expect( subject.instance_variable_get(:@datafile) ). to eq 'data.json'
13
+ end
14
+
15
+ it 'stores lister' do
16
+ expect( subject.instance_variable_get(:@lister) ).to be_a ListTool::Lister
17
+ end
18
+ end
19
+
20
+
21
+ describe '#load_data' do
22
+ it 'loads data to lister' do
23
+ file = subject.send(:datafile_fullname)
24
+ expect( subject.instance_variable_get(:@lister) ).to receive(:load).with(file)
25
+ subject.send(:load_data)
26
+ end
27
+ end
28
+
29
+
30
+ describe '#ensure_data_dir' do
31
+ let (:dir) { subject.instance_variable_get(:@datadir) }
32
+
33
+ context "when data dir doesn't exist" do
34
+ context 'success' do
35
+ it 'creates data dir' do
36
+ allow(Dir).to receive(:exist?).with(dir).and_return(false)
37
+ expect(Dir).to receive(:mkdir).with(dir)
38
+ subject.send(:ensure_data_dir)
39
+ end
40
+ end
41
+
42
+ context 'failure' do
43
+ it 'raises SystemCallError' do
44
+ allow(Dir).to receive(:mkdir).and_raise( SystemCallError.new('some msg') )
45
+ allow(Dir).to receive(:exist?).with(dir).and_return(false)
46
+ expect{ subject.send(:ensure_data_dir) }.to raise_error(SystemCallError)
47
+ end
48
+ end
49
+ end
50
+
51
+ context 'when data dir exists' do
52
+ it 'does nothing' do
53
+ allow(Dir).to receive(:exist?).and_return(true)
54
+ expect(Dir).not_to receive(:mkdir)
55
+ subject.send(:ensure_data_dir)
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+
62
+ describe '#ensure_data_file' do
63
+ let(:file) { subject.send(:datafile_fullname) }
64
+
65
+ context "when data file doesn't exist" do
66
+
67
+ context 'success' do
68
+ it 'creates data file with initial(empty) data' do
69
+ allow(File).to receive(:exist?).with(file).and_return(false)
70
+ fake_datafile = double('file')
71
+ expect(File).to receive(:open).with(file, 'w').and_yield(fake_datafile)
72
+ expect(fake_datafile).to receive(:<<).with( '{"lists":[]}' )
73
+
74
+ subject.send(:ensure_data_file)
75
+ end
76
+ end
77
+
78
+ context 'failure' do
79
+ it 'raises SystemCallError' do
80
+ allow(File).to receive(:open).and_raise( SystemCallError.new('some msg') )
81
+ allow(File).to receive(:exist?).with(file).and_return(false)
82
+ expect{ subject.send(:ensure_data_file) }.to raise_error(SystemCallError)
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+
90
+ describe '#ensure_data' do
91
+ it 'calls "ensure_data_dir"' do
92
+ expect(subject).to receive(:ensure_data_dir)
93
+ allow(subject).to receive(:ensure_data_file)
94
+ subject.send(:ensure_data)
95
+ end
96
+
97
+ it 'calls "ensure_data_file"' do
98
+ allow(subject).to receive(:ensure_data_dir)
99
+ expect(subject).to receive(:ensure_data_file)
100
+ subject.send(:ensure_data)
101
+ end
102
+ end
103
+
104
+
105
+ describe '#datafile_fullname' do
106
+ it 'returns full datafile name' do
107
+ file = File.join(subject.instance_variable_get(:@datadir),subject.instance_variable_get(:@datafile))
108
+ expect(subject.send(:datafile_fullname)).to eq file
109
+ end
110
+ end
111
+
112
+
113
+ describe '#run' do
114
+ let (:lister) { subject.instance_variable_get(:@lister) }
115
+
116
+ context 'success' do
117
+ it 'ensures presence of data' do
118
+ expect( subject ).to receive(:ensure_data)
119
+ allow( subject ).to receive(:load_data)
120
+ allow( ListTool::App::Commands ).to receive(:process)
121
+ allow( lister ).to receive(:save)
122
+
123
+ subject.run ['argv']
124
+ end
125
+
126
+ it 'loads data' do
127
+ allow( subject ).to receive(:ensure_data)
128
+ expect( subject ).to receive(:load_data)
129
+ allow( ListTool::App::Commands ).to receive(:process)
130
+ allow( lister ).to receive(:save)
131
+
132
+ subject.run []
133
+ end
134
+
135
+ it 'starts command processing' do
136
+ allow( subject ).to receive(:ensure_data)
137
+ allow( subject ).to receive(:load_data)
138
+ expect( ListTool::App::Commands ).to receive(:process).with(['argv'], lister)
139
+ allow( lister ).to receive(:save)
140
+
141
+ subject.run ['argv']
142
+ end
143
+
144
+ it 'saves data' do
145
+ allow( subject ).to receive(:ensure_data)
146
+ allow( subject ).to receive(:load_data)
147
+ allow( ListTool::App::Commands ).to receive(:process)
148
+ expect( lister ).to receive(:save)
149
+
150
+ subject.run ['argv']
151
+ end
152
+ end
153
+
154
+ context 'failure' do
155
+ context 'when any of inner method calls ended with exception' do
156
+ it 'passes this exception to Printer.error' do
157
+ allow( subject ).to receive(:ensure_data).and_raise(error = StandardError)
158
+ expect( ListTool::App::Printer ).to receive(:error).with(error)
159
+
160
+ subject.run ['argv']
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ end
@@ -0,0 +1,32 @@
1
+ require_relative '../../spec_helper.rb'
2
+
3
+ describe String do
4
+
5
+ describe '#colorize' do
6
+ it 'colorizes string using given code' do
7
+ expect('test'.colorize(31)).to eq "\x1B[31mtest\x1B[0m"
8
+ end
9
+ end
10
+
11
+ describe '#red' do
12
+ it 'calls #colorize with 31' do
13
+ expect(string = 'test').to receive(:colorize).with(31)
14
+ string.red
15
+ end
16
+ end
17
+
18
+ describe '#green' do
19
+ it 'calls #colorize with 32' do
20
+ expect(string = 'test').to receive(:colorize).with(32)
21
+ string.green
22
+ end
23
+ end
24
+
25
+ describe '#blue' do
26
+ it 'calls #colorize with 34' do
27
+ expect(string = 'test').to receive(:colorize).with(34)
28
+ string.blue
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,257 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ describe Data do
4
+ let (:data) { ListTool::Data.new(Factory.data) }
5
+
6
+ describe '#initialize' do
7
+
8
+ context 'success' do
9
+ context 'from initial data' do
10
+ it "stores objects of List class" do
11
+ expect(data.lists[0]).to be_an_instance_of(ListTool::List)
12
+ end
13
+
14
+ it 'stores 2 lists' do
15
+ expect(data.lists.length).to eq 2
16
+ end
17
+
18
+ it 'stores default list' do
19
+ expect(data.default_list.name).to eq 'Todolist'
20
+ end
21
+ end
22
+
23
+ context 'no arguments' do
24
+ it 'creates new Data instance with empty array of lists' do
25
+ expect(ListTool::Data.new().lists).to be_empty
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ context 'failure' do
32
+ context 'argument is not a hash' do
33
+ it 'raises ArgumentError' do
34
+ expect{ListTool::Data.new('not_a_hash')}.to raise_error(ArgumentError)
35
+ end
36
+ end
37
+
38
+ context 'no "lists" key in given hash' do
39
+ it 'creates new Data instance with empty lists array' do
40
+ expect(ListTool::Data.new({}).lists).to be_empty
41
+ end
42
+ end
43
+
44
+ context '"lists" is not an array' do
45
+ it 'raises ArgumentError' do
46
+ expect{ListTool::Data.new("lists" => 'not_an_array')}.to raise_error(ArgumentError)
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+
54
+ describe '#add_list' do
55
+
56
+ context 'hash given' do
57
+ it 'adds new list to data' do
58
+ data.add_list(Factory.list)
59
+ expect(data.lists.length).to eq 3
60
+ end
61
+ end
62
+
63
+ context 'string given' do
64
+ it 'adds blank list with given name' do
65
+ data.add_list('Testlist')
66
+ expect(data.lists.last.name).to eq 'Testlist'
67
+ end
68
+ end
69
+
70
+ it 'returns list object' do
71
+ expect(data.add_list(Factory.list)).to be_an_instance_of(ListTool::List)
72
+ end
73
+
74
+ end
75
+
76
+
77
+ describe '#delete_list' do
78
+
79
+ context 'success' do
80
+ it 'removes list with given number' do
81
+ data.delete_list(1)
82
+ expect(data.lists.length).to eq 1
83
+ end
84
+
85
+ it 'returns deleted list' do
86
+ list = data.lists[1]
87
+ expect(data.delete_list(1)).to eq list
88
+ end
89
+
90
+ context 'default list is being deleted' do
91
+ it 'clears default list' do
92
+ data.delete_list(0)
93
+ expect(data.default_list).to be_nil
94
+ end
95
+ end
96
+ end
97
+
98
+ context 'no list with given index' do
99
+ it 'returns nil' do
100
+ expect(data.delete_list(2)).to be_nil
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+
107
+ describe '#rename_list' do
108
+
109
+ context 'success' do
110
+ it 'renames list with given index and returns old name' do
111
+ expect( data.lists[1] ).to receive(:rename).with('Testlist').and_return('Wishlist')
112
+ data.rename_list(1, 'Testlist')
113
+ end
114
+
115
+ it 'returns not nil' do
116
+ expect( data.rename_list(1, 'Testlist') ).not_to be_nil
117
+ end
118
+ end
119
+
120
+ context 'no list with given index' do
121
+ it 'returns nil' do
122
+ expect(data.rename_list(2, 'new_name')).to be_nil
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+
129
+ describe '#set_default_list' do
130
+
131
+ context 'success' do
132
+ it 'replaces default list' do
133
+ data.set_default_list(1)
134
+ expect(data.default_list).to eq data.lists[1]
135
+ end
136
+
137
+ it 'returns new defaut list' do
138
+ expect(data.set_default_list(1)).to eq data.lists[1]
139
+ end
140
+ end
141
+
142
+ context 'failure' do
143
+
144
+ context 'argument is not an integer' do
145
+ it 'raises ArgumentError' do
146
+ expect{data.set_default_list('bad_int')}.to raise_error(ArgumentError)
147
+ end
148
+ end
149
+
150
+ context 'no list with given index' do
151
+ it 'returns nil' do
152
+ expect(data.set_default_list(2)).to be_nil
153
+ end
154
+
155
+ it 'does not affect on default list' do
156
+ data.set_default_list(2)
157
+ expect(data.default_list).to eq data.lists[0]
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+
166
+ describe '#clear_list' do
167
+
168
+ context 'success' do
169
+ it 'clears list with given index' do
170
+ data.clear_list(0)
171
+ expect( data.lists[0].items ).to be_empty
172
+ end
173
+
174
+ it 'returns true' do
175
+ expect( data.clear_list(0) ).to be_truthy
176
+ end
177
+ end
178
+
179
+ context 'failure' do
180
+
181
+ context 'no list with given index' do
182
+ it 'returns nil' do
183
+ expect( data.clear_list(2) ).to be_nil
184
+ end
185
+ end
186
+
187
+ end
188
+ end
189
+
190
+
191
+ describe '#move_list' do
192
+
193
+ context 'success' do
194
+ it 'moves list up' do
195
+ data.move_list(1, :up)
196
+ expect(data.lists[0].name).to eq 'Wishlist'
197
+ end
198
+
199
+ it 'moves list down' do
200
+ data.move_list(0, :down)
201
+ expect(data.lists[1].name).to eq 'Todolist'
202
+ end
203
+
204
+ it 'returns not nil' do
205
+ expect( data.move_list(1, :up) ).not_to be_nil
206
+ end
207
+ end
208
+
209
+ context 'failure' do
210
+
211
+ context 'too high index' do
212
+ it 'does nothing when moving up' do
213
+ lists = data.lists.dup
214
+ data.move_list(2, :up)
215
+ expect(data.lists).to eq lists
216
+ end
217
+
218
+ it 'does nothing when moving down' do
219
+ lists = data.lists.dup
220
+ data.move_list(2, :down)
221
+ expect(data.lists).to eq lists
222
+ end
223
+ end
224
+
225
+ context 'too low index' do
226
+ it 'does nothing when moving up' do
227
+ lists = data.lists.dup
228
+ data.move_list(0, :up)
229
+ expect(data.lists).to eq lists
230
+ end
231
+
232
+ it 'does nothing when moving down' do
233
+ lists = data.lists.dup
234
+ data.move_list(-1, :down)
235
+ expect(data.lists).to eq lists
236
+ end
237
+ end
238
+
239
+ end
240
+
241
+ end
242
+
243
+
244
+ describe '#to_json' do
245
+ it 'returns correct json' do
246
+ expect(data.to_json).to eq Factory.json
247
+ end
248
+
249
+ context 'default list not set' do
250
+ it 'returns json without "default_list" field' do
251
+ data = ListTool::Data.new(Factory.blank_data)
252
+ expect(data.to_json).to eq '{"lists":[]}'
253
+ end
254
+ end
255
+ end
256
+
257
+ end
@@ -0,0 +1,84 @@
1
+ require_relative '../spec_helper.rb'
2
+
3
+ describe ListTool::FileManager do
4
+ let(:fm){ListTool::FileManager}
5
+
6
+ describe '.load' do
7
+
8
+ context 'success' do
9
+ it 'loads json from specified file' do
10
+ allow(File).to receive(:read).and_return('{"test":0}')
11
+ expect(fm.load('some_file')).to eq '{"test":0}'
12
+ end
13
+ end
14
+
15
+ context 'failure' do
16
+
17
+ context 'access denied to specified file' do
18
+ it 'raises FileAccessError' do
19
+ allow(File).to receive(:read).and_raise(Errno::EACCES)
20
+ expect{ fm.load('some_file') }.to raise_error(ListTool::FileAccessError)
21
+ end
22
+ end
23
+
24
+ context "file doesn't exist" do
25
+ it 'raises NoFileError' do
26
+ allow(File).to receive(:read).and_raise(Errno::ENOENT)
27
+ expect{ fm.load('some_file') }.to raise_error(ListTool::FileNotFoundError)
28
+ end
29
+ end
30
+
31
+ context 'unknown error' do
32
+ it 'raises IOError' do
33
+ allow(File).to receive(:read).and_raise(StandardError)
34
+ expect{ fm.load('some_file') }.to raise_error(IOError)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+
43
+ describe '.save' do
44
+ let(:filename){ "some_file" }
45
+ let(:data){ ListTool::Data.new }
46
+
47
+ context 'success' do
48
+ it 'saves given data to specified file' do
49
+ file = double('File')
50
+ allow(File).to receive(:open).with(filename, 'w').and_yield(file)
51
+ expect(file).to receive(:<<).with('{"lists":[]}')
52
+
53
+ ListTool::FileManager.save(filename, data)
54
+ end
55
+ end
56
+
57
+ context 'failure' do
58
+
59
+ context 'access denied to specified file' do
60
+ it 'raises FileAccessError' do
61
+ allow(File).to receive(:open).with(filename, 'w').and_raise(Errno::EACCES)
62
+ expect{ fm.save('some_file', data) }.to raise_error(ListTool::FileAccessError)
63
+ end
64
+ end
65
+
66
+ context "file doesn't exist" do
67
+ it 'raises NoFileError' do
68
+ allow(File).to receive(:open).with(filename, 'w').and_raise(Errno::ENOENT)
69
+ expect{ fm.save('some_file', data) }.to raise_error(ListTool::FileNotFoundError)
70
+ end
71
+ end
72
+
73
+ context 'unknown error' do
74
+ it 'raises IOError' do
75
+ allow(File).to receive(:open).with(filename, 'w').and_raise(StandardError)
76
+ expect{ fm.save('some_file', data) }.to raise_error(IOError)
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+ end