exel 1.1.0 → 1.2.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.rubocop_todo.yml +10 -16
  4. data/Gemfile +2 -0
  5. data/README.md +5 -2
  6. data/exel.gemspec +2 -1
  7. data/lib/exel/ast_node.rb +2 -1
  8. data/lib/exel/context.rb +45 -42
  9. data/lib/exel/deferred_context_value.rb +35 -0
  10. data/lib/exel/error/job_termination.rb +3 -5
  11. data/lib/exel/events.rb +26 -0
  12. data/lib/exel/instruction.rb +2 -4
  13. data/lib/exel/instruction_node.rb +1 -0
  14. data/lib/exel/job.rb +32 -10
  15. data/lib/exel/listen_instruction.rb +17 -0
  16. data/lib/exel/null_instruction.rb +1 -0
  17. data/lib/exel/old_context.rb +109 -0
  18. data/lib/exel/processor_helper.rb +1 -4
  19. data/lib/exel/processors/async_processor.rb +1 -0
  20. data/lib/exel/processors/run_processor.rb +3 -0
  21. data/lib/exel/processors/split_processor.rb +12 -2
  22. data/lib/exel/providers/local_file_provider.rb +3 -1
  23. data/lib/exel/providers/threaded_async_provider.rb +1 -0
  24. data/lib/exel/sequence_node.rb +1 -0
  25. data/lib/exel/value.rb +1 -0
  26. data/lib/exel/version.rb +1 -1
  27. data/lib/exel.rb +20 -1
  28. data/spec/exel/ast_node_spec.rb +4 -4
  29. data/spec/exel/context_spec.rb +35 -109
  30. data/spec/exel/deferred_context_value_spec.rb +51 -7
  31. data/spec/exel/events_spec.rb +89 -0
  32. data/spec/exel/instruction_node_spec.rb +3 -3
  33. data/spec/exel/instruction_spec.rb +9 -9
  34. data/spec/exel/job_spec.rb +23 -13
  35. data/spec/exel/listen_instruction_spec.rb +14 -0
  36. data/spec/exel/logging_spec.rb +3 -3
  37. data/spec/exel/processors/split_processor_spec.rb +14 -6
  38. data/spec/exel/sequence_node_spec.rb +1 -1
  39. data/spec/exel_spec.rb +7 -0
  40. data/spec/fixtures/sample.csv +501 -0
  41. data/spec/integration/integration_spec.rb +51 -0
  42. data/spec/spec_helper.rb +17 -1
  43. data/spec/support/integration_test_classes.rb +44 -0
  44. metadata +32 -5
@@ -128,15 +128,13 @@ module EXEL
128
128
 
129
129
  describe '#process' do
130
130
  let(:block) { proc {} }
131
+ let(:processor_class) { class_double(Class) }
131
132
 
132
- before do
133
- allow(Job::Parser).to receive(:parse).and_return(ast)
134
- end
133
+ before { allow(Job::Parser).to receive(:parse).and_return(ast) }
135
134
 
136
135
  context 'without a block' do
137
136
  it 'creates a process instruction' do
138
- processor_class = double(:processor_class)
139
- expect(Instruction).to receive(:new).with('process', processor_class, {arg1: 'arg1_value'}, nil)
137
+ expect(Instruction).to receive(:new).with(processor_class, {arg1: 'arg1_value'}, nil)
140
138
 
141
139
  parser.process with: processor_class, arg1: 'arg1_value'
142
140
  end
@@ -144,19 +142,17 @@ module EXEL
144
142
  it 'appends an instruction node to the AST with no children' do
145
143
  expect(parser.ast).to receive(:add_child) do |node|
146
144
  expect(node).to be_a_kind_of(InstructionNode)
147
- expect(node.instruction.name).to eq('process')
148
145
  expect(node.children).to eq([])
149
146
  end
150
147
 
151
- parser.process with: double(:processor_class)
148
+ parser.process with: processor_class
152
149
  end
153
150
  end
