box_packer 1.2.0 → 1.2.1

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: cb419643a33b63ce8d279f9baafa0c2e4c010300
4
- data.tar.gz: a5174fcc00bc4ccb58542182ac40a7aceef95f14
3
+ metadata.gz: 4659a59306f377ffb56826c4066f6a8cd59a3ed6
4
+ data.tar.gz: 1f789104af76b44e14a8aedada8cc4e1a8a7a9ff
5
5
  SHA512:
6
- metadata.gz: fa82429a9a668dafdc268f9bc85d46261b9b9742a31099c87cb37870ce8cc6af3b8c358cc5babd5ebfd8e39549caa16344aef181737fdb33a1616b1696423cf4
7
- data.tar.gz: 82af4730e2b2b13dc9868398a65b76f46561663ba0e158b606e8502aa3a4c569b9b42b7e22f83399420cbae3ad19368908c8fd0d01c4e3c036db594ed20e64f4
6
+ metadata.gz: 3d245edfff6dc2ba6af12e65dcab58215eb2b9ae21bb71b953d8f98c6421f237f699487f46ae946a3ea89a631cdb92c43f1c4fef5e7556748c45dedaba3e18e0
7
+ data.tar.gz: 9751c392ce1c08783d1c265b28677e6e53dca4bf0a1f5475c38d80af3b5610b65bf6d18ed5c68be52613b3195bd69085c36e77ed0615af68cd677497854c9b13
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  BoxPacker
2
2
  =========
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/box_packer.svg)](http://badge.fury.io/rb/box_packer)
5
+
4
6
  A heuristic first-fit 3D bin packing algorithm with optional weight and bin limits.
5
7
 
6
8
  Installation
@@ -10,4 +10,3 @@ require 'box_packer/packing'
10
10
  require 'box_packer/svg_exporter'
11
11
  require 'box_packer/container'
12
12
  require 'box_packer/builder'
13
- require 'box_packer/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: box_packer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max White
@@ -11,63 +11,67 @@ cert_chain: []
11
11
  date: 2015-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: attire
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.1'
20
- type: :development
19
+ version: '0.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.3
23
+ type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '3.1'
29
+ version: '0.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.0.3
27
33
  - !ruby/object:Gem::Dependency
28
- name: attire
34
+ name: rasem
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '0'
39
+ version: '0.6'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '0'
46
+ version: '0.6'
41
47
  - !ruby/object:Gem::Dependency
42
- name: rasem
48
+ name: rspec
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '0.6'
48
- type: :runtime
53
+ version: '3.1'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 3.1.0
57
+ type: :development
49
58
  prerelease: false
50
59
  version_requirements: !ruby/object:Gem::Requirement
51
60
  requirements:
52
61
  - - "~>"
53
62
  - !ruby/object:Gem::Version
54
- version: '0.6'
63
+ version: '3.1'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 3.1.0
55
67
  description:
56
- email:
57
- - mushishi78@gmail.com
68
+ email: mushishi78@gmail.com
58
69
  executables: []
59
70
  extensions: []
60
71
  extra_rdoc_files: []
61
72
  files:
62
- - ".gitignore"
63
- - ".rspec"
64
- - ".rubocop.yml"
65
- - Gemfile
66
73
  - LICENSE.txt
67
74
  - README.md
68
- - Rakefile
69
- - box_packer.gemspec
70
- - examples/example1.svg
71
75
  - lib/box_packer.rb
72
76
  - lib/box_packer/box.rb
73
77
  - lib/box_packer/builder.rb
@@ -78,16 +82,7 @@ files:
78
82
  - lib/box_packer/packing.rb
79
83
  - lib/box_packer/position.rb
80
84
  - lib/box_packer/svg_exporter.rb
81
- - lib/box_packer/version.rb
82
- - spec/lib/box_spec.rb
83
- - spec/lib/container_spec.rb
84
- - spec/lib/dimensions_spec.rb
85
- - spec/lib/item_spec.rb
86
- - spec/lib/packer_spec.rb
87
- - spec/lib/packing_spec.rb
88
- - spec/spec_helper.rb
89
- - spec/support/matchers/yield_each_once.rb
90
- homepage: https://github.com/mushishi78/box_packer
85
+ homepage:
91
86
  licenses:
92
87
  - MIT
93
88
  metadata: {}
@@ -110,14 +105,5 @@ rubyforge_project:
110
105
  rubygems_version: 2.2.2
111
106
  signing_key:
112
107
  specification_version: 4
113
- summary: Heuristic first-fit 3D bin-packing algorithmwith optional weight and bin
114
- limits.
115
- test_files:
116
- - spec/lib/box_spec.rb
117
- - spec/lib/container_spec.rb
118
- - spec/lib/dimensions_spec.rb
119
- - spec/lib/item_spec.rb
120
- - spec/lib/packer_spec.rb
121
- - spec/lib/packing_spec.rb
122
- - spec/spec_helper.rb
123
- - spec/support/matchers/yield_each_once.rb
108
+ summary: 3D bin-packing algorithm with optional weight and bin limits.
109
+ test_files: []
data/.gitignore DELETED
@@ -1,15 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.bundle
11
- *.so
12
- *.o
13
- *.a
14
- mkmf.log
15
- *.gem
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
@@ -1,4 +0,0 @@
1
- Metrics/LineLength:
2
- Max: 100
3
- Documentation:
4
- Enabled: false
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in box_packer.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1 +0,0 @@
1
- require 'bundler/gem_tasks'
@@ -1,24 +0,0 @@
1
- lib = File.expand_path('../lib', __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'box_packer/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'box_packer'
7
- spec.version = BoxPacker::VERSION
8
- spec.authors = ['Max White']
9
- spec.email = ['mushishi78@gmail.com']
10
- spec.summary = 'Heuristic first-fit 3D bin-packing algorithm' \
11
- 'with optional weight and bin limits.'
12
- spec.homepage = 'https://github.com/mushishi78/box_packer'
13
- spec.license = 'MIT'
14
-
15
- spec.files = `git ls-files -z`.split("\x0")
16
- spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(/^(test|spec|features)/)
18
- spec.require_paths = ['lib']
19
-
20
- spec.add_development_dependency 'rspec', '~> 3.1'
21
-
22
- spec.add_dependency 'attire', '~> 0'
23
- spec.add_dependency 'rasem', '~> 0.6'
24
- end
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
- <svg width="1045.0" height="1185.0" version="1.1"
5
- xmlns="http://www.w3.org/2000/svg">
6
- <rect x="15" y="15" width="500.0" height="375.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="15.0" y="15.0" width="375.0" height="375.0" rx="0" ry="0" style="fill:blue;"/><text x="199.5" y="202.5" style="fill:black;"><tspan x="199.5" dy="0em">Hat</tspan></text><rect x="390.0" y="15.0" width="125.0" height="250.0" rx="0" ry="0" style="fill:green;"/><text x="447.5" y="140.0" style="fill:black;"><tspan x="447.5" dy="0em">Shoes</tspan></text><rect x="390.0" y="265.0" width="125.0" height="125.0" rx="0" ry="0" style="fill:orange;"/><text x="446.5" y="327.5" style="fill:black;"><tspan x="446.5" dy="0em">Dragon</tspan></text><rect x="15.0" y="15.0" width="375.0" height="250.0" rx="0" ry="0" style="fill:red;"/><text x="199.5" y="140.0" style="fill:black;"><tspan x="199.5" dy="0em">Bag</tspan></text><rect x="15.0" y="265.0" width="375.0" height="125.0" rx="0" ry="0" style="fill:purple;"/><text x="195.5" y="327.5" style="fill:black;"><tspan x="195.5" dy="0em">Slipper</tspan></text><rect x="530.0" y="15" width="500.0" height="375.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="530.0" y="265.0" width="375.0" height="125.0" rx="0" ry="0" style="fill:purple;"/><text x="710.5" y="327.5" style="fill:black;"><tspan x="710.5" dy="0em">Slipper</tspan></text><rect x="530.0" y="15.0" width="375.0" height="250.0" rx="0" ry="0" style="fill:red;"/><text x="714.5" y="140.0" style="fill:black;"><tspan x="714.5" dy="0em">Bag</tspan></text><rect x="905.0" y="265.0" width="125.0" height="125.0" rx="0" ry="0" style="fill:orange;"/><text x="961.5" y="327.5" style="fill:black;"><tspan x="961.5" dy="0em">Dragon</tspan></text><rect x="905.0" y="15.0" width="125.0" height="250.0" rx="0" ry="0" style="fill:green;"/><text x="962.5" y="140.0" style="fill:black;"><tspan x="962.5" dy="0em">Shoes</tspan></text><rect x="530.0" y="15.0" width="375.0" height="375.0" rx="0" ry="0" style="fill:blue;"/><text x="714.5" y="202.5" style="fill:black;"><tspan x="714.5" dy="0em">Hat</tspan></text><rect x="15" y="405.0" width="375.0" height="250.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="15.0" y="405.0" width="375.0" height="125.0" rx="0" ry="0" style="fill:blue;"/><text x="199.5" y="467.5" style="fill:black;"><tspan x="199.5" dy="0em">Hat</tspan></text><rect x="15.0" y="530.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:red;"/><text x="137.0" y="592.5" style="fill:black;"><tspan x="137.0" dy="0em">Bag</tspan></text><rect x="265.0" y="530.0" width="125.0" height="125.0" rx="0" ry="0" style="fill:purple;"/><text x="320.5" y="592.5" style="fill:black;"><tspan x="320.5" dy="0em">Slipper</tspan></text><rect x="15.0" y="405.0" width="250.0" height="250.0" rx="0" ry="0" style="fill:green;"/><text x="135.0" y="530.0" style="fill:black;"><tspan x="135.0" dy="0em">Shoes</tspan></text><rect x="265.0" y="405.0" width="125.0" height="250.0" rx="0" ry="0" style="fill:orange;"/><text x="321.5" y="530.0" style="fill:black;"><tspan x="321.5" dy="0em">Dragon</tspan></text><rect x="405.0" y="405.0" width="375.0" height="250.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="655.0" y="405.0" width="125.0" height="250.0" rx="0" ry="0" style="fill:orange;"/><text x="711.5" y="530.0" style="fill:black;"><tspan x="711.5" dy="0em">Dragon</tspan></text><rect x="405.0" y="405.0" width="250.0" height="250.0" rx="0" ry="0" style="fill:green;"/><text x="525.0" y="530.0" style="fill:black;"><tspan x="525.0" dy="0em">Shoes</tspan></text><rect x="655.0" y="530.0" width="125.0" height="125.0" rx="0" ry="0" style="fill:purple;"/><text x="710.5" y="592.5" style="fill:black;"><tspan x="710.5" dy="0em">Slipper</tspan></text><rect x="405.0" y="530.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:red;"/><text x="527.0" y="592.5" style="fill:black;"><tspan x="527.0" dy="0em">Bag</tspan></text><rect x="405.0" y="405.0" width="375.0" height="125.0" rx="0" ry="0" style="fill:blue;"/><text x="589.5" y="467.5" style="fill:black;"><tspan x="589.5" dy="0em">Hat</tspan></text><rect x="15" y="670.0" width="250.0" height="500.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="15.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:blue;"/><text x="74.5" y="857.5" style="fill:black;"><tspan x="74.5" dy="0em">Hat</tspan></text><rect x="140.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:red;"/><text x="199.5" y="857.5" style="fill:black;"><tspan x="199.5" dy="0em">Bag</tspan></text><rect x="15.0" y="1045.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:green;"/><text x="135.0" y="1107.5" style="fill:black;"><tspan x="135.0" dy="0em">Shoes</tspan></text><rect x="140.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:purple;"/><text x="195.5" y="857.5" style="fill:black;"><tspan x="195.5" dy="0em">Slipper</tspan></text><rect x="15.0" y="1045.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:orange;"/><text x="134.0" y="1107.5" style="fill:black;"><tspan x="134.0" dy="0em">Dragon</tspan></text><rect x="280.0" y="670.0" width="250.0" height="500.0" rx="0" ry="0" style="stroke:black;stroke-width:1;fill:white;"/><rect x="280.0" y="1045.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:orange;"/><text x="399.0" y="1107.5" style="fill:black;"><tspan x="399.0" dy="0em">Dragon</tspan></text><rect x="405.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:purple;"/><text x="460.5" y="857.5" style="fill:black;"><tspan x="460.5" dy="0em">Slipper</tspan></text><rect x="280.0" y="1045.0" width="250.0" height="125.0" rx="0" ry="0" style="fill:green;"/><text x="400.0" y="1107.5" style="fill:black;"><tspan x="400.0" dy="0em">Shoes</tspan></text><rect x="405.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:red;"/><text x="464.5" y="857.5" style="fill:black;"><tspan x="464.5" dy="0em">Bag</tspan></text><rect x="280.0" y="670.0" width="125.0" height="375.0" rx="0" ry="0" style="fill:blue;"/><text x="339.5" y="857.5" style="fill:black;"><tspan x="339.5" dy="0em">Hat</tspan></text></svg>
@@ -1,3 +0,0 @@
1
- module BoxPacker
2
- VERSION = '1.2.0'
3
- end
@@ -1,52 +0,0 @@
1
- module BoxPacker
2
- describe Box do
3
- subject(:box) { Box.new(dimensions, position: position) }
4
- let(:dimensions) { Dimensions[25, 30, 10] }
5
- let(:position) { Position[10, 25, 5] }
6
- let(:item) { Item.new(Dimensions[5, 2, 1]) }
7
-
8
- context 'if no position is given' do
9
- let(:position) { nil }
10
-
11
- it 'defaults to origin position' do
12
- expect(box.position).to eql(Position[0, 0, 0])
13
- end
14
- end
15
-
16
- describe '#orient!' do
17
- before { box.orient! }
18
- it { expect(box.dimensions).to eql(Dimensions[30, 25, 10]) }
19
- end
20
-
21
- describe '#sub_boxes_args' do
22
- let(:expected_args) do
23
- [
24
- [Dimensions[20, 30, 10], position: Position[15, 25, 5]],
25
- [Dimensions[5, 28, 10], position: Position[10, 27, 5]],
26
- [Dimensions[5, 2, 9], position: Position[10, 25, 6]]
27
- ]
28
- end
29
-
30
- it 'calculates the correct dimensions and positions' do
31
- expect(box.send(:sub_boxes_args, item)).to eql(expected_args)
32
- end
33
- end
34
-
35
- describe '#sub_boxes' do
36
- it 'orders sub-boxes by volumes' do
37
- sub_boxes = box.sub_boxes(item)
38
- expect(sub_boxes[0].volume).to be >= (sub_boxes[1].volume)
39
- expect(sub_boxes[1].volume).to be >= (sub_boxes[2].volume)
40
- end
41
-
42
- context 'with an item that reaches a side' do
43
- let(:item) { Box.new(Dimensions[15, 2, 10]) }
44
-
45
- it 'only returns 2 sub-boxes' do
46
- sub_boxes = box.sub_boxes(item)
47
- expect(sub_boxes.length).to eql(2)
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,89 +0,0 @@
1
- module BoxPacker
2
- describe Container do
3
- subject(:container) { Container.new([25, 30, 15]) }
4
-
5
- it { expect(container.packings).to eql(nil) }
6
-
7
- context 'with items' do
8
- let(:items) do
9
- [
10
- Item.new([15, 24, 8], weight: 25),
11
- Item.new([2, 1, 2], weight: 6),
12
- Item.new([9, 9, 10], weight: 30)
13
- ]
14
- end
15
- before { container.items = items }
16
-
17
- context 'with container prepared' do
18
- before do
19
- container.send(:prepare_to_pack!)
20
- end
21
-
22
- describe '#prepare_to_pack!' do
23
- let(:expected_dimensions)do
24
- [
25
- Dimensions[24, 15, 8],
26
- Dimensions[2, 2, 1],
27
- Dimensions[10, 9, 9]
28
- ]
29
- end
30
-
31
- it { expect(container.items.map(&:dimensions)).to eql(expected_dimensions) }
32
- it { expect(container.packings).to eql([]) }
33
- end
34
-
35
- context 'with some items packed' do
36
- before do
37
- container.new_packing!
38
- container.packing << items[1]
39
- container.packing << items[2]
40
- end
41
-
42
- it { expect(container.packings.length).to eql(1) }
43
- it { expect(container.packing).to match_array([items[1], items[2]]) }
44
-
45
- describe '#new_packing!!' do
46
- before { container.new_packing! }
47
- it { expect(container.packings.length).to eql(2) }
48
- it { expect(container.packing).to eql([]) }
49
- end
50
- end
51
- end
52
-
53
- describe '#packable?' do
54
- context 'with no items' do
55
- before { container.items = [] }
56
- it { expect(container.send(:packable?)).to be(false) }
57
- end
58
-
59
- context 'with items that fit' do
60
- it { expect(container.send(:packable?)).to be(true) }
61
- end
62
-
63
- context 'with an item to large' do
64
- before { container.items[0].dimensions = Dimensions[26, 34, 8] }
65
- it { expect(container.send(:packable?)).to be(false) }
66
- end
67
-
68
- context 'with a weight limit thats lighter than one of the items' do
69
- before { container.weight_limit = 24 }
70
- it { expect(container.send(:packable?)).to be(false) }
71
- end
72
-
73
- context 'with a packings limit of one packing' do
74
- before { container.packings_limit = 1 }
75
-
76
- context 'with a weight limit thats lighter than items' do
77
- before { container.weight_limit = 50 }
78
- it { expect(container.send(:packable?)).to be(false) }
79
- end
80
-
81
- context 'with a weight limit thats heavier than items' do
82
- before { container.weight_limit = 70 }
83
- it { expect(container.send(:packable?)).to be(true) }
84
- end
85
- end
86
- end
87
- end
88
- end
89
- end
@@ -1,54 +0,0 @@
1
- require_relative '../support/matchers/yield_each_once'
2
-
3
- module BoxPacker
4
- describe Dimensions do
5
- include BoxPacker::Matchers
6
- subject(:dimensions) { Dimensions[2, 10, 3] }
7
-
8
- describe '#volume' do
9
- it { expect(dimensions.volume).to eql(60) }
10
- end
11
-
12
- describe '#>=' do
13
- context 'when compared with Dimensions that are all bigger' do
14
- let(:other_dimensions) { Dimensions[1, 5, 2] }
15
- it { expect(dimensions >= other_dimensions).to be(true) }
16
- end
17
-
18
- context 'when compared with Dimensions where some are bigger and some are equal' do
19
- let(:other_dimensions) { Dimensions[2, 5, 3] }
20
- it { expect(dimensions >= other_dimensions).to be(true) }
21
- end
22
-
23
- context 'when compared with Dimensions that are all equal' do
24
- let(:other_dimensions) { Dimensions[2, 10, 3] }
25
- it { expect(dimensions >= other_dimensions).to be(true) }
26
- end
27
-
28
- context 'when compared with Dimensions where some are bigger and some are smaller' do
29
- let(:other_dimensions) { Dimensions[5, 5, 1] }
30
- it { expect(dimensions >= other_dimensions).to be(false) }
31
- end
32
-
33
- context 'when compared with Dimensions where none are bigger' do
34
- let(:other_dimensions) { Dimensions[5, 15, 11] }
35
- it { expect(dimensions >= other_dimensions).to be(false) }
36
- end
37
- end
38
-
39
- describe '#each_rotation' do
40
- let(:rotations)do
41
- [
42
- Dimensions[2, 10, 3],
43
- Dimensions[2, 3, 10],
44
- Dimensions[10, 2, 3],
45
- Dimensions[10, 3, 2],
46
- Dimensions[3, 10, 2],
47
- Dimensions[3, 2, 10]
48
- ]
49
- end
50
-
51
- it { expect { |b| dimensions.each_rotation(&b) }.to yield_each_once(rotations) }
52
- end
53
- end
54
- end
@@ -1,27 +0,0 @@
1
- module BoxPacker
2
- describe Item do
3
- subject(:item) { Item.new(dimensions) }
4
- let(:dimensions) { [12, 5, 7] }
5
-
6
- describe '#fit_into' do
7
- context 'when box is larger than box' do
8
- let(:box) { Box.new(Dimensions[6, 15, 9]) }
9
- let(:rotated_dimensions) { Dimensions[5, 12, 7] }
10
-
11
- it 'fits and orientation is rotated to fit' do
12
- expect(item.fit_into?(box)).to be(true)
13
- expect(item.dimensions).to eql(rotated_dimensions)
14
- end
15
- end
16
-
17
- context 'when other box has a smaller side than box' do
18
- let(:box) { Box.new(Dimensions[11, 6, 7]) }
19
-
20
- it 'does not fit and orientation is unchanged' do
21
- expect(item.fit_into?(box)).to be(false)
22
- expect(item.dimensions).to eql(Dimensions[*dimensions])
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,80 +0,0 @@
1
- module BoxPacker
2
- describe Packer do
3
- subject(:container) { Container.new(dimensions) }
4
- let(:dimensions) { [10, 15, 5] }
5
- let(:opts) { nil }
6
- let(:items)do
7
- [
8
- Item.new([1, 1, 1], weight: 1),
9
- Item.new([3, 1, 1], weight: 6),
10
- Item.new([5, 5, 1], weight: 15),
11
- Item.new([5, 5, 5], weight: 20)
12
- ]
13
- end
14
-
15
- describe '#pack' do
16
- context 'with items that fit exactly in one packing' do
17
- before do
18
- 20.times { container.items << items[0].dup }
19
- 10.times { container.items << items[1].dup }
20
- 8.times { container.items << items[2].dup }
21
- 4.times { container.items << items[3].dup }
22
- end
23
-
24
- it do
25
- expect(container.pack!).to eql(1)
26
- expect(container.packed_successfully).to be(true)
27
- end
28
- end
29
-
30
- context 'with items that fit exactly in three packings' do
31
- before do
32
- 35.times { container.items << items[0].dup }
33
- 30.times { container.items << items[1].dup }
34
- 10.times { container.items << items[2].dup }
35
- 15.times { container.items << items[3].dup }
36
- end
37
-
38
- it do
39
- expect(container.pack!).to eql(3)
40
- expect(container.packed_successfully).to be(true)
41
- end
42
- end
43
-
44
- context 'with a packing limit of one and too many items' do
45
- before do
46
- container.packings_limit = 1
47
- 35.times { container.items << items[0].dup }
48
- 30.times { container.items << items[1].dup }
49
- 10.times { container.items << items[2].dup }
50
- 15.times { container.items << items[3].dup }
51
- end
52
-
53
- it do
54
- expect(container.pack!).to be(false)
55
- expect(container.packed_successfully).to be(false)
56
- end
57
- end
58
-
59
- context 'with random container and random items' do
60
- let(:dimensions) { [x, y, z] }
61
- let(:x) { rand(1..75) }
62
- let(:y) { rand(1..75) }
63
- let(:z) { rand(1..75) }
64
-
65
- let(:items) do
66
- (1..rand(1..100)).map do
67
- Item.new([x / rand(1..5), y / rand(1..5), z / rand(1..5)])
68
- end
69
- end
70
-
71
- before do
72
- container.items = items
73
- container.pack!
74
- end
75
-
76
- it { expect(container.packed_successfully).to be(true) }
77
- end
78
- end
79
- end
80
- end
@@ -1,76 +0,0 @@
1
- module BoxPacker
2
- describe Packing do
3
- subject(:packing) { Packing.new(total_volume, total_weight) }
4
- let(:total_volume) { 200 }
5
- let(:total_weight) { 50 }
6
- let(:items) do
7
- [
8
- Item.new([2, 4, 1], weight: 5),
9
- Item.new([5, 2, 7], weight: 6),
10
- Item.new([8, 4, 2], weight: 3)
11
- ]
12
- end
13
-
14
- it 'defaults to empty' do
15
- expect(packing).to eql([])
16
- end
17
-
18
- describe '#<<' do
19
- before { items.each { |i| packing << i } }
20
-
21
- it { expect(packing.remaining_volume).to eql(58) }
22
- it { expect(packing.remaining_weight).to eql(36) }
23
-
24
- context 'with items that do not have weight' do
25
- let(:items) do
26
- [
27
- Item.new([2, 4, 1]),
28
- Item.new([5, 2, 7]),
29
- Item.new([8, 4, 2])
30
- ]
31
- end
32
-
33
- it { expect(packing.remaining_weight).to be(50) }
34
- end
35
-
36
- context 'with total_weight nil' do
37
- let(:total_weight) { nil }
38
- it { expect(packing.remaining_weight).to be(nil) }
39
- end
40
- end
41
-
42
- describe '#fit?' do
43
- before { items.each { |i| packing << i } }
44
-
45
- context 'with item that fits' do
46
- let(:item) { Item.new([1, 5, 5], weight: 5) }
47
- it { expect(packing.fit?(item)).to be(true) }
48
- end
49
-
50
- context 'with item thats already packed' do
51
- it { expect(packing.fit?(items[0])).to be(false) }
52
- end
53
-
54
- context 'with item thats too large' do
55
- let(:item) { Item.new([3, 5, 5], weight: 25) }
56
- it { expect(packing.fit?(item)).to be(false) }
57
- end
58
-
59
- context 'with item thats too heavy' do
60
- let(:item) { Item.new([1, 5, 5], weight: 45) }
61
- it { expect(packing.fit?(item)).to be(false) }
62
- end
63
-
64
- context 'with total_weight nil and item that fits' do
65
- let(:total_weight) { nil }
66
- let(:item) { Item.new([1, 5, 5], weight: 5) }
67
- it { expect(packing.fit?(item)).to be(true) }
68
- end
69
-
70
- context 'with item that has no weight but fits' do
71
- let(:item) { Item.new([1, 5, 5]) }
72
- it { expect(packing.fit?(item)).to be(true) }
73
- end
74
- end
75
- end
76
- end
@@ -1 +0,0 @@
1
- require 'box_packer'
@@ -1,38 +0,0 @@
1
- require 'rspec/matchers/built_in/yield'
2
-
3
- module BoxPacker
4
- module Matchers
5
- class YieldEachOnce
6
- attr_init :expected
7
-
8
- def matches?(block)
9
- @probe = RSpec::Matchers::BuiltIn::YieldProbe.probe(block)
10
- @actual = @probe.successive_yield_args
11
-
12
- @actual.each do |value|
13
- unless expected.delete(value)
14
- @failure_value = value
15
- return false
16
- end
17
- end
18
- true
19
- end
20
-
21
- def supports_block_expectations?
22
- true
23
- end
24
-
25
- def description
26
- 'be in expected array'
27
- end
28
-
29
- def failure_message
30
- "value #{@failure_value.to_a} was not in expected array"
31
- end
32
- end
33
-
34
- def yield_each_once(expected)
35
- YieldEachOnce.new(expected)
36
- end
37
- end
38
- end