physical 0.4.3 → 0.4.5

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: b5071305935c7247bcd7f1cdc6f67693d5c8cb37
4
- data.tar.gz: 6040fbc65b93b5d0aced798b9c4f4007952e954f
2
+ SHA256:
3
+ metadata.gz: a0be314d80085ad67728a8353fd16c80d0a177a939018af9d20f08eb47d789a8
4
+ data.tar.gz: 13b2a4f823b4568a372f221d2d9ef2027eae4317943ac379aadf0dde3725fb76
5
5
  SHA512:
6
- metadata.gz: 346db67ecfe973dfcf2553331d0d67836e62cff6de2ea688227e37f01703cb1871a4d49b7670d71d0023d5a17cb92e4005bef7e9ebc9a2317c0320a8fbc5b89f
7
- data.tar.gz: 937e4dbd4098d311d36622db26514e40b15e4f6c9690facb0fda1bc37056e68dc73f14b1c4b1ec03f406bd1e927b0c4172c06311fb0a02992e0dfe28c7b215c1
6
+ metadata.gz: a5e3cd08e4be265708c39d1b17952e704da2cecd4fb7048fcdcb00d0899812192767b09d5466aff0e74e585f4d4b1bf0186184a13c462dc4fdc9afa519713a9c
7
+ data.tar.gz: e21a20c9e7469006a13f68c57a1284515d533c71af13b8433c7f4cd527e09a927885a56344e927ef0dcac9e1606d7c42baa4580c47c9e1987bca83d4d2d68b58
data/.circleci/config.yml CHANGED
@@ -7,12 +7,7 @@ jobs:
7
7
  build:
8
8
  docker:
9
9
  # specify the version you desire here
10
- - image: circleci/ruby:2.4.5
11
-
12
- # Specify service dependencies here if necessary
13
- # CircleCI maintains a library of pre-built images
14
- # documented at https://circleci.com/docs/2.0/circleci-images/
15
- # - image: circleci/postgres:9.4
10
+ - image: cimg/ruby:3.0.4
16
11
 
17
12
  working_directory: ~/repo
18
13
 
@@ -37,6 +32,10 @@ jobs:
37
32
  - ./vendor/bundle
38
33
  key: v1-dependencies-{{ checksum "Gemfile.lock" }}
39
34
 
35
+ - run:
36
+ name: run Rubocop
37
+ command: bundle exec rubocop
38
+
40
39
  # run tests!
41
40
  - run:
42
41
  name: run tests
data/.gitignore CHANGED
@@ -9,4 +9,9 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .ruby-version
12
13
  Gemfile.lock
