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