exel 1.2.1 → 1.3.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -4
  3. data/.rubocop_todo.yml +1 -13
  4. data/Gemfile +1 -0
  5. data/Guardfile +1 -0
  6. data/README.md +95 -30
  7. data/Rakefile +1 -0
  8. data/exel.gemspec +2 -2
  9. data/lib/exel.rb +6 -1
  10. data/lib/exel/ast_node.rb +4 -9
  11. data/lib/exel/context.rb +1 -0
  12. data/lib/exel/deferred_context_value.rb +1 -0
  13. data/lib/exel/error/job_termination.rb +9 -0
  14. data/lib/exel/events.rb +1 -0
  15. data/lib/exel/instruction.rb +3 -1
  16. data/lib/exel/instruction_node.rb +1 -0
  17. data/lib/exel/job.rb +1 -0
  18. data/lib/exel/listen_instruction.rb +1 -0
  19. data/lib/exel/logging.rb +22 -1
  20. data/lib/exel/logging/logger_wrapper.rb +28 -0
  21. data/lib/exel/logging_helper.rb +35 -0
  22. data/lib/exel/middleware/chain.rb +66 -0
  23. data/lib/exel/middleware/logging.rb +30 -0
  24. data/lib/exel/null_instruction.rb +1 -0
  25. data/lib/exel/processor_helper.rb +7 -0
  26. data/lib/exel/processors/async_processor.rb +2 -8
  27. data/lib/exel/processors/run_processor.rb +2 -7
  28. data/lib/exel/processors/split_processor.rb +5 -8
  29. data/lib/exel/providers/local_file_provider.rb +1 -0
  30. data/lib/exel/providers/threaded_async_provider.rb +1 -0
  31. data/lib/exel/sequence_node.rb +1 -0
  32. data/lib/exel/value.rb +1 -0
  33. data/lib/exel/version.rb +2 -1
  34. data/spec/exel/ast_node_spec.rb +24 -3
  35. data/spec/exel/context_spec.rb +1 -0
  36. data/spec/exel/deferred_context_value_spec.rb +1 -0
  37. data/spec/exel/events_spec.rb +1 -0
  38. data/spec/exel/instruction_node_spec.rb +1 -0
  39. data/spec/exel/instruction_spec.rb +6 -0
  40. data/spec/exel/job_spec.rb +1 -0
  41. data/spec/exel/listen_instruction_spec.rb +1 -0
  42. data/spec/exel/logging/logger_wrapper_spec.rb +95 -0
  43. data/spec/exel/logging_helper_spec.rb +25 -0
  44. data/spec/exel/logging_spec.rb +36 -3
  45. data/spec/exel/middleware/chain_spec.rb +67 -0
  46. data/spec/exel/middleware/logging_spec.rb +33 -0
  47. data/spec/exel/middleware_spec.rb +69 -0
  48. data/spec/exel/null_instruction_spec.rb +1 -0
  49. data/spec/exel/processors/async_processor_spec.rb +1 -0
  50. data/spec/exel/processors/run_processor_spec.rb +1 -0
  51. data/spec/exel/processors/split_processor_spec.rb +2 -7
  52. data/spec/exel/providers/local_file_provider_spec.rb +1 -0
  53. data/spec/exel/providers/threaded_async_provider_spec.rb +1 -0
  54. data/spec/exel/sequence_node_spec.rb +1 -0
  55. data/spec/exel/value_spec.rb +1 -0
  56. data/spec/exel_spec.rb +1 -0
  57. data/spec/integration/integration_spec.rb +1 -0
  58. data/spec/spec_helper.rb +1 -0
  59. data/spec/support/integration_test_classes.rb +1 -0
  60. metadata +18 -18
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module EXEL
3
+ describe LoggingHelper do
4
+ class HelperClass
5
+ include LoggingHelper
6
+ end
7
+
8
+ let(:helper) { HelperClass.new }
9
+
10
+ describe '#logger' do
11
+ it 'returns EXEL.logger' do
12
+ expect(helper.logger).to eq(EXEL.logger)
13
+ end
14
+ end
15
+
16
+ %i(debug info warn error fatal).each do |level|
17
+ describe "#log_#{level}" do
18
+ it "logs a #{level} message" do
19
+ expect(EXEL.logger).to receive(level).with('test')
20
+ helper.send("log_#{level}", 'test')
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,13 +1,33 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  describe Logging do
3
4
  before { @restore_logger = Logging.logger }
