arstotzka 1.0.4 → 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
2
  SHA1:
3
- metadata.gz: f6434b65a0dc88484fb45965e6c0700978300f24
4
- data.tar.gz: e91d322f0ad668991927080809a0ba63430814ac
3
+ metadata.gz: 74d1946cebd9e40fa273fc644a478e809ce9d888
4
+ data.tar.gz: 66abec44e1e8090d5507c8f4c59532dce3e8be03
5
5
  SHA512:
6
- metadata.gz: 5bd3079f38a8f38d95ef74521273f02dc9c40add3c81315d5bde04382fd75f02b017663cca973ed99a17681d9bf6bf509f9df9b79977edf9ab62f29fbccd1291
7
- data.tar.gz: 8929be5f4f9fae35d4ad87f54b3a60d7a361877c975e04dadbeebb553a5d0888fbb0f0167e00d1c72bd9e308eacd54176041e9b4c8848d029ebfd4addb2bda19
6
+ metadata.gz: 931eb74bb1e15412c7927c613204dbac3d48dc1ca6f3d81d58c941540ccf23ed530a19c4f8b1214ef06ba0f878d44e5e28cc6b55f3a32c0930123336d4fe3b43
7
+ data.tar.gz: fac8783602cc90be4933d9dce2f2fe5b6e24fd284ec2c53925ee75cd5cb5895aa62a1de5a40acdef5e158c66cc174df8fe3390ebfacacd7460f5d39c705830f6
data/.circleci/config.yml CHANGED
@@ -23,3 +23,6 @@ jobs:
23
23
  - run:
24
24
  name: Yardstick coverage check
25
25
  command: bundle exec rake verify_measurements
26
+ - run:
27
+ name: Check version documentation
28
+ command: scripts/check_readme.sh
data/.rubocop.yml CHANGED
@@ -10,3 +10,6 @@ Metrics/BlockLength:
10
10
 
11
11
  Metrics/LineLength:
12
12
  Max: 100
13
+
14
+ RSpec/AlignLeftLetBrace:
15
+ Enabled: true
data/.rubocop_todo.yml CHANGED
@@ -1,15 +1,17 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-03-07 08:37:15 +0000 using RuboCop version 0.58.1.
3
+ # on 2019-03-11 11:14:54 +0000 using RuboCop version 0.58.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  # Offense count: 1
10
- # Configuration parameters: CountKeywordArgs.
11
- Metrics/ParameterLists:
12
- Max: 7
10
+
11
+ # Offense count: 1
12
+ RSpec/AnyInstance:
13
+ Exclude:
14
+ - 'spec/lib/arstotzka/options_spec.rb'
13
15
 
14
16
  # Offense count: 46
15
17
  RSpec/NestedGroups:
data/README.md CHANGED
@@ -3,6 +3,7 @@ Arstotzka
3
3
  [![Code Climate](https://codeclimate.com/github/darthjee/arstotzka/badges/gpa.svg)](https://codeclimate.com/github/darthjee/arstotzka)
4
4
  [![Test Coverage](https://codeclimate.com/github/darthjee/arstotzka/badges/coverage.svg)](https://codeclimate.com/github/darthjee/arstotzka/coverage)
5
5
  [![Issue Count](https://codeclimate.com/github/darthjee/arstotzka/badges/issue_count.svg)](https://codeclimate.com/github/darthjee/arstotzka)
6
+ [![Gem Version](https://badge.fury.io/rb/arstotzka.svg)](https://badge.fury.io/rb/arstotzka)
6
7
 
7
8
  ![arstotzka](https://raw.githubusercontent.com/darthjee/arstotzka/master/arstotzka.jpg)
8
9
 
@@ -21,72 +22,71 @@ Instalation
21
22
  1. Add Arstotzka to your `Gemfile` and `bundle install`:
22
23
  - Install it
23
24
 
24
- ```ruby
25
- gem install arstotzka
26
- ```
25
+ ```ruby
26
+ gem install arstotzka
27
+ ```
27
28
 
28
- - Or add Arstotka to you `Gemfile` and `bundle install`
29
+ - Or add Arstotka to you `Gemfile` and `bundle install`
29
30
 
30
- ```ruby
31
- gem 'arstotzka'
32
- ```
31
+ ```ruby
32
+ gem 'arstotzka'
33
+ ```
33
34
 
34
- ```bash
35
- bundle install arstotzka
36
- ```
35
+ ```bash
36
+ bundle install arstotzka
37
+ ```
37
38
 
38
39
  Yard Documentation
39
40
  -------------------
40
- https://www.rubydoc.info/gems/arstotzka/1.0.4
41
+ https://www.rubydoc.info/gems/arstotzka/1.1.0
41
42
 
42
43
  Getting Started
43
44
  ---------------
44
45
  1. Include in a class that you want to wrap a json/hash
45
- ```ruby
46
- class MyParser
47
- include Arstotzka
48
- ```
46
+
47
+ ```ruby
48
+ class MyParser
49
+ include Arstotzka
50
+ end
51
+ ```
49
52
 
50
53
  2. Declare the keys you want to crawl
51
- ```ruby
52
- class MyParser
53
- include Arstotzka
54
54
 
55
- expose :id
56
- expose :name, :age, path: :person
55
+ ```ruby
56
+ class MyParser
57
+ include Arstotzka
58
+
59
+ expose :id
60
+ expose :name, :age, path: :person
57
61
 
58
- attr_reader :json
62
+ attr_reader :json
59
63
 
60
- def initialize(json = {})
61
- @json = json
62
- end
64
+ def initialize(json = {})
65
+ @json = json
63
66
  end
67
+ end
64
68
 
65
- ```
69
+ ```
66
70
 
67
- and let it fetch values from your hash
71
+ and let it fetch values from your hash
68
72
 
69
73
 
70
- ```ruby
71
- object = MyParser.new(
72
- id: 10,
74
+ ```ruby
75
+ MyParser.new(
76
+ id: 10,
77
+ age: 22
78
+ person: {
79
+ name: 'Robert',
73
80
  age: 22
74
- person: {
75
- name: 'Robert',
76
- age: 22
77
- }
78
- )
79
-
80
- object.name
81
- #returns 'Robert'
82
- ```
81
+ }
82
+ )
83
+ ```
83
84
 
84
- this is usefull when trying to fetch data from hashes missing nodes
85
+ this is usefull when trying to fetch data from hashes missing nodes
85
86
 
86
- ```ruby
87
- MyParser.new.name
88
- #returns nil
89
- ```
87
+ ```ruby
88
+ MyParser.new.name # returns nil
89
+ ```
90
90
 
91
91
  3. fully customise the way you crawl / fetch the information with [Options](#options)
92
92
 
@@ -98,7 +98,7 @@ Options
98
98
  - json: method that contains the hash to be parsed (json by default)
99
99
  - full_path: full path to fetch the value (empty by default)
100
100
  - cached: indicator that once the value has been fetched, it should be cached (false by default)
101
- - class: class to be used when wrapping the final value
101
+ - klass: class to be used when wrapping the final value
102
102
  - compact: indicator telling to ignore nil values inside array (false by default)
103
103
  - flatten: indicator telling that to flattern the resulting array (false by default)
104
104
  - after: name of a method to be called after with the resulting value
@@ -143,20 +143,20 @@ end
143
143
  ```
144
144
 
145
145
  ```ruby
146
- object = MyParser.new(
147
- accounts: [
148
- { balance: '$ 1000.50', type: 'checking' },
149
- { balance: '$ 150.10', type: 'savings' },
150
- { balance: '$ -100.24', type: 'checking' }
151
- ],
152
- loans: [
153
- { value: '$ 300.50', bank: 'the_bank' },
154
- { value: '$ 150.10', type: 'the_other_bank' },
155
- { value: '$ 100.24', type: 'the_same_bank' }
156
- ]
157
- )
158
-
159
- object.total_money # returns 1050.36
146
+ object = MyParser.new(
147
+ accounts: [
148
+ { balance: '$ 1000.50', type: 'checking' },
149
+ { balance: '$ 150.10', type: 'savings' },
150
+ { balance: '$ -100.24', type: 'checking' }
151
+ ],
152
+ loans: [
153
+ { value: '$ 300.50', bank: 'the_bank' },
154
+ { value: '$ 150.10', type: 'the_other_bank' },
155
+ { value: '$ 100.24', type: 'the_same_bank' }
156
+ ]
157
+ )
158
+
159
+ object.total_money # returns 1050.36
160
160
  ```
161
161
 
162
162
  ## Default
@@ -175,7 +175,7 @@ class StarGazer
175
175
  include Arstotzka
176
176
 
177
177
  expose :favorite_star, full_path: 'universe.star',
178
- default: { name: 'Sun' }, class: ::Star
178
+ default: { name: 'Sun' }, klass: ::Star
179
179
 
180
180
  attr_reader :json
181
181
 
@@ -186,14 +186,11 @@ end
186
186
 
187
187
  ```
188
188
 
189
-
190
189
  ```ruby
191
190
  star_gazer = StarGazer.new
192
191
 
193
- star_gazer.favorite_star.name
194
- #returns "Sun"
192
+ star_gazer.favorite_star.name # returns "Sun"
195
193
 
196
- star_gazer.favorite_star.class
197
- #returns Star
194
+ star_gazer.favorite_star.class # returns Star
198
195
  ```
199
196
 
data/config/yardstick.yml CHANGED
@@ -20,44 +20,32 @@ rules:
20
20
  enabled: true
21
21
  exclude:
22
22
  - Arstotzka::Builder#attr_names
23
+ - Arstotzka::Builder#options
23
24
  - Arstotzka::Builder#json_name
24
- - Arstotzka::Builder#path
25
- - Arstotzka::Builder#full_path
26
- - Arstotzka::Builder#cached
27
25
  - Arstotzka::Crawler#post_process
28
- - Arstotzka::Crawler#path
29
- - Arstotzka::Crawler#case_type
30
- - Arstotzka::Crawler#compact
31
- - Arstotzka::Crawler#default
32
- - Arstotzka::Fetcher#path
26
+ - Arstotzka::Crawler#options
27
+ - Arstotzka::Fetcher#keys
33
28
  - Arstotzka::Fetcher#hash
34
29
  - Arstotzka::Fetcher#instance
35
- - Arstotzka::Reader#path
36
- - Arstotzka::Reader#case_type
37
- - Arstotzka::Reader#change_case
38
- - Arstotzka::Wrapper#clazz
39
- - Arstotzka::Wrapper#type
30
+ - Arstotzka::Fetcher#options
31
+ - Arstotzka::Reader#keys
32
+ - Arstotzka::Reader#options
33
+ - Arstotzka::Wrapper#options
40
34
  Summary::Presence:
41
35
  enabled: true
42
36
  exclude:
43
37
  - Arstotzka::Builder#attr_names
38
+ - Arstotzka::Builder#options
44
39
  - Arstotzka::Builder#json_name
45
- - Arstotzka::Builder#path
46
- - Arstotzka::Builder#full_path
47
- - Arstotzka::Builder#cached
48
40
  - Arstotzka::Crawler#post_process
49
- - Arstotzka::Crawler#path
50
- - Arstotzka::Crawler#case_type
51
- - Arstotzka::Crawler#compact
52
- - Arstotzka::Crawler#default
53
- - Arstotzka::Fetcher#path
41
+ - Arstotzka::Crawler#options
42
+ - Arstotzka::Fetcher#keys
54
43
  - Arstotzka::Fetcher#hash
55
44
  - Arstotzka::Fetcher#instance
56
- - Arstotzka::Reader#path
57
- - Arstotzka::Reader#case_type
58
- - Arstotzka::Reader#change_case
59
- - Arstotzka::Wrapper#clazz
60
- - Arstotzka::Wrapper#type
45
+ - Arstotzka::Fetcher#options
46
+ - Arstotzka::Reader#keys
47
+ - Arstotzka::Reader#options
48
+ - Arstotzka::Wrapper#options
61
49
  Summary::Length:
62
50
  enabled: true
63
51
  exclude: []
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arstotzka
4
+ # @api private
5
+ #
6
+ # Common code to be used by classes
7
+ module Base
8
+ private
9
+
10
+ # Sets the @options object
11
+ #
12
+ # @overload options=(options_hash={})
13
+ # @param options_hash [Hash] options
14
+ #
15
+ # @overload options=(options)
16
+ # @param options [Arstotzka::Options] options object
17
+ #
18
+ # @return [Arstotzka::Options]
19
+ def options=(options)
20
+ @options = if options.is_a?(Hash)
21
+ Options.new(options)
22
+ else
23
+ options
24
+ end
25
+ end
26
+ end
27
+ end
@@ -21,13 +21,13 @@ module Arstotzka
21
21
  # 'cars' => 2.0
22
22
  # )
23
23
  #
24
- # options = Arstotzka::Builder::DEFAULT_OPTIONS.merge(full_path: 'name.first')
24
+ # options = Arstotzka::Options.new(full_path: 'name.first')
25
25
  # builder = Arstotzka::Builder.new([ :first_name ], MyModel, options)
26
26
  # builder.build
27
27
  #
28
28
  # instance.first_name # returns 'John'
29
29
  #
30
- # options = Arstotzka::Builder::DEFAULT_OPTIONS.merge(type: :integer)
30
+ # options = Arstotzka::Options.new(type: :integer)
31
31
  # builder = Arstotzka::Builder.new([ :age, :cars ], MyModel, options)
32
32
  # builder.build
33
33
  #
@@ -36,64 +36,34 @@ module Arstotzka
36
36
  #
37
37
  # @see https://www.rubydoc.info/gems/sinclair Sinclair
38
38
  class Builder < Sinclair
39
- DEFAULT_OPTIONS = {
40
- json: :json,
41
- path: nil,
42
- full_path: nil,
43
- cached: false,
44
- after: false,
45
- case: :lower_camel,
46
- class: nil,
47
- compact: false,
48
- default: nil,
49
- flatten: false,
50
- type: :none
51
- }.freeze
52
-
39
+ include Base
53
40
  # Returns new instance of Arstotzka::Builder
41
+ #
54
42
  # @param attr_names [Array] list of attributes to be fetched from the hash/json
55
43
  # @param clazz [Class] class to receive the methods
56
- # @param path [String/Symbol] path of hash attributes to find the root
57
- # where the attribute live (then fetching it using the attribute name)
58
- # @param full_path [String/Symbol] path of hash attributes to find exacttly where the
59
- # value live (ignoring the attribute name)
60
- # @param cached [Boolean] flag if the result should be memorized instead of repeating
61
- # the crawling
62
- # @param json [String/Symbol] name of the method containing the Hash/json to be crawled
63
- # @param options [Hash] hash containing extra options
64
- # @option options [String/Symbol] case: {Reader} flag definining on which case will
65
- # the keys be defined
66
- # - lower_camel: keys in the hash are lowerCamelCase
67
- # - upper_camel: keys in the hash are UpperCamelCase
68
- # - snake: keys in the hash are snake_case
69
- # @option options [Boolean] compact: {Crawler} flag to apply Array#compact thus
70
- # removing nil results
71
- # @option options [Class] class: {Fetcher} option thatwhen passed, wraps the result in an
72
- # instance of the given class
73
- # @option options [String/Symbol] after: {Fetcher} option with the name of the method to be
74
- # called once the value is fetched for mapping the value
75
- # @option options [Boolean] flatten: {Fetcher} flag to aplly Array#flatten thus
76
- # avoing nested arrays
77
- # @option options [String/Symbol] type: {Fetcher} option declaring the type of the returned
78
- # value (to use casting)
79
- # - integer
80
- # - string
81
- # - float
82
- def initialize(attr_names, clazz, json:, path:, full_path:, cached:, **options)
83
- super(clazz, options)
44
+ # (using {https://www.rubydoc.info/gems/sinclair Sinclair})
45
+ #
46
+ # @overload initialize(attr_names, clazz, options_hash={})
47
+ # @param options_hash [Hash] hash containing extra options
48
+ #
49
+ # @overload initialize(attr_names, clazz, options)
50
+ # @param options [Arstotzka::Options] options of initialization object
51
+ #
52
+ # @see https://www.rubydoc.info/gems/sinclair Sinclair
53
+ # @see Arstotzka::Options
54
+ def initialize(attr_names, clazz, options = {})
55
+ super(clazz)
56
+ self.options = options
84
57
 
85
58
  @attr_names = attr_names
86
- @path = path
87
- @full_path = full_path
88
- @cached = cached
89
- @json_name = json
90
59
  init
91
60
  end
92
61
 
93
62
  private
94
63
 
95
64
  # @private
96
- attr_reader :attr_names, :json_name, :path, :full_path, :cached
65
+ attr_reader :attr_names, :options
66
+ delegate :json_name, :path, :full_path, :cached, to: :options
97
67
 
98
68
  # @private
99
69
  #
@@ -117,37 +87,6 @@ module Arstotzka
117
87
  full_path || [path, attribute].compact.join('.')
118
88
  end
119
89
 
120
- # @private
121
- #
122
- # Fetch class to wrap resulting value
123
- #
124
- # after fetching the value, when wrapper_clazz returns
125
- # a Class object, the value will be wrapped with
126
- # +wrapper_clazz.new(value)+
127
- #
128
- # @return [Class] the class to wrap the resulting value
129
- #
130
- # @see Arstotzka::Wrapper
131
- def wrapper_clazz
132
- options[:class]
133
- end
134
-
135
- # @private
136
- #
137
- # Fetches the case of the keys
138
- #
139
- # case types can be
140
- # - lower_camel: keys in the hash are lowerCamelCase
141
- # - upper_camel: keys in the hash are UpperCamelCase
142
- # - snake: keys in the hash are snake_case
143
- #
144
- # @return [Symbol/String] defined case_type
145
- #
146
- # @see Arstotzka::Reader
147
- def case_type
148
- options[:case]
149
- end
150
-
151
90
  # @private
152
91
  #
153
92
  # Options needed by fetcher
@@ -158,9 +97,7 @@ module Arstotzka
158
97
  #
159
98
  # @see Arstotzka::Fetcher
160
99
  def fetcher_options(attribute)
161
- options.slice(:compact, :after, :type, :flatten, :default).merge(
162
- clazz: wrapper_clazz,
163
- case_type: case_type,
100
+ options.to_h.slice(:klass, :case, :compact, :after, :type, :flatten, :default).merge(
164
101
  path: real_path(attribute)
165
102
  )
166
103
  end
@@ -178,6 +115,10 @@ module Arstotzka
178
115
  add_method attribute, (cached ? cached_fetcher(attribute) : attr_fetcher(attribute)).to_s
179
116
  end
180
117
 
118
+ def json_name
119
+ options.json
120
+ end
121
+
181
122
  # Returns the code needed to initialize fetcher
182
123
  #
183
124
  # @param [String/Symbol] attribute name of method / attribute
@@ -35,14 +35,14 @@ module Arstotzka
35
35
  # instance.age # returns 20
36
36
  # instance.cars # returns 2
37
37
  #
38
- # @return nil
38
+ # @return [Array<Sinclair::MethodDefinition>]
39
39
  #
40
40
  # @see Builder Arstotzka::Builder
41
41
  # @see
42
42
  # https://www.rubydoc.info/gems/activesupport/5.2.2/ActiveSupport/Concern
43
43
  # ActiveSupport::Concern
44
- def expose(*attr_names, **options)
45
- options = Builder::DEFAULT_OPTIONS.merge(options.symbolize_keys)
44
+ def expose(*attr_names, **options_hash)
45
+ options = Options.new(options_hash.symbolize_keys)
46
46
  Builder.new(attr_names, self, options).build
47
47
  end
48
48
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Arstotzka
4
- # Crawl a hash through the path of keys
4
+ # Crawl a hash through the keys of keys
5
5
  #
6
6
  # @api private
7
7
  #
8
8
  # @example
9
- # crawler = Arstotzka::Crawler.new(%w(person information first_name))
9
+ # crawler = Arstotzka::Crawler.new(keys: %w(person information first_name))
10
10
  # hash = {
11
11
  # person: {
12
12
  # 'information' => {
@@ -16,31 +16,37 @@ module Arstotzka
16
16
  # }
17
17
  # crawler.value(hash) # returns 'John'
18
18
  class Crawler
19
+ include Base
20
+
19
21
  # Creates a new instance of Crawler
20
22
  #
21
- # @param path [Array] path of keys to be crawled
22
- # @param case_type [Symbol] case type of the keys
23
- # - snake: snake_cased keys
24
- # - lower_camel: lowerCamelCased keys
25
- # - upper_camel: UperCamelCased keys
26
- # @param compact [Boolean] flag signallying if nil values should be removed of an array
27
- # @param default [Object] default value to be returned when failing to fetch a value
28
23
  # @param block [Proc] block to be ran over the fetched value before returning it
29
- def initialize(path:, case_type: :lower_camel, compact: false, default: nil, &block)
30
- @case_type = case_type
31
- @compact = compact
32
- @default = default
33
- @path = path
24
+ #
25
+ # @overload initialize(options_hash={}, &block)
26
+ # @param options [Hash] options of initialization
27
+ # @option options keys [Array] keys of keys to be crawled
28
+ # @option options case [Symbol] case type of the keys
29
+ # - snake: snake_cased keys
30
+ # - lower_camel: lowerCamelCased keys
31
+ # - upper_camel: UperCamelCased keys
32
+ # @option options compact [Boolean] flag signallying if nil values should be removed of array
33
+ # @option options default [Object] default value to be returned when failing to fetch a value
34
+ #
35
+ # @overload initialize(options, &block)
36
+ # @param options [Arstotzka::Options] options of initialization object
37
+ def initialize(options = {}, &block)
38
+ self.options = options
39
+
34
40
  @post_process = block || proc { |value| value }
35
41
  end
36
42
 
37
- # Crawls into the hash looking for all keys in the given path
38
- # @overload value(hash)
43
+ # Crawls into the hash looking for all keys in the given keys
44
+ #
39
45
  # @return [Object] value fetched from the last Hash#fetch call using the last part
40
- # of path
46
+ # of keys
41
47
  #
42
48
  # @example
43
- # crawler = Arstotzka::Crawler.new(%w(person information first_name))
49
+ # crawler = Arstotzka::Crawler.new(keys: %w(person information first_name))
44
50
  # hash = {
45
51
  # person: {
46
52
  # 'information' => {
@@ -52,8 +58,8 @@ module Arstotzka
52
58
  #
53
59
  # @example
54
60
  # crawler = Arstotzka::Crawler.new(
55
- # %w(companies games hero),
56
- # compact: true, case_type: :snake
61
+ # keys: %w(companies games hero),
62
+ # compact: true, case: :snake
57
63
  # )
58
64
  # games_hash = {
59
65
  # 'companies' => [{
@@ -73,16 +79,16 @@ module Arstotzka
73
79
  #
74
80
  # @example
75
81
  # crawler = Arstotzka::Crawler.new(
76
- # %w(companies games hero),
77
- # compact: true, case_type: :snake, default: 'NO HERO'
82
+ # keys: %w(companies games hero),
83
+ # compact: true, case: :snake, default: 'NO HERO'
78
84
  # )
79
85
  #
80
86
  # crawler.value(games_hash) # returns [['NO HERO', 'Rakhar'], 'NO HERO']
81
87
  #
82
88
  # @example
83
89
  # crawler = Arstotzka::Crawler.new(
84
- # %w(companies games hero),
85
- # compact: true, case_type: :snake
90
+ # keys: %w(companies games hero),
91
+ # compact: true, case: :snake
86
92
  # ) { |value| value.&to_sym }
87
93
  #
88
94
  # crawler.value(games_hash) # returns [[:Rakhar]]
@@ -95,7 +101,8 @@ module Arstotzka
95
101
  private
96
102
 
97
103
  # @private
98
- attr_reader :post_process, :path, :case_type, :compact, :default
104
+ attr_reader :post_process, :options
105
+ delegate :keys, :compact, :default, to: :options
99
106
 
100
107
  # Fetch the value from hash by crawling the keys
101
108
  #
@@ -134,10 +141,7 @@ module Arstotzka
134
141
  #
135
142
  # @return [Arstotzka::Reader] Object responsible for extracting values out of the hash
136
143
  def reader
137
- @reader ||= Arstotzka::Reader.new(
138
- path: path,
139
- case_type: case_type
140
- )
144
+ @reader ||= Arstotzka::Reader.new(options)
141
145
  end
142
146
 
143
147
  # @private