154
151
 
155
152
  context 'with a block' do
156
153
  it 'passes the parsed subtree to the instruction' do
157
- processor_class = double(:processor_class)
158
154
  expect(Job::Parser).to receive(:parse).with(block).and_return(ast)
159
- expect(Instruction).to receive(:new).with('process', processor_class, {arg1: 'arg1_value'}, ast)
155
+ expect(Instruction).to receive(:new).with(processor_class, {arg1: 'arg1_value'}, ast)
160
156
 
161
157
  parser.process with: processor_class, arg1: 'arg1_value', &block
162
158
  end
@@ -164,11 +160,10 @@ module EXEL
164
160
  it 'appends an instruction node to the AST with the parsed block as its subtree' do
165
161
  expect(parser.ast).to receive(:add_child) do |node|
166
162
  expect(node).to be_a_kind_of(InstructionNode)
167
- expect(node.instruction.name).to eq('process')
168
163
  expect(node.children).to eq([ast])
169
164
  end
170
165
 
171
- parser.process with: double(:processor_class), &block
166
+ parser.process with: processor_class, &block
172
167
  end
173
168
  end
174
169
  end
@@ -184,7 +179,7 @@ module EXEL
184
179
  end
185
180
 
186
181
  it "creates a #{data[:method]} instruction" do
187
- expect(Instruction).to receive(:new).with(data[:method].to_s, data[:processor], {arg1: 'arg1_value'}, ast)
182
+ expect(Instruction).to receive(:new).with(data[:processor], {arg1: 'arg1_value'}, ast)
188
183
  parser.send(data[:method], arg1: 'arg1_value') {}
189
184
  end
190
185
 
@@ -198,7 +193,6 @@ module EXEL
198
193
  it 'adds parsed subtree and instruction to the AST' do
199
194
  expect(parser.ast).to receive(:add_child) do |node|
200
195
  expect(node).to be_a_kind_of(InstructionNode)
201
- expect(node.instruction.name).to eq(data[:method].to_s)
202
196
  expect(node.children).to eq([ast])
203
197
  end
204
198
 
@@ -212,5 +206,21 @@ module EXEL
212
206
  expect(parser.context).to be_a_kind_of(DeferredContextValue)
213
207
  end
214
208
  end
209
+
210
+ describe '#listen' do
211
+ let(:listener_class) { class_double(Class) }
212
+
213
+ it 'creates a listen instruction' do
214
+ expect(ListenInstruction).to receive(:new).with(:event, listener_class)
215
+ parser.listen for: :event, with: listener_class
216
+ end
217
+
218
+ it 'adds an InstructionNode containing the listen instruction' do
219
+ parser.listen for: :event, with: listener_class
220
+ node = parser.ast.children.first
221
+ expect(node).to be_a_kind_of(InstructionNode)
222
+ expect(node.instruction).to be_a_kind_of(ListenInstruction)
223
+ end
224
+ end
215
225
  end
216
226
  end
@@ -0,0 +1,14 @@
1
+ module EXEL
2
+ describe ListenInstruction do
3
+ subject(:instruction) { EXEL::ListenInstruction.new(:event, listener) }
4
+ let(:listener) { double(:listener) }
5
+ let(:context) { EXEL::Context.new }
6
+
7
+ describe '#execute' do
8
+ it 'registers the event listener' do
9
+ expect(instruction).to receive(:register_listener).with(context, :event, listener)
10
+ instruction.execute(context)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,13 +4,13 @@ module EXEL
4
4
  after { Logging.logger = @restore_logger }
5
5
 
6
6
  describe '.logger=' do
7
- it 'should set a logger' do
7
+ it 'sets a logger' do
8
8
  logger = double(:logger)
9
9
  Logging.logger = logger
10
10
  expect(Logging.logger).to be(logger)
11
11
  end
12
12
 
13
- it 'should set a null logger when nil given' do
13
+ it 'sets a null logger when nil given' do
14
14
  expect(Logger).to receive(:new).with('/dev/null')