4
5
  after { Logging.logger = @restore_logger }
5
6
 
7
+ describe Logging::PrefixFormatter do
8
+ context 'without a Logging prefix' do
9
+ it 'formats the message' do
10
+ expect(subject.call('warn', Time.new(2007, 11, 1, 15, 25, 0, '+09:00'), 'test', 'message'))
11
+ .to eq("2007-11-01 06:25:00 UTC severity=warn, message\n")
12
+ end
13
+ end
14
+
15
+ context 'with a Logging prefix' do
16
+ it 'adds the prefix to the formatted message' do
17
+ Logging.with_prefix('[prefix] ') do
18
+ expect(subject.call('warn', Time.new(2007, 11, 1, 15, 25, 0, '+09:00'), 'test', 'message'))
19
+ .to eq("2007-11-01 06:25:00 UTC severity=warn, [prefix] message\n")
20
+ end
21
+ end
22
+ end
23
+ end
24
+
6
25
  describe '.logger=' do
7
- it 'sets a logger' do
8
- logger = double(:logger)
26
+ it 'sets a wrapped logger' do
27
+ logger = instance_double(Logger)
9
28
  Logging.logger = logger
10
- expect(Logging.logger).to be(logger)
29
+ expect(Logging.logger).to be_a(Logging::LoggerWrapper)
30
+ expect(Logging.logger.__getobj__).to be(logger)
11
31
  end
12
32
 
13
33
  it 'sets a null logger when nil given' do
@@ -28,9 +48,22 @@ module EXEL
28
48
  logger = instance_double(Logger)
29
49
  expect(Logger).to receive(:new).with('log.txt').and_return(logger)
30
50
  expect(logger).to receive(:level=).with(Logger::WARN)
51
+ expect(logger).to receive(:formatter=).with(Logging::PrefixFormatter)
31
52
 
32
53
  Logging.logger
33
54
  end
34
55
  end
56
+
57
+ describe '.with_prefix' do
58
+ it 'sets the prefix before yielding to the block and clears it after' do
59
+ expect(Logging.prefix).to be_nil
60
+
61
+ Logging.with_prefix('testing') do
62
+ expect(Logging.prefix).to eq('testing')
63
+ end
64
+
65
+ expect(Logging.prefix).to be_nil
66
+ end
67
+ end
35
68
  end
