darlingtonia 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cce55d5fc4915436a8e73be35f5944c46072a888
4
- data.tar.gz: 70ca3ece0257d1d613c6986088ffbe7eddafe433
2
+ SHA256:
3
+ metadata.gz: 4b822b291286cddbaf96726161ebfaf758f9491743d4b4daaf78a04182ef4ffe
4
+ data.tar.gz: 2c0ff5b15a5e1875acf7586754e52c79495c388f2efdde899047f372a01ca778
5
5
  SHA512:
6
- metadata.gz: 705a826ca99966be26ec62c93e68c36c6ffe30ac8639f7bc61eeb023f23134506051f6f8f22fe924e8c59126d42df03ab7d7e3936c9f4e5e53f6c9804bdd2bcb
7
- data.tar.gz: de85779f43db76264fa8b444066478321f915c51469674e4f60ff6d0cf8a7fad06e07bdd3d4b0881484273d870a6a60554e3ff47d2397561c275aae290ac949a
6
+ metadata.gz: 87891bbce7ba7f2c27d3f9a4394885ea0d8d142baf519daacd67ab2323b6b99da984458cf92457c3a469ebb137b8ff146f74f14e480ea6eeceb03f4842c58242
7
+ data.tar.gz: 27d66a21d1f8600cf177e31289a866d864a6f2df1106be8af42ae7b7ef4adb641915085f19fc70ab666fd126cfa8f8f026c8b948f473e61e33750696dd212530
@@ -7,11 +7,14 @@ AllCops:
7
7
  Lint/HandleExceptions:
8
8
  Exclude:
9
9
  - 'spec/**/*'
10
+ - 'lib/darlingtonia/spec/**/*'
10
11
 
11
12
  Metrics/BlockLength:
12
13
  Exclude:
13
14
  - 'spec/**/*'
15
+ - 'lib/darlingtonia/spec/**/*'
14
16
 
15
17
  RSpec/DescribeClass:
16
18
  Exclude:
17
19
  - 'spec/integration/**/*'
20
+ - 'spec/*_spec.rb'
@@ -1,3 +1,10 @@
1
+ 1.1.0 - Fri Mar 30, 2018
2
+ ------------------------
3
+
4
+ Formatted message stream.
5
+
6
+ - Adds a formatted message stream to wrap other streams in a formatter.
7
+
1
8
  1.0.0 - Mon Jan 29, 2018
2
9
  ------------------------
3
10
 
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  Darlingtonia
2
2
  ============