14
+
15
+ # RubyMine
16
+ .idea
17
+ .rakeTasks
@@ -0,0 +1,169 @@
1
+ # Relaxed.Ruby.Style
2
+ ## Version 2.2
3
+
4
+ Style/Alias:
5
+ Enabled: false
6
+ StyleGuide: https://relaxed.ruby.style/#stylealias
7
+
8
+ Style/AsciiComments:
9
+ Enabled: false
10
+ StyleGuide: https://relaxed.ruby.style/#styleasciicomments
11
+
12
+ Style/BeginBlock:
13
+ Enabled: false
14
+ StyleGuide: https://relaxed.ruby.style/#stylebeginblock
15
+
16
+ Style/BlockDelimiters:
17
+ Enabled: false
18
+ StyleGuide: https://relaxed.ruby.style/#styleblockdelimiters
19
+
20
+ Style/CommentAnnotation:
21
+ Enabled: false
22
+ StyleGuide: https://relaxed.ruby.style/#stylecommentannotation
23
+
24
+ Style/Documentation:
25
+ Enabled: false
26
+ StyleGuide: https://relaxed.ruby.style/#styledocumentation
27
+
28
+ Layout/DotPosition:
29
+ Enabled: false
30
+ StyleGuide: https://relaxed.ruby.style/#layoutdotposition
31
+
32
+ Style/DoubleNegation:
33
+ Enabled: false
34
+ StyleGuide: https://relaxed.ruby.style/#styledoublenegation
35
+
36
+ Style/EndBlock:
37
+ Enabled: false
38
+ StyleGuide: https://relaxed.ruby.style/#styleendblock
39
+
40
+ Style/FormatString:
41
+ Enabled: false
42
+ StyleGuide: https://relaxed.ruby.style/#styleformatstring
43
+
44
+ Style/IfUnlessModifier:
45
+ Enabled: false
46
+ StyleGuide: https://relaxed.ruby.style/#styleifunlessmodifier
47
+
48
+ Style/Lambda:
49
+ Enabled: false
50
+ StyleGuide: https://relaxed.ruby.style/#stylelambda
51
+
52
+ Style/ModuleFunction:
53
+ Enabled: false
54
+ StyleGuide: https://relaxed.ruby.style/#stylemodulefunction
55
+
56
+ Style/MultilineBlockChain:
57
+ Enabled: false
58
+ StyleGuide: https://relaxed.ruby.style/#stylemultilineblockchain
59
+
60
+ Style/NegatedIf:
61
+ Enabled: false
62
+ StyleGuide: https://relaxed.ruby.style/#stylenegatedif
63
+
64
+ Style/NegatedWhile:
65
+ Enabled: false
66
+ StyleGuide: https://relaxed.ruby.style/#stylenegatedwhile
67
+
68
+ Style/ParallelAssignment:
69
+ Enabled: false
70
+ StyleGuide: https://relaxed.ruby.style/#styleparallelassignment
71
+
72
+ Style/PercentLiteralDelimiters:
73
+ Enabled: false
74
+ StyleGuide: https://relaxed.ruby.style/#stylepercentliteraldelimiters
75
+
76
+ Style/PerlBackrefs:
77
+ Enabled: false
78
+ StyleGuide: https://relaxed.ruby.style/#styleperlbackrefs
79
+
80
+ Style/Semicolon:
81
+ Enabled: false
82
+ StyleGuide: https://relaxed.ruby.style/#stylesemicolon
83
+
84
+ Style/SignalException:
85
+ Enabled: false
86
+ StyleGuide: https://relaxed.ruby.style/#stylesignalexception
87
+
88
+ Style/SingleLineBlockParams:
89
+ Enabled: false
90
+ StyleGuide: https://relaxed.ruby.style/#stylesinglelineblockparams
91
+
92
+ Style/SingleLineMethods:
93
+ Enabled: false
94
+ StyleGuide: https://relaxed.ruby.style/#stylesinglelinemethods
95
+
96
+ Layout/SpaceBeforeBlockBraces:
97
+ Enabled: false
98
+ StyleGuide: https://relaxed.ruby.style/#layoutspacebeforeblockbraces
99
+
100
+ Layout/SpaceInsideParens:
101
+ Enabled: false
102
+ StyleGuide: https://relaxed.ruby.style/#layoutspaceinsideparens
103
+
104
+ Style/SpecialGlobalVars:
105
+ Enabled: false
106
+ StyleGuide: https://relaxed.ruby.style/#stylespecialglobalvars
107
+
108
+ Style/StringLiterals:
109
+ Enabled: false
110
+ StyleGuide: https://relaxed.ruby.style/#stylestringliterals
111
+
112
+ Style/TrailingCommaInArguments:
113
+ Enabled: false
114
+ StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarguments
115
+
116
+ Style/TrailingCommaInArrayLiteral:
117
+ Enabled: false
118
+ StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarrayliteral
119
+
120
+ Style/TrailingCommaInHashLiteral:
121
+ Enabled: false
122
+ StyleGuide: https://relaxed.ruby.style/#styletrailingcommainhashliteral
123
+
124
+ Style/SymbolArray:
125
+ Enabled: false
126
+ StyleGuide: http://relaxed.ruby.style/#stylesymbolarray
127
+
128
+ Style/WhileUntilModifier:
129
+ Enabled: false
130
+ StyleGuide: https://relaxed.ruby.style/#stylewhileuntilmodifier
131
+
132
+ Style/WordArray:
133
+ Enabled: false
134
+ StyleGuide: https://relaxed.ruby.style/#stylewordarray
135
+
136
+ Lint/AmbiguousRegexpLiteral:
137
+ Enabled: false
138
+ StyleGuide: https://relaxed.ruby.style/#lintambiguousregexpliteral
139
+
140
+ Lint/AssignmentInCondition:
141
+ Enabled: false
142
+ StyleGuide: https://relaxed.ruby.style/#lintassignmentincondition
143
+
144
+ Metrics/AbcSize:
145
+ Enabled: false
146
+
147
+ Metrics/BlockNesting:
148
+ Enabled: false
149
+
150
+ Metrics/ClassLength:
151
+ Enabled: false
152
+
153
+ Metrics/ModuleLength:
154
+ Enabled: false
155
+
156
+ Metrics/CyclomaticComplexity:
157
+ Enabled: false
158
+
159
+ Metrics/LineLength:
160
+ Enabled: false
161
+
162
+ Metrics/MethodLength:
163
+ Enabled: false
164
+
165
+ Metrics/ParameterLists:
166
+ Enabled: false
167
+
168
+ Metrics/PerceivedComplexity:
169
+ Enabled: false
data/.rubocop.yml CHANGED
@@ -1,321 +1,8 @@
1
1
  AllCops:
2
- Exclude:
3
- - Gemfile
4
- - Rakefile
5
- - bin/*
6
- - vendor/**/*
2
+ TargetRubyVersion: 2.4
7
3
 