36
69
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ module EXEL
3
+ module Middleware
4
+ describe Chain do
5
+ subject(:chain) { EXEL::Middleware::Chain.new }
6
+
7
+ class TestMiddleware
8
+ def initialize(*)
9
+ end
10
+
11
+ def call
12
+ end
13
+ end
14
+
15
+ AnotherTestMiddleware = Class.new(TestMiddleware)
16
+
17
+ describe '#add' do
18
+ it 'adds a middleware to the chain' do
19
+ chain.add(TestMiddleware)
20
+ expect(chain).to include(TestMiddleware)
21
+ end
22
+
23
+ it 'removes and adds to end if already present' do
24
+ chain.add(TestMiddleware)
25
+ chain.add(AnotherTestMiddleware)
26
+ chain.add(TestMiddleware)
27
+ expect(chain.entries.map(&:klass)).to eq([AnotherTestMiddleware, TestMiddleware])
28
+ end
29
+ end
30
+
31
+ describe '#remove' do
32
+ it 'removes a middleware from the chain' do
33
+ chain.add(TestMiddleware)
34
+ chain.add(AnotherTestMiddleware)
35
+ chain.remove(TestMiddleware)
36
+ expect(chain.entries.map(&:klass)).to eq([AnotherTestMiddleware])
37
+ end
38
+ end
39
+
40
+ describe '#include?' do
41
+ it 'returns true if the middleware class is in the chain' do
42
+ chain.add(TestMiddleware)
43
+ expect(chain).to include(TestMiddleware)
44
+ end
45
+
46
+ it 'returns false if the middleware class is not in the chain' do
47
+ chain.add(TestMiddleware)
48
+ expect(chain).not_to include(AnotherTestMiddleware)
49
+ end
50
+ end
51
+
52
+ describe '#invoke' do
53
+ it 'calls each middleware' do
54
+ chain.add(TestMiddleware)
55
+ expect_any_instance_of(TestMiddleware).to receive(:call).with(1, 2, 3)
56
+ chain.invoke(1, 2, 3)
57
+ end
58
+
59
+ it 'initializes middleware with given constructor arguments' do
60
+ chain.add(TestMiddleware, 1, 2)
61
+ expect(TestMiddleware).to receive(:new).with(1, 2).and_return(TestMiddleware.new)
62
+ chain.invoke
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module EXEL
3
+ module Middleware
4
+ describe Logging do
5
+ TestProcessor = Class.new
6
+
7
+ describe '#call' do
8
+ it 'yields to the given block' do
9
+ called = false
10
+
11
+ subject.call(Object, {}, {}) do
12
+ called = true
13
+ end
14
+
15
+ expect(called).to be_truthy
16
+ end
17
+
18
+ it 'logs with context[:log_prefix] and the processor class as the prefix' do
19
+ expect(EXEL::Logging).to receive(:with_prefix).with('[prefix][EXEL::Middleware::TestProcessor] ')
20
+ subject.call(TestProcessor, {log_prefix: '[prefix]'}, {}) {}
21
+ end
22
+
23
+ it 'raises rescued exceptions' do
24
+ expect do
25
+ subject.call(Object, {}, {}) do
26
+ raise Exception, 're-raise me'
27
+ end
28
+ end.to raise_error Exception, 're-raise me'
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ module EXEL
3
+ describe Middleware do
4
+ class IORecorder
5
+ def initialize(input, output)
6
+ @input = input
7
+ @output = output
8
+ end
9
+
10
+ def call(_processor, context, args)
11
+ @input << args[:input]
12
+ yield
13
+ @output << context[:output]
14
+ end
15
+ end
16
+
17
+ class RescueErrors
18
+ def call(_processor, _context, _args)
19
+ yield
20
+ rescue
21
+ nil
22
+ end
23
+ end
24
+
25
+ class AddProcessor
26
+ def initialize(context)
27
+ @context = context
28
+ end
29
+
30
+ def process(_)
31
+ @context[:output] = @context[:input] + 1
32
+ raise 'rescue me'
33
+ end
34
+ end
35
+
36
+ before :all do
37
+ EXEL::Job.define :middleware_test_job do
38
+ process with: AddProcessor, input: 1
39
+ end
40
+ end
41
+
42
+ let(:input) { [] }
43
+ let(:output) { [] }
44
+
45
+ before do
46
+ EXEL.configure do |config|
47
+ config.middleware.add(IORecorder, input, output)
48
+ config.middleware.add(RescueErrors)
49
+ end
50
+ end
51
+
52
+ after do
53
+ EXEL.configure do |config|
54
+ config.middleware.remove(IORecorder)
55
+ config.middleware.remove(RescueErrors)
56
+ end
57
+ end
58
+
59
+ it 'can configure custom middleware' do
60
+ expect(EXEL.configuration.middleware.entries.map(&:klass)).to eq([IORecorder, RescueErrors])
61
+ end
62
+
63
+ it 'invokes the middleware around the processor' do
64
+ EXEL::Job.run(:middleware_test_job)
65
+ expect(input).to eq([1])
66
+ expect(output).to eq([2])
67
+ end
68
+ end
69
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  describe NullInstruction do
3
4
  it { is_expected.to respond_to :execute }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  module Processors