3
+ [![Build Status](https://travis-ci.org/curationexperts/darlingtonia.svg?branch=master)](https://travis-ci.org/curationexperts/darlingtonia)
4
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/darlingtonia)
3
5
 
4
- Object import for Hyrax.
6
+ Object import for Hyrax. See the [API documentation](https://www.rubydoc.info/gems/darlingtonia) for more
7
+ information.
5
8
 
6
9
  Usage
7
10
  -----
@@ -18,9 +21,12 @@ with your `Hyrax` application. You need to provide a `Parser` (out of the box, w
18
21
  import with `CsvParser`).
19
22
 
20
23
  ```ruby
21
- parser = Darlingtonia::CsvParser.new(file: File.open('path/to/import.csv'))
24
+ file = File.open('path/to/import.csv')
25
+ parser = Darlingtonia::CsvParser.new(file: file)
22
26
 
23
27
  Darlingtonia::Importer.new(parser: parser).import
28
+
29
+ file.close # unless a block is passed to File.open, the file must be explicitly closed
24
30
  ```
25
31
 
26
32
  Development
@@ -33,3 +39,9 @@ cd darlingtonia
33
39
  bundle install
34
40
  bundle exec rake ci
35
41
  ```
42
+
43
+ ### RSpec Support
44
+
45
+ This gem ships with RSpec shared examples and other support tools intended to ease testing and ensure
46
+ interoperability of client code. These can be included by adding `require 'darlingtonia/spec'` to a
47
+ `spec_helper.rb` or `rails_helper.rb` file in your application's test suite.
@@ -1,14 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_fedora'
4
-
5
3
  ##
6
- # Bulk object import for Hyrax.
4
+ # Bulk object import for Samvera.
5
+ #
6
+ # == Importers
7
+ #
8
+ # {Importer} is the core class for importing records using {Darlingtonia}.
9
+ # Importers accept a {Parser} and (optionally) a custom {RecordImporter}, and
10
+ # process each record in the given parser (see: {Parser#records}).
11
+ #
12
+ # @example Importing in bulk from a file
13
+ # parser = Darlingtonia::Parser.for(file: File.new('path/to/file.ext'))
14
+ #
15
+ # Darlingtonia::Importer.new(parser: parser).import if parser.validate
7
16
  #
8
17
  # @example A basic configuration
9
18
  # Darlingtonia.config do |config|
10
- # # error streams must respond to `#<<`
19
+ # # error/info streams must respond to `#<<`
11
20
  # config.default_error_stream = MyErrorStream.new
21
+ # config.default_info_stream = STDOUT
12
22
  # end
13
23
  #
14
24
  module Darlingtonia
@@ -1,6 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Darlingtonia
4
+ ##
5
+ # The chief entry point for bulk import of records. `Importer` accepts a
6
+ # {Parser} on initialization and iterates through its {Parser#records}, importing
7
+ # each using a given {RecordImporter}.
8
+ #
9
+ # @example Importing in bulk from a CSV file
10
+ # parser = Darlingtonia::Parser.for(file: File.new('path/to/import.csv'))
11
+ #
12
+ # Darlingtonia::Importer.new(parser: parser).import if parser.validate
13
+ #
4
14
  class Importer
5
15
  extend Forwardable
6
16
 
@@ -17,13 +27,18 @@ module Darlingtonia
17
27
  def_delegator :parser, :records, :records
18
28
 
19
29
  ##
20
- # @param parser [Parser]
30
+ # @param parser [Parser] The parser to use as the source for import
31
+ # records.
32
+ # @param record_importer [RecordImporter] An object to handle import of
33
+ # each record
21
34
  def initialize(parser:, record_importer: RecordImporter.new)
22
35
  self.parser = parser
23
36
  self.record_importer = record_importer
24
37
  end
25
38
 
26
39
  ##
40
+ # Import each record in {#records}.
41
+ #
27
42
  # @return [void]
28
43
  def import
29
44
  records.each { |record| record_importer.import(record: record) }
@@ -1,6 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Darlingtonia
4
+ ##
5
+ # @example Building an importer with the factory
6
+ # record = InputRecord.from({some: :metadata}, mapper: MyMapper.new)
7
+ # record.some # => :metadata
8
+ #
4
9
  class InputRecord
5
10
  ##
6
11
  # @!attribute [rw] mapper
@@ -8,13 +13,18 @@ module Darlingtonia
8
13
  attr_accessor :mapper
9
14
 
10
15
  ##
11
- # @param metadata [Object]
12
- # @param mapper [#map_fields]
16
+ # @param mapper [#map_fields]
13
17
  def initialize(mapper: HashMapper.new)
14
18
  self.mapper = mapper
15
19
  end
16
20
 
17
21
  class << self
22
+ ##
23
+ # @param metadata [Object]
24
+ # @param mapper [#map_fields]
25
+ #
26
+ # @return [InputRecord] an input record mapping metadata with the given
27
+ # mapper
18
28
  def from(metadata:, mapper: HashMapper.new)
19
29
  mapper.metadata = metadata
20
30
  new(mapper: mapper)
@@ -36,7 +36,6 @@ module Darlingtonia
36
36
  #
37
37
  # mapper.fields.map { |field| mapper.send(field) }
38
38
  #
39
- #
40
39
  # @see ImportRecord#attributes for the canonical usage of a `MetadataMapper`.
41
40
  # @see HashMapper for an example implementation with dynamically generated
42
41
  # fields
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darlingtonia
4
+ ##
5
+ # RSpec test support for {Darlingtonia} importers.
6
+ #
7
+ # @see https://relishapp.com/rspec/rspec-core/docs/
8
+ module Spec
9
+ require 'darlingtonia/spec/shared_examples/a_mapper'
10
+ require 'darlingtonia/spec/shared_examples/a_message_stream'
11
+ require 'darlingtonia/spec/shared_examples/a_parser'
12
+ require 'darlingtonia/spec/shared_examples/a_validator'
13
+ require 'darlingtonia/spec/fakes/fake_parser'
14
+ end
15
+ end
@@ -14,8 +14,6 @@ class FakeParser < Darlingtonia::Parser
14
14
  end
15
15
  end
16
16
 
17
- require 'support/shared_examples/a_parser'
18
-
19
17
  # rubocop:disable RSpec/FilePath
20
18
  describe FakeParser do
21
19
  it_behaves_like 'a Darlingtonia::Parser' do
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples 'a Darlingtonia::MessageStream' do
4
+ describe '#<<' do
5
+ it { is_expected.to respond_to(:<<) }
6
+
7
+ it 'accepts a string argument' do
8
+ expect { stream << 'some string' }.not_to raise_error
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Darlingtonia
4
+ ##
5
+ # A message stream that formats a message before forwarding it to an
6
+ # underlying {#stream} (STDOUT by default). Messages are formatted using
7
+ # the `#%` method; the formatter can be a string format specification like
8
+ # "Message received: %s".
9
+ #
10
+ # @example Using a simple formatter
11
+ # formatter = "Message received: %s\n"
12
+ # stream = Darlingtonia::FormattedMessageStream.new(formatter: formatter)
13
+ #
14
+ # stream << "a message"
15
+ # # Message received: a message
16
+ # # => #<IO:<STDOUT>>
17
+ #
18
+ # @example A more complex formatter use case
19
+ # class MyFormatter
20
+ # def %(arg)
21
+ # "#{Time.now}: %s\n" % arg
22
+ # end
23
+ # end
24
+ #
25
+ # formatter = MyFormatter.new
26
+ # stream = Darlingtonia::FormattedMessageStream.new(formatter: formatter)
27
+ #
28
+ # stream << 'a message'
29
+ # # 2018-02-02 16:10:52 -0800: a message
30
+ # # => #<IO:<STDOUT>>
31
+ #
32
+ # stream << 'another message'
33
+ # # 2018-02-02 16:10:55 -0800: another message
34
+ # # => #<IO:<STDOUT>>
35
+ #
36
+ class FormattedMessageStream
37
+ ##
38
+ # @!attribute [rw] formatter
39
+ # @return [#%] A format specification
40
+ # @see https://ruby-doc.org/core-2.4.0/String.html#method-i-25
41
+ # @!attribute [rw] stream
42
+ # @return [#<<] an underlying stream to forward messages to after
43
+ # formatting
44
+ attr_accessor :formatter, :stream
45
+
46
+ ##
47
+ # @param formatter [#%] A format specification
48
+ # @param stream [#<<] an underlying stream to forward messages to after
49
+ # formatting
50
+ #
51
+ # @see https://ruby-doc.org/core-2.4.0/String.html#method-i-25
52
+ def initialize(stream: STDOUT, formatter: "%s\n")
53
+ self.formatter = formatter
54
+ self.stream = stream
55
+ end
56
+
57
+ ##
58
+ def <<(msg)
59
+ stream << format_message(msg)
60
+ end
61
+
62
+ ##
63
+ # @param msg [#to_s]
64
+ #
65
+ # @return [String] the input, cast to a string and formatted using
66
+ def format_message(msg)
67
+ formatter % msg
68
+ end
69
+ end
70
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Darlingtonia
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'darlingtonia/streams/formatted_message_stream'
5
+
6
+ describe Darlingtonia::FormattedMessageStream do
7
+ subject(:stream) { described_class.new(stream: fake_stream) }
8
+ let(:fake_stream) { [] }
9
+
10
+ it_behaves_like 'a Darlingtonia::MessageStream'
11
+
12
+ describe '#stream' do
13
+ subject(:stream) { described_class.new }
14
+
15
+ it 'is STDOUT by default' do
16
+ expect(stream.stream).to eq STDOUT
17
+ end
18
+ end
19
+
20
+ describe '#<<' do
21
+ it 'appends newlines by default' do
22
+ expect { stream << 'moomin' }
23
+ .to change { fake_stream }
24
+ .to contain_exactly("moomin\n")
25
+ end
26
+
27
+ it 'uses other % formatters' do
28
+ stream.formatter = "!!!%s!!!"
29
+
30
+ expect { stream << 'moomin' }
31
+ .to change { fake_stream }
32
+ .to contain_exactly('!!!moomin!!!')
33
+ end
34
+ end
35
+ end
@@ -4,8 +4,10 @@ require 'pry' unless ENV['CI']
4
4
  ENV['environment'] ||= 'test'
5
5
 
6
6
  require 'bundler/setup'
7
+ require 'active_fedora'
7
8
  require 'active_fedora/cleaner'
8
9
  require 'darlingtonia'
10
+ require 'darlingtonia/spec'
9
11
 
10
12
  Dir['./spec/support/**/*.rb'].each { |f| require f }
11
13
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'STDOUT as a MessageStream' do
6
+ subject(:stream) { STDOUT }
7
+
8
+ it_behaves_like 'a Darlingtonia::MessageStream'
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: darlingtonia
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Johnson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-01-29 00:00:00.000000000 Z
12
+ date: 2018-12-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: active-fedora
@@ -152,12 +152,20 @@ files:
152
152
  - lib/darlingtonia/parser.rb
153
153
  - lib/darlingtonia/parsers/csv_parser.rb
154
154
  - lib/darlingtonia/record_importer.rb
155
+ - lib/darlingtonia/spec.rb
156
+ - lib/darlingtonia/spec/fakes/fake_parser.rb
157
+ - lib/darlingtonia/spec/shared_examples/a_mapper.rb
158
+ - lib/darlingtonia/spec/shared_examples/a_message_stream.rb
159
+ - lib/darlingtonia/spec/shared_examples/a_parser.rb
160
+ - lib/darlingtonia/spec/shared_examples/a_validator.rb
161
+ - lib/darlingtonia/streams/formatted_message_stream.rb
155
162
  - lib/darlingtonia/validator.rb
156
163
  - lib/darlingtonia/validators/csv_format_validator.rb
157
164
  - lib/darlingtonia/validators/title_validator.rb
158
165
  - lib/darlingtonia/version.rb
159
166
  - spec/darlingtonia/csv_format_validator_spec.rb
160
167
  - spec/darlingtonia/csv_parser_spec.rb
168
+ - spec/darlingtonia/formatted_message_stream_spec.rb
161
169
  - spec/darlingtonia/hash_mapper_spec.rb
162
170
  - spec/darlingtonia/importer_spec.rb
163
171
  - spec/darlingtonia/input_record_spec.rb
@@ -171,11 +179,8 @@ files:
171
179
  - spec/fixtures/example.csv
172
180
  - spec/integration/import_csv_spec.rb
173
181
  - spec/spec_helper.rb
174
- - spec/support/fakes/fake_parser.rb
182
+ - spec/stdout_stream_spec.rb
175
183
  - spec/support/shared_contexts/with_work_type.rb
176
- - spec/support/shared_examples/a_mapper.rb
177
- - spec/support/shared_examples/a_parser.rb
178
- - spec/support/shared_examples/a_validator.rb
179
184
  homepage:
180
185
  licenses:
181
186
  - Apache-2.0
@@ -196,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
201
  version: '0'
197
202
  requirements: []
198
203
  rubyforge_project:
199
- rubygems_version: 2.6.13
204
+ rubygems_version: 2.7.7
200
205
  signing_key:
201
206
  specification_version: 4
202
207
  summary: Hyrax importers.