8
- Layout/EmptyLinesAroundBlockBody:
9
- Enabled: false
10
-
11
- Layout/EmptyLinesAroundModuleBody:
12
- Enabled: false
13
-
14
- Layout/EmptyLinesAroundClassBody:
15
- Enabled: false
16
-
17
- Layout/EmptyLinesAroundMethodBody:
18
- Enabled: false
19
-
20
- Naming/MemoizedInstanceVariableName:
21
- Enabled: false
22
-
23
- Style/RedundantSelf:
24
- Enabled: false
25
-
26
- CollectionMethods:
27
- Enabled: false
28
-
29
- # Sometimes I believe this reads better
30
- # This also causes spacing issues on multi-line fixes
31
- Style/BracesAroundHashParameters:
32
- Enabled: false
33
-
34
- # We use class vars and will have to continue doing so for compatability
35
- Style/ClassVars:
36
- Enabled: false
37
-
38
- # We need these names for backwards compatability
39
- Naming/PredicateName:
40
- Enabled: false
41
-
42
- Naming/AccessorMethodName:
43
- Enabled: false
44
-
45
- # This has been used for customization
46
- Style/MutableConstant:
47
- Enabled: false
48
-
49
- # `something.count > 0` is often used in Solidus admin and IMO better to read then `something.count.positive?`
50
- Style/NumericPredicate:
51
- Enabled: false
52
-
53
- Style/ClassAndModuleChildren:
54
- Enabled: false
55
-
56
- Style/EmptyElse:
57
- Enabled: false
58
-
59
- Style/GuardClause:
60
- Enabled: false
61
-
62
- Style/Next:
63
- Enabled: false
64
-
65
- Style/WordArray:
66
- Enabled: false
67
-
68
- Style/ConditionalAssignment:
69
- Enabled: false
70
-
71
- Performance/Count:
72
- Enabled: false
73
-
74
- Style/RaiseArgs:
75
- Enabled: false
76
-
77
- Naming/BinaryOperatorParameterName:
78
- Enabled: false
79
-
80
- # We can use good judgement here
81
- Style/RegexpLiteral:
82
- Enabled: false
83
-
84
- # Unicode comments are useful
85
- Style/AsciiComments:
86
- Enabled: false
87
-
88
- Layout/EndAlignment:
89
- Enabled: false
90
-
91
- Layout/ElseAlignment:
92
- Enabled: false
93
-
94
- Layout/IndentationWidth:
95
- Enabled: false
96
-
97
- Layout/AlignParameters:
98
- Enabled: false
99
-
100
- Layout/ClosingParenthesisIndentation:
101
- Enabled: false
102
-
103
- Layout/MultilineMethodCallIndentation:
104
- Enabled: false
105
-
106
- Layout/IndentArray:
107
- Enabled: false
108
-
109
- Layout/IndentHash:
110
- Enabled: false
111
-
112
- Layout/AlignHash:
113
- Enabled: false
114
-
115
- Style/TrailingCommaInArguments:
116
- Enabled: false
117
-
118
- Style/TrailingCommaInArrayLiteral:
119
- Enabled: false
120
-
121
- Style/TrailingCommaInHashLiteral:
122
- Enabled: false
123
-
124
- Layout/SpaceInsideHashLiteralBraces:
125
- Enabled: false
126
-
127
- # Symbol Arrays are ok and the %i syntax widely unknown
128
- Style/SymbolArray:
129
- Enabled: false
130
-
131
- Rails/DynamicFindBy:
132
- Whitelist:
133
- - find_by_param
134
- - find_by_param!
135
-
136
- # We use a lot of
137
- #
138
- # expect {
139
- # something
140
- # }.to { happen }
141
- #
142
- # syntax in the specs files.
143
- Lint/AmbiguousBlockAssociation:
144
- Exclude:
145
- - 'spec/**/*'
146
-
147
- # We use eval to add common_spree_dependencies into the Gemfiles of each of our gems
148
- Security/Eval:
149
- Exclude:
150
- - 'Gemfile'
151
- - '*/Gemfile'
152
-
153
- Naming/VariableNumber:
154
- Enabled: false
155
-
156
- # Write empty methods as you wish.
157
- Style/EmptyMethod:
158
- Enabled: false
159
-
160
- # The Rails Guides are in contradiction with this cop.
161
- Style/FormatStringToken:
162
- Exclude:
163
- - 'config/routes.rb'
164
-
165
- # From http://relaxed.ruby.style/
166
-
167
- Style/Alias:
168
- Enabled: false
169
- StyleGuide: http://relaxed.ruby.style/#stylealias
170
-
171
- Style/BeginBlock:
172
- Enabled: false
173
- StyleGuide: http://relaxed.ruby.style/#stylebeginblock
174
-
175
- Style/BlockDelimiters:
176
- Enabled: false
177
- StyleGuide: http://relaxed.ruby.style/#styleblockdelimiters
178
-
179
- Style/Documentation:
180
- Enabled: false
181
- StyleGuide: http://relaxed.ruby.style/#styledocumentation
182
-
183
- Layout/DotPosition:
184
- EnforcedStyle: trailing
185
- Enabled: true
186
- StyleGuide: http://relaxed.ruby.style/#styledotposition
187
-
188
- Style/DoubleNegation:
189
- Enabled: false
190
- StyleGuide: http://relaxed.ruby.style/#styledoublenegation
191
-
192
- Style/EndBlock:
193
- Enabled: false
194
- StyleGuide: http://relaxed.ruby.style/#styleendblock
195
-
196
- Style/FormatString:
197
- Enabled: false
198
- StyleGuide: http://relaxed.ruby.style/#styleformatstring
199
-
200
- Style/IfUnlessModifier:
201
- Enabled: false
202
- StyleGuide: http://relaxed.ruby.style/#styleifunlessmodifier
203
-
204
- Style/Lambda:
205
- Enabled: false
206
- StyleGuide: http://relaxed.ruby.style/#stylelambda
207
-
208
- Style/ModuleFunction:
209
- Enabled: false
210
- StyleGuide: http://relaxed.ruby.style/#stylemodulefunction
211
-
212
- Style/MultilineBlockChain:
213
- Enabled: false
214
- StyleGuide: http://relaxed.ruby.style/#stylemultilineblockchain
215
-
216
- Style/NegatedIf:
217
- Enabled: false
218
- StyleGuide: http://relaxed.ruby.style/#stylenegatedif
219
-
220
- Style/NegatedWhile:
221
- Enabled: false
222
- StyleGuide: http://relaxed.ruby.style/#stylenegatedwhile
223
-
224
- Style/ParallelAssignment:
225
- Enabled: false
226
- StyleGuide: http://relaxed.ruby.style/#styleparallelassignment
227
-
228
- Style/PercentLiteralDelimiters:
229
- Enabled: false
230
- StyleGuide: http://relaxed.ruby.style/#stylepercentliteraldelimiters
231
-
232
- Style/PerlBackrefs:
233
- Enabled: false
234
- StyleGuide: http://relaxed.ruby.style/#styleperlbackrefs
235
-
236
- Style/Semicolon:
237
- Enabled: false
238
- StyleGuide: http://relaxed.ruby.style/#stylesemicolon
239
-
240
- Style/SignalException:
241
- Enabled: false
242
- StyleGuide: http://relaxed.ruby.style/#stylesignalexception
243
-
244
- Style/SingleLineBlockParams:
245
- Enabled: false
246
- StyleGuide: http://relaxed.ruby.style/#stylesinglelineblockparams
247
-
248
- Style/SingleLineMethods:
249
- Enabled: false
250
- StyleGuide: http://relaxed.ruby.style/#stylesinglelinemethods
251
-
252
- Layout/SpaceBeforeBlockBraces:
253
- Enabled: false
254
- StyleGuide: http://relaxed.ruby.style/#stylespacebeforeblockbraces
255
-
256
- Layout/SpaceInsideParens:
257
- Enabled: false
258
- StyleGuide: http://relaxed.ruby.style/#stylespaceinsideparens
259
-
260
- Style/SpecialGlobalVars:
261
- Enabled: false
262
- StyleGuide: http://relaxed.ruby.style/#stylespecialglobalvars
263
-
264
- Style/StringLiterals:
265
- Enabled: false
266
- StyleGuide: http://relaxed.ruby.style/#stylestringliterals
267
-
268
- Style/SymbolProc:
269
- Enabled: false
270
-
271
- Style/WhileUntilModifier:
272
- Enabled: false
273
- StyleGuide: http://relaxed.ruby.style/#stylewhileuntilmodifier
274
-
275
- Lint/AmbiguousRegexpLiteral:
276
- Enabled: false
277
- StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
278
-
279
- Lint/AssignmentInCondition:
280
- Enabled: true
281
- StyleGuide: http://relaxed.ruby.style/#lintassignmentincondition
282
-
283
- Metrics/AbcSize:
284
- Enabled: false
285
-
286
- Metrics/BlockNesting:
287
- Enabled: false
288
-
289
- Metrics/ClassLength:
290
- Enabled: false
291
-
292
- Metrics/ModuleLength:
293
- Enabled: false
4
+ inherit_from:
5
+ - .rubocop-relaxed.yml
294
6
 