3
4
  describe AsyncProcessor do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  module Processors
3
4
  describe RunProcessor do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  module Processors
3
4
  describe SplitProcessor do
@@ -82,13 +83,7 @@ module EXEL
82
83
  end
83
84
 
84
85
  def create_file(lines)
85
- content = ''
86
-
87
- lines.times do |i|
88
- line = CSV.generate_line(["line#{i}"])
89
- content << line
90
- end
91
-
86
+ content = Array.new(lines) { |i| CSV.generate_line(["line#{i}"]) }.join
92
87
  StringIO.new(content)
93
88
  end
94
89
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  module Providers
3
4
  describe LocalFileProvider do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  module Providers
3
4
  class ContextMutatingProcessor
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  describe SequenceNode do
3
4
  subject(:node) { described_class.new(instance_double(ASTNode), instance_double(ASTNode)) }
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module EXEL
2
3
  describe Value do
3
4
  let(:uri) { 's3://test_file.csv' }
data/spec/exel_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  describe EXEL do
2
3
  describe '.async_provider' do
3
4
  context 'with no async provider set in the configuration' do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  describe EXEL do
2
3
  let(:context) { EXEL::Context.new(resource: csv_file, email_service: email_service, delete_resource: false) }
3
4
  let(:csv_file) { File.open(File.expand_path('../../fixtures/sample.csv', __FILE__)) }
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'codeclimate-test-reporter'
2
3
  CodeClimate::TestReporter.start
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  Person = Struct.new(:name, :email)
2
3
 
3
4
  class RecordLoader
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yroo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-21 00:00:00.000000000 Z
11
+ date: 2016-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,28 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.37.0
131
+ version: 0.39.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.37.0
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop-rspec
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '1'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '1'
138
+ version: 0.39.0
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rubocop-rspec-focused
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -207,6 +193,10 @@ files:
207
193
  - lib/exel/job.rb
208
194
  - lib/exel/listen_instruction.rb
209
195
  - lib/exel/logging.rb
196
+ - lib/exel/logging/logger_wrapper.rb
197
+ - lib/exel/logging_helper.rb
198
+ - lib/exel/middleware/chain.rb
199
+ - lib/exel/middleware/logging.rb
210
200
  - lib/exel/null_instruction.rb
211
201
  - lib/exel/processor_helper.rb
212
202
  - lib/exel/processors/async_processor.rb
@@ -225,7 +215,12 @@ files:
225
215
  - spec/exel/instruction_spec.rb
226
216
  - spec/exel/job_spec.rb
227
217
  - spec/exel/listen_instruction_spec.rb
218
+ - spec/exel/logging/logger_wrapper_spec.rb
219
+ - spec/exel/logging_helper_spec.rb
228
220
  - spec/exel/logging_spec.rb
221
+ - spec/exel/middleware/chain_spec.rb
222
+ - spec/exel/middleware/logging_spec.rb
223
+ - spec/exel/middleware_spec.rb
229
224
  - spec/exel/null_instruction_spec.rb
230
225
  - spec/exel/processors/async_processor_spec.rb
231
226
  - spec/exel/processors/run_processor_spec.rb
@@ -272,7 +267,12 @@ test_files:
272
267
  - spec/exel/instruction_spec.rb
273
268
  - spec/exel/job_spec.rb
274
269
  - spec/exel/listen_instruction_spec.rb
270
+ - spec/exel/logging/logger_wrapper_spec.rb
271
+ - spec/exel/logging_helper_spec.rb
275
272
  - spec/exel/logging_spec.rb
273
+ - spec/exel/middleware/chain_spec.rb
274
+ - spec/exel/middleware/logging_spec.rb
275
+ - spec/exel/middleware_spec.rb
276
276
  - spec/exel/null_instruction_spec.rb
277
277
  - spec/exel/processors/async_processor_spec.rb
278
278
  - spec/exel/processors/run_processor_spec.rb