15
15
  Logging.logger = nil
16
16
  end
@@ -19,7 +19,7 @@ module EXEL
19
19
  describe '.logger' do
20
20
  before { Logging.instance_variable_set(:@logger, nil) }
21
21
 
22
- it 'should initialize the logger on first read if not already set' do
22
+ it 'initializes the logger on first read if not already set' do
23
23
  EXEL.configure do |config|
24
24
  config.log_level = :warn
25
25
  config.log_filename = 'log.txt'
@@ -15,7 +15,7 @@ module EXEL
15
15
  describe '#process' do
16
16
  let(:file) { create_file(3) }
17
17
 
18
- it 'should process file with 3 lines line by line' do
18
+ it 'processes file with 3 lines line by line' do
19
19
  allow(CSV).to receive(:foreach).and_yield('line0').and_yield('line1').and_yield('line2')
20
20
 
21
21
  3.times do |i|
@@ -28,12 +28,20 @@ module EXEL
28
28
  splitter.process(callback)
29
29
  end
30
30
 
31
- it 'should abort parsing the csv file if it is malformed' do
31
+ it 'aborts parsing the csv file if it is malformed' do
32
32
  allow(CSV).to receive(:foreach).and_raise(CSV::MalformedCSVError)
33
33
  expect(splitter).to receive(:process_line).with(:eof, callback)
34
34
 
35
35
  splitter.process(callback)
36
36
  end
37
+
38
+ it 'does not delete the resource file if :delete_resource is set to false in the context' do
39
+ allow(CSV).to receive(:foreach).and_yield(:eof)
40
+ expect(File).not_to receive(:delete).with(file.path)
41
+
42
+ context[:delete_resource] = false
43
+ splitter.process(callback)
44
+ end
37
45
  end
38
46
 
39
47
  describe '#process_line' do
@@ -42,8 +50,8 @@ module EXEL
42
50
  {input: 3, chunks: %W(0\n1\n 2\n)},
43
51
  {input: 4, chunks: %W(0\n1\n 2\n3\n)}
44
52
  ].each do |data|
45
- it "should produce #{data[:chunks].size} chunks with #{data[:input]} input lines" do
46
- allow(splitter).to receive(:chunk_size).and_return(2)
53
+ it "produces #{data[:chunks].size} chunks with #{data[:input]} input lines" do
54
+ context[:chunk_size] = 2
47
55
 
48
56
  data[:chunks].each do |chunk|
49
57
  expect(splitter).to receive(:generate_chunk).with(chunk).and_return(chunk_file)
@@ -59,13 +67,13 @@ module EXEL
59
67
  end
60
68
 
61
69
  describe '#generate_chunk' do
62
- it 'should create a file with the contents of the given string' do
70
+ it 'creates a file with the contents of the given string' do
63
71
  file = splitter.generate_chunk('abc')
64
72
  content = file.read
65
73
  expect(content).to eq('abc')
66
74
  end
67
75
 
68
- it 'should create a file with a unique name' do
76
+ it 'creates a file with a unique name' do
69
77
  3.times do |i|
70
78
  file = splitter.generate_chunk('content')
71
79
  expect(file.path).to include("text_#{i + 1}_")
@@ -6,7 +6,7 @@ module EXEL
6
6
  it { is_expected.to be_an(ASTNode) }
7
7
 
8
8
  describe '#run' do
9
- it 'should run each child node in sequence' do
9
+ it 'runs each child node in sequence' do
10
10
  expect(node.children.first).to receive(:run).with(context).once.ordered
11
11
  expect(node.children.last).to receive(:run).with(context).once.ordered
12
12
 
data/spec/exel_spec.rb CHANGED
@@ -38,4 +38,11 @@ describe EXEL do
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ after :each do
43
+ EXEL.configure do |config|
44
+ config.remote_provider = nil # reset providers to default
45
+ config.async_provider = nil
46
+ end
47
+ end
41
48
  end