295
7
  Metrics/BlockLength:
296
8
  Enabled: false
297
-
298
- Metrics/CyclomaticComplexity:
299
- Enabled: false
300
-
301
- Metrics/LineLength:
302
- Enabled: true
303
- Max: 120
304
- Exclude:
305
- - 'spec/**/*'
306
-
307
- Metrics/MethodLength:
308
- Enabled: false
309
- Max: 25
310
-
311
- Metrics/ParameterLists:
312
- Enabled: false
313
-
314
- Metrics/PerceivedComplexity:
315
- Enabled: false
316
-
317
- Bundler/OrderedGems:
318
- Enabled: false
319
-
320
- Style/NumericLiterals:
321
- Enabled: false
data/CHANGELOG.md CHANGED
@@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## [0.4.5] - 2022-09-28
10
+ ### Added
11
+ - Add `Physical::Pallet` class [#12]
12
+ - Convenience methods for weight, volume, and fill [#15]
13
+ - Add inner dimensions for `Pallet` class [#16]
14
+
15
+ ### Changed
16
+ - Fix Ruby 2.7 deprecation warnings [#3]
17
+ - Set rounding mode for Money gem [#6]
18
+ - Bump Rake version [#10]
19
+ - Ruby 3 support [#18]
20
+
21
+ ## [0.4.4] - 2019-10-29
22
+ ### Added
23
+ - Add `#sku`, `#cost` and `#description` to `Physical::Item`
24
+
9
25
  ## [0.4.3] - 2019-10-14
10
26
  ### Added
11
27
  - Add `#latitude` and `#longitude` to `Physical::Location`
data/Gemfile CHANGED
@@ -1,10 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in physical.gemspec
6
8
  gemspec
7
-
8
- group :test do
9
- gem 'rspec_junit_formatter'
10
- end
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "physical"
data/lib/physical/box.rb CHANGED
@@ -13,8 +13,10 @@ module Physical
13
13
  :inner_height,
14
14
  :max_weight
15
15
 
16
- def initialize(inner_dimensions: [], max_weight: Measured::Weight(DEFAULT_MAX_WEIGHT, :g), **args)
17
- super args
16
+ def initialize(**args)
17
+ inner_dimensions = args.delete(:inner_dimensions) || []
18
+ max_weight = args.delete(:max_weight) || Measured::Weight(DEFAULT_MAX_WEIGHT, :g)
19
+ super(**args)
18
20
  @inner_dimensions = fill_dimensions(Types::Dimensions[inner_dimensions])
19
21
  @inner_length, @inner_width, @inner_height = *@inner_dimensions
20
22
  @max_weight = Types::Weight[max_weight]
@@ -26,5 +28,17 @@ module Physical
26
28
  :ml
27
29
  )
28
30
  end
31
+
32
+ # @param [Physical::Item] item
33
+ # @return [Boolean]
34
+ def item_fits?(item)
35
+ return false if item.weight > max_weight
36
+
37
+ box_dimensions = inner_dimensions.sort
38
+ item.dimensions.sort.each.with_index do |axis, index|
39
+ return false if axis >= box_dimensions[index]
40
+ end
41
+ true
42
+ end
29
43
  end
30
44
  end
@@ -22,16 +22,18 @@ module Physical
22
22
  def density
23
23
  return Measured::Density(Float::INFINITY, :g_ml) if volume.value.zero?
24
24
  return Measured::Density(0.0, :g_ml) if volume.value.infinite?
25
+
25
26
  Measured::Density(weight.convert_to(:g).value / volume.convert_to(:ml).value, :g_ml)
26
27
  end
27
28
 
28
29
  def ==(other)
29
- id == other.id
30
+ other.is_a?(self.class) &&
31
+ id == other&.id
30
32
  end
31
33
 
32
34
  private
33
35
 
34
- NORMALIZED_METHOD_REGEX = /(\w+)\??$/
36
+ NORMALIZED_METHOD_REGEX = /(\w+)\??$/.freeze
35
37
 
36
38
  def method_missing(method)
37
39
  symbolized_properties = properties.symbolize_keys
data/lib/physical/item.rb CHANGED
@@ -3,5 +3,16 @@
3
3
  module Physical
4
4
  class Item < Cuboid
5
5
  DEFAULT_LENGTH = 0
6
+
7
+ attr_reader :cost,
8
+ :sku,
9
+ :description
10
+
11
+ def initialize(**kwargs)
12
+ @cost = Types::Money.optional[kwargs.delete(:cost)]
13
+ @sku = kwargs.delete(:sku)
14
+ @description = kwargs.delete(:description)
15
+ super(**kwargs)
16
+ end
6
17
  end
7
18
  end
@@ -4,7 +4,7 @@ require 'carmen'
4
4
 
5
5
  module Physical
6
6
  class Location
7
- ADDRESS_TYPES = %w(residential commercial po_box)
7
+ ADDRESS_TYPES = %w(residential commercial po_box).freeze
8
8
 
9
9
  attr_reader :country,
10
10
  :zip,
@@ -23,28 +23,28 @@ module Physical
23
23
  :longitude
24
24
 
25
25
  def initialize(
26
- name: nil,
27
- company_name: nil,
28
- address1: nil,
29
- address2: nil,
30
- address3: nil,
31
- city: nil,
32
- region: nil,
33
- zip: nil,
34
- country: nil,
35
- phone: nil,
36
- fax: nil,
37
- email: nil,
38
- address_type: nil,
39
- latitude: nil,
40
- longitude: nil
41
- )
26
+ name: nil,
27
+ company_name: nil,
28
+ address1: nil,
29
+ address2: nil,
30
+ address3: nil,
31
+ city: nil,
32
+ region: nil,
33
+ zip: nil,
34
+ country: nil,
35
+ phone: nil,
36
+ fax: nil,
37
+ email: nil,
38
+ address_type: nil,
39
+ latitude: nil,
40
+ longitude: nil
41
+ )
42
42
 
43
- if country.is_a?(Carmen::Country)
44
- @country = country
45
- else
46
- @country = Carmen::Country.coded(country.to_s)
47
- end
43
+ @country = if country.is_a?(Carmen::Country)
44
+ country
45
+ else
46
+ Carmen::Country.coded(country.to_s)
47
+ end
48
48
 
49
49
  if region.is_a?(Carmen::Region)
50
50
  @region = region
@@ -81,9 +81,9 @@ module Physical
81
81
 
82
82
  def to_hash
83
83
  {
84
- country: country.code,
84
+ country: country&.code,
85
85
  postal_code: zip,
86
- region: region.code,
86
+ region: region&.code,
87
87
  city: city,
88
88
  name: name,
89
89
  address1: address1,
@@ -98,7 +98,8 @@ module Physical
98
98
  end
99
99
 
100
100
  def ==(other)
101
- to_hash == other.to_hash
101
+ other.is_a?(self.class) &&
102
+ to_hash == other&.to_hash
102
103
  end
103
104
  end
104
105
  end
@@ -14,22 +14,23 @@ module Physical
14
14
 
15
15
  delegate [:dimensions, :width, :length, :height, :properties, :volume] => :container
16
16
 
17
- def <<(item)
18
- @items.add(item)
17
+ def <<(other)
18
+ @items.add(other)
19
19
  end
20
20
  alias_method :add, :<<
21
21
 
22
- def >>(item)
23
- @items.delete(item)
22
+ def >>(other)
23
+ @items.delete(other)
24
24
  end
25
25
  alias_method :delete, :>>
26
26
 
27
27
  def weight
28
- container.weight + items.map(&:weight).reduce(Measured::Weight(0, :g), &:+) + void_fill_weight
28
+ container.weight + items_weight + void_fill_weight
29
29
  end
30
30
 
31
- def remaining_volume
32
- container.inner_volume - items.map(&:volume).reduce(Measured::Volume(0, :ml), &:+)
31
+ # @return [Measured::Weight]
32
+ def items_weight
33
+ items.map(&:weight).reduce(Measured::Weight(0, :g), &:+)
33
34
  end
34
35
 
35
36
  def void_fill_weight
@@ -38,9 +39,19 @@ module Physical
38
39
  Measured::Weight(void_fill_density.convert_to(:g_ml).value * remaining_volume.convert_to(:ml).value, :g)
39
40
  end
40
41
 
42
+ # @return [Measured::Volume]
43
+ def used_volume
44
+ items.map(&:volume).reduce(Measured::Volume(0, :ml), &:+)
45
+ end
46
+
47
+ def remaining_volume
48
+ container.inner_volume - used_volume
49
+ end
50
+
41
51
  def density
42
52
  return Measured::Density(Float::INFINITY, :g_ml) if container.volume.value.zero?
43
53
  return Measured::Density(0.0, :g_ml) if container.volume.value.infinite?
54
+
44
55
  Measured::Density(weight.convert_to(:g).value / container.volume.convert_to(:ml).value, :g_ml)
45
56
  end
46
57
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'measured'
4
+
5
+ module Physical
6
+ class Pallet < Cuboid
7
+ DEFAULT_LENGTH = BigDecimal::INFINITY
8
+ DEFAULT_MAX_WEIGHT = BigDecimal::INFINITY
9
+
10
+ attr_reader :max_weight
11
+
12
+ def initialize(**args)
13
+ max_weight = args.delete(:max_weight) || Measured::Weight(DEFAULT_MAX_WEIGHT, :g)
14
+ super(**args)
15
+ @max_weight = Types::Weight[max_weight]
16
+ end
17
+
18
+ alias_method :inner_volume, :volume
19
+ alias_method :inner_dimensions, :dimensions
20
+ alias_method :inner_length, :length
21
+ alias_method :inner_width, :width
22
+ alias_method :inner_height, :height
23
+
24
+ # @param [Physical::Package] package
25
+ # @return [Boolean]
26
+ def package_fits?(package)
27
+ return false if package.weight > max_weight
28
+
29
+ pallet_dimensions = dimensions.sort
30
+ package.dimensions.sort.each.with_index do |axis, index|
31
+ return false if axis >= pallet_dimensions.sort[index]
32
+ end
33
+ true
34
+ end
35
+ end
36
+ end
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
4
-
5
3
  FactoryBot.define do
6
4
  factory :physical_box, class: "Physical::Box" do
7
5
  dimensions { [20, 15, 30].map { |d| Measured::Length(d, :cm) } }
8
6
  inner_dimensions { dimensions.map { |d| d - Measured::Length(1, :cm) } }
9
7
  weight { Measured::Weight(0.1, :kg) }
10
- initialize_with { new(attributes) }
8
+ initialize_with { new(**attributes) }
11
9
  end
12
10
  end
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
4
-
5
3
  FactoryBot.define do
6
4
  factory :physical_item, class: "Physical::Item" do
7
- dimensions { [1, 2, 3].map { |d| Measured::Length(d, :cm)} }
5
+ dimensions { [1, 2, 3].map { |d| Measured::Length(d, :cm) } }
8
6
  weight { Measured::Weight(50, :g) }
9
- initialize_with { new(attributes) }
7
+ initialize_with { new(**attributes) }
10
8
  end
11
9
  end
@@ -12,10 +12,10 @@ FactoryBot.define do
12
12
  address1 { '11 Lovely Street' }
13
13
  address2 { 'South' }
14
14
  city { 'Herndon' }
15
- sequence(:zip, 10001) { |i| i.to_s }
15
+ sequence(:zip, 10_001, &:to_s)
16
16
  phone { '555-555-0199' }
17
17
  region { country.subregions.coded(region_code) }
18
18
  country { Carmen::Country.coded(country_code) }
19
- initialize_with { new(attributes) }
19
+ initialize_with { new(**attributes) }
20
20
  end
21
21
  end
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
4
- require_relative 'box_factory'
5
- require_relative 'item_factory'
6
-
7
3
  FactoryBot.define do
8
4
  factory :physical_package, class: "Physical::Package" do
9
5
  container { FactoryBot.build(:physical_box) }
10
6
  items { build_list(:physical_item, 2) }
11
7
  void_fill_density { Measured::Density(0.01, :g_ml) }
12
- initialize_with { new(attributes) }
8
+ initialize_with { new(**attributes) }
13
9
  end
14
10
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :physical_pallet, class: "Physical::Pallet" do
5
+ dimensions { [80, 120, 165].map { |d| Measured::Length(d, :cm) } }
6
+ weight { Measured::Weight(22, :kg) }
7
+ initialize_with { new(**attributes) }
8
+ end
9
+ end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_bot'
4
- require_relative 'location_factory'
5
- require_relative 'package_factory'
6
-
7
3
  FactoryBot.define do
8
4
  factory :physical_shipment, class: "Physical::Shipment" do
9
5
  origin { FactoryBot.build(:physical_location) }
10
6
  destination { FactoryBot.build(:physical_location) }
11
7
  packages { build_list(:physical_package, 2) }
12
8
  service_code { "usps_priority_mail" }
13
- initialize_with { new(attributes) }
9
+ initialize_with { new(**attributes) }
14
10
  end
15
11
  end
@@ -28,4 +28,18 @@ RSpec.shared_examples 'a cuboid' do
28
28
  expect(subject.width).to eq(Measured::Length.new(3.3, :cm))
29
29
  expect(subject.height).to eq(Measured::Length.new(2.2, :cm))
30
30
  end
31
+
32
+ describe "#==" do
33
+ let(:args) { Hash[id: 123] }
34
+ let(:other_cuboid) { described_class.new(**args) }
35
+ let(:non_cuboid) { double(id: 123) }
36
+
37
+ it "compares cuboids" do
38
+ aggregate_failures do
39
+ expect(subject == other_cuboid).to be(true)
40
+ expect(subject == non_cuboid).to be(false)
41
+ expect(subject.nil?).to be(false)
42
+ end
43
+ end
44
+ end
31
45
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Add to spec_helper.rb to require Physical factories:
4
+ #
5
+ # require "physical/test_support"
6
+ # FactoryBot.definition_file_paths.concat(Physical::TestSupport.factory_paths)
7
+ # FactoryBot.reload
8
+
9
+ module Physical
10
+ module TestSupport
11
+ def self.factory_paths
12
+ spec = Gem::Specification.find_by_name("physical")
13
+ root = Pathname.new(spec.gem_dir)
14
+ Dir[
15
+ root.join("lib", "physical", "spec_support", "factories", "*_factory.rb")
16
+ ].map { |path| path.sub(/.rb\z/, "") }
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'measured'
2
4
  require 'dry-types'
3
5
 
@@ -9,6 +11,7 @@ module Physical
9
11
  Length = Types.Instance(::Measured::Length)
10
12
  Volume = Types.Instance(::Measured::Volume)
11
13
  Density = Types.Instance(::Measured::Density)
14
+ Money = Types.Instance(::Money)
12
15
 
13
16
  Dimensions = Types::Strict::Array.of(Length)
14
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Physical
4
- VERSION = "0.4.3"
4
+ VERSION = "0.4.5"
5
5
  end
data/lib/physical.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "money"
3
4
  require "measured/density"
4
5
  require "physical/types"
5
6
  require "physical/version"
6
7
  require "physical/cuboid"
7
8
  require "physical/box"
8
9
  require "physical/package"
10
+ require "physical/pallet"
9
11
  require "physical/item"
10
12
  require "physical/location"
11
13
  require "physical/shipment"
data/physical.gemspec CHANGED
@@ -21,11 +21,15 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
  spec.required_ruby_version = '>= 2.4'
23
23
  spec.add_runtime_dependency "carmen", "~> 1.0"
24
+ spec.add_runtime_dependency "dry-types", "~> 1.5.1"
24
25
  spec.add_runtime_dependency "measured", "~> 2.4"
25
- spec.add_runtime_dependency "dry-types", "~> 1.0.0"
26
+ spec.add_runtime_dependency "money", ">= 5"
26
27
 
27
28
  spec.add_development_dependency "bundler", [">= 1.16", "< 3"]
28
- spec.add_development_dependency "factory_bot", "~> 4.8"
29
- spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "factory_bot", "~> 6.2"
30
+ spec.add_development_dependency "rake", ">= 12.3.3"
30
31
  spec.add_development_dependency "rspec", "~> 3.0"
32
+ spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
33
+ spec.add_development_dependency "rubocop"
34
+ spec.add_development_dependency "simplecov"
31
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: physical
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Meyerhoff
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-14 00:00:00.000000000 Z
11
+ date: 2022-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: carmen
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: measured
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +53,19 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '2.4'
41
55
  - !ruby/object:Gem::Dependency
42
- name: dry-types
56
+ name: money
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: 1.0.0
61
+ version: '5'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: 1.0.0
68
+ version: '5'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -78,28 +92,28 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: '4.8'
95
+ version: '6.2'
82
96
  type: :development
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: '4.8'
102
+ version: '6.2'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rake
91
105
  requirement: !ruby/object:Gem::Requirement
92
106
  requirements:
93
- - - "~>"
107
+ - - ">="
94
108
  - !ruby/object:Gem::Version
95
- version: '10.0'
109
+ version: 12.3.3
96
110
  type: :development
97
111
  prerelease: false
98
112
  version_requirements: !ruby/object:Gem::Requirement
99
113
  requirements:
100
- - - "~>"
114
+ - - ">="
101
115
  - !ruby/object:Gem::Version
102
- version: '10.0'
116
+ version: 12.3.3
103
117
  - !ruby/object:Gem::Dependency
104
118
  name: rspec
105
119
  requirement: !ruby/object:Gem::Requirement
@@ -114,6 +128,48 @@ dependencies:
114
128
  - - "~>"
115
129
  - !ruby/object:Gem::Version
116
130
  version: '3.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rspec_junit_formatter
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.4'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.4'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rubocop
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: simplecov
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
117
173
  description: A package with boxes and items
118
174
  email:
119
175
  - mamhoff@gmail.com
@@ -124,8 +180,8 @@ files:
124
180
  - ".circleci/config.yml"
125
181
  - ".gitignore"
126
182
  - ".rspec"
183
+ - ".rubocop-relaxed.yml"
127
184
  - ".rubocop.yml"
128
- - ".ruby-version"
129
185
  - ".travis.yml"
130
186
  - CHANGELOG.md
131
187
  - CODE_OF_CONDUCT.md
@@ -142,14 +198,16 @@ files:
142
198
  - lib/physical/item.rb
143
199
  - lib/physical/location.rb
144
200
  - lib/physical/package.rb
201
+ - lib/physical/pallet.rb
145
202
  - lib/physical/shipment.rb
146
- - lib/physical/spec_support/factories.rb
147
203
  - lib/physical/spec_support/factories/box_factory.rb
148
204
  - lib/physical/spec_support/factories/item_factory.rb
149
205
  - lib/physical/spec_support/factories/location_factory.rb
150
206
  - lib/physical/spec_support/factories/package_factory.rb
207
+ - lib/physical/spec_support/factories/pallet_factory.rb
151
208
  - lib/physical/spec_support/factories/shipment_factory.rb
152
209
  - lib/physical/spec_support/shared_examples.rb
210
+ - lib/physical/test_support.rb
153
211
  - lib/physical/types.rb
154
212
  - lib/physical/version.rb
155
213
  - physical.gemspec
@@ -157,7 +215,7 @@ homepage: https://github.com/friendlycart/physical
157
215
  licenses:
158
216
  - MIT
159
217
  metadata: {}
160
- post_install_message:
218
+ post_install_message:
161
219
  rdoc_options: []
162
220
  require_paths:
163
221
  - lib
@@ -172,9 +230,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
230
  - !ruby/object:Gem::Version
173
231
  version: '0'
174
232
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 2.6.14.1
177
- signing_key:
233
+ rubygems_version: 3.1.6
234
+ signing_key:
178
235
  specification_version: 4
179
236
  summary: A facade to deal with physical packages
180
237
  test_files: []
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.4.4
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'physical/spec_support/factories/item_factory'
4
- require 'physical/spec_support/factories/box_factory'
5
- require 'physical/spec_support/factories/package_factory'
6
- require 'physical/spec_support/factories/location_factory'
7
- require 'physical/spec_support/factories/shipment_factory'