vector2d 2.2.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Coercions
5
- include Contracts
6
-
7
- Contract VectorLike => [Vector2d, Vector2d]
8
5
  def coerce(other)
9
6
  case other
10
7
  when Vector2d
@@ -20,7 +17,6 @@ class Vector2d
20
17
  #
21
18
  # Vector2d(2, 3).inspect # => "Vector2d(2,3)"
22
19
  #
23
- Contract None => String
24
20
  def inspect
25
21
  "Vector2d(#{x},#{y})"
26
22
  end
@@ -29,7 +25,6 @@ class Vector2d
29
25
  #
30
26
  # Vector2d(2, 3).to_a # => [2,3]
31
27
  #
32
- Contract None => [Num, Num]
33
28
  def to_a
34
29
  [x, y]
35
30
  end
@@ -38,7 +33,6 @@ class Vector2d
38
33
  #
39
34
  # Vector2d(2, 3).to_hash # => {x: 2, y: 3}
40
35
  #
41
- Contract None => Hash
42
36
  def to_hash
43
37
  { x: x, y: y }
44
38
  end
@@ -47,7 +41,6 @@ class Vector2d
47
41
  #
48
42
  # Vector2d(2.0, 3.0).to_i_vector # => Vector2d(2,3)
49
43
  #
50
- Contract None => Vector2d
51
44
  def to_i_vector
52
45
  self.class.new(x.to_i, y.to_i)
53
46
  end
@@ -56,7 +49,6 @@ class Vector2d
56
49
  #
57
50
  # Vector2d(2, 3).to_f_vector # => Vector2d(2.0,3.0)
58
51
  #
59
- Contract None => Vector2d
60
52
  def to_f_vector
61
53
  self.class.new(x.to_f, y.to_f)
62
54
  end
@@ -65,7 +57,6 @@ class Vector2d
65
57
  #
66
58
  # Vector2d.new(150, 100).to_s # => "150x100"
67
59
  #
68
- Contract None => String
69
60
  def to_s
70
61
  "#{x}x#{y}"
71
62
  end
@@ -1,9 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Fitting
5
- include Contracts
6
-
7
5
  # Scales down the given vector unless it fits inside.
8
6
  #
9
7
  # vector = Vector2d(20, 20)
@@ -11,46 +9,52 @@ class Vector2d
11
9
  # vector.contain(Vector2d(40, 20)) # => Vector2d(20,10)
12
10
  # vector.contain(Vector2d(20, 40)) # => Vector2d(10,20)
13
11
  #
14
- Contract VectorLike => Vector2d
15
12
  def contain(other)
16
- v, _ = coerce(other)
17
- (v.x > x || v.y > y) ? other.fit(self) : other
13
+ v, = coerce(other)
14
+ v.x > x || v.y > y ? other.fit(self) : other
18
15
  end
19
16
 
20
- # Scales the vector to fit inside another vector, retaining the aspect ratio.
17
+ # Scales the vector to fit inside another vector, retaining the
18
+ # aspect ratio.
21
19
  #
22
20
  # vector = Vector2d(20, 10)
23
21
  # vector.fit(Vector2d(10, 10)) # => Vector2d(10,5)
24
22
  # vector.fit(Vector2d(20, 20)) # => Vector2d(20,10)
25
23
  # vector.fit(Vector2d(40, 40)) # => Vector2d(40,20)
26
24
  #
27
- # Note: Either axis will be disregarded if zero or nil. This is a feature, not a bug.
25
+ # Note: Either axis will be disregarded if zero or nil. This is a
26
+ # feature, not a bug.
28
27
  #
29
- Contract VectorLike => Vector2d
30
28
  def fit(other)
31
- v, _ = coerce(other)
29
+ v, = coerce(other)
32
30
  scale = v.to_f_vector / self
33
- self * ((scale.y == 0 || (scale.x > 0 && scale.x < scale.y)) ? scale.x : scale.y)
31
+ self * (
32
+ if scale.y.zero? || (scale.x.positive? && scale.x < scale.y)
33
+ scale.x
34
+ else
35
+ scale.y
36
+ end
37
+ )
34
38
  end
35
- alias_method :constrain_both, :fit
39
+ alias constrain_both fit
36
40
 
37
- # Constrain/expand so that one of the coordinates fit within (the square implied by) another vector.
41
+ # Constrain/expand so that one of the coordinates fit within (the
42
+ # square implied by) another vector.
38
43
  #
39
44
  # constraint = Vector2d(5, 5)
40
45
  # Vector2d(20, 10).fit_either(constraint) # => Vector2d(10,5)
41
46
  # Vector2d(10, 20).fit_either(constraint) # => Vector2d(5,10)
42
47
  #
43
- Contract VectorLike => Vector2d
44
48
  def fit_either(other)
45
- v, _ = coerce(other)
49
+ v, = coerce(other)
46
50
  scale = v.to_f_vector / self
47
- if (scale.x > 0 && scale.y > 0)
48
- scale = (scale.x < scale.y) ? scale.y : scale.x
51
+ if scale.x.positive? && scale.y.positive?
52
+ scale = [scale.x, scale.y].max
49
53
  self * scale
50
54
  else
51
55
  fit(v)
52
56
  end
53
57
  end
54
- alias_method :constrain_one, :fit_either
58
+ alias constrain_one fit_either
55
59
  end
56
60
  end
@@ -1,14 +1,11 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Properties
5
- include Contracts
6
-
7
5
  # Angle of vector.
8
6
  #
9
7
  # Vector2d(2, 3).angle # => 0.9827..
10
8
  #
11
- Contract None => Num
12
9
  def angle
13
10
  Math.atan2(y, x)
14
11
  end
@@ -17,16 +14,14 @@ class Vector2d
17
14
  #
18
15
  # Vector2d(2, 3).aspect_ratio # => 0.6667..
19
16
  #
20
- Contract None => Num
21
17
  def aspect_ratio
22
- (x.to_f / y.to_f).abs
18
+ (x.to_f / y).abs
23
19
  end
24
20
 
25
21
  # Length of vector.
26
22
  #
27
23
  # Vector2d(2, 3).length # => 3.6055..
28
24
  #
29
- Contract None => Num
30
25
  def length
31
26
  Math.sqrt(squared_length)
32
27
  end
@@ -35,9 +30,8 @@ class Vector2d
35
30
  #
36
31
  # Vector2d(2, 3).squared_length # => 13
37
32
  #
38
- Contract None => Num
39
33
  def squared_length
40
- x * x + y * y
34
+ (x * x) + (y * y)
41
35
  end
42
36
 
43
37
  # Is this a normalized vector?
@@ -45,9 +39,8 @@ class Vector2d
45
39
  # Vector2d(0, 1).normalized? # => true
46
40
  # Vector2d(2, 3).normalized? # => false
47
41
  #
48
- Contract None => Bool
49
42
  def normalized?
50
- self.length.to_f == 1.0
43
+ (length.to_f - 1.0).abs < Float::EPSILON
51
44
  end
52
45
  end
53
46
  end
@@ -1,23 +1,32 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Transformations
5
- include Contracts
6
-
7
5
  # Rounds vector to up nearest integer.
8
6
  #
9
7
  # Vector2d(2.4, 3.6).ceil # => Vector2d(3,4)
10
8
  #
11
- Contract None => Vector2d
12
9
  def ceil
13
10
  self.class.new(x.ceil, y.ceil)
14
11
  end
15
12
 
13
+ # Clamps the vector between two others, one axis at a time.
14
+ # The bounds are coerced, so scalars work too.
15
+ #
16
+ # vector = Vector2d(2, 8)
17
+ # vector.clamp(Vector2d(3, 3), Vector2d(6, 6)) # => Vector2d(3,6)
18
+ # vector.clamp(3, 6) # => Vector2d(3,6)
19
+ #
20
+ def clamp(min, max)
21
+ min_v, = coerce(min)
22
+ max_v, = coerce(max)
23
+ self.class.new(x.clamp(min_v.x, max_v.x), y.clamp(min_v.y, max_v.y))
24
+ end
25
+
16
26
  # Rounds vector to up nearest integer.
17
27
  #
18
28
  # Vector2d(2.4, 3.6).floor # => Vector2d(2,3)
19
29
  #
20
- Contract None => Vector2d
21
30
  def floor
22
31
  self.class.new(x.floor, y.floor)
23
32
  end
@@ -28,7 +37,6 @@ class Vector2d
28
37
  # vector.normalize # => Vector2d(0.5547.., 0.8320..)
29
38
  # vector.normalize.length # => 1.0
30
39
  #
31
- Contract None => Vector2d
32
40
  def normalize
33
41
  resize(1.0)
34
42
  end
@@ -37,7 +45,6 @@ class Vector2d
37
45
  #
38
46
  # Vector2d(2, 3).perpendicular # => Vector2d(-3,2)
39
47
  #
40
- Contract None => Vector2d
41
48
  def perpendicular
42
49
  Vector2d.new(-y, x)
43
50
  end
@@ -46,16 +53,14 @@ class Vector2d
46
53
  #
47
54
  # Vector2d(2, 3).resize(1.0) # => Vector2d(0.5547.., 0.8320..)
48
55
  #
49
- Contract Num => Vector2d
50
56
  def resize(new_length)
51
- self * (new_length / self.length)
57
+ self * (new_length / length)
52
58
  end
53
59
 
54
60
  # Reverses the vector.
55
61
  #
56
62
  # Vector2d(2, 3).reverse # => Vector2d(-2,-3)
57
63
  #
58
- Contract None => Vector2d
59
64
  def reverse
60
65
  self.class.new(-x, -y)
61
66
  end
@@ -64,11 +69,10 @@ class Vector2d
64
69
  #
65
70
  # Vector2d(1, 0).rotate(Math:PI/2) => Vector2d(1,0)
66
71
  #
67
- Contract Num => Vector2d
68
72
  def rotate(angle)
69
73
  Vector2d.new(
70
- x * Math.cos(angle) - y * Math.sin(angle),
71
- x * Math.sin(angle) + y * Math.cos(angle)
74
+ (x * Math.cos(angle)) - (y * Math.sin(angle)),
75
+ (x * Math.sin(angle)) + (y * Math.cos(angle))
72
76
  )
73
77
  end
74
78
 
@@ -77,8 +81,7 @@ class Vector2d
77
81
  # Vector2d(2.4, 3.6).round # => Vector2d(2,4)
78
82
  # Vector2d(2.4444, 3.666).round(2) # => Vector2d(2.44, 3.67)
79
83
  #
80
- Contract Or[None, Num] => Vector2d
81
- def round(digits=0)
84
+ def round(digits = 0)
82
85
  self.class.new(x.round(digits), y.round(digits))
83
86
  end
84
87
 
@@ -88,9 +91,8 @@ class Vector2d
88
91
  # vector.truncate(5.0) # => Vector2d(2.0, 3.0)
89
92
  # vector.truncate(1.0) # => Vector2d(0.5547.., 0.8320..)
90
93
  #
91
- Contract Num => Vector2d
92
94
  def truncate(max)
93
- resize([max, self.length].min)
95
+ resize([max, length].min)
94
96
  end
95
97
  end
96
98
  end
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
- VERSION = "2.2.3"
4
+ VERSION = "2.3.0"
5
5
  end
data/lib/vector2d.rb CHANGED
@@ -1,25 +1,11 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require "contracts"
4
-
5
- class Vector2d
6
- include Contracts
7
- VectorLike = Or[
8
- [Num, Num],
9
- { x: Num, y: Num },
10
- { 'x' => Num, 'y' => Num },
11
- Num,
12
- String,
13
- Vector2d
14
- ]
15
- end
16
-
17
- require 'vector2d/calculations'
18
- require 'vector2d/coercions'
19
- require 'vector2d/fitting'
20
- require 'vector2d/properties'
21
- require 'vector2d/transformations'
22
- require 'vector2d/version'
3
+ require "vector2d/calculations"
4
+ require "vector2d/coercions"
5
+ require "vector2d/fitting"
6
+ require "vector2d/properties"
7
+ require "vector2d/transformations"
8
+ require "vector2d/version"
23
9
 
24
10
  class Vector2d
25
11
  extend Vector2d::Calculations::ClassMethods
@@ -41,55 +27,44 @@ class Vector2d
41
27
  # Vector2d.parse({x: 150, y: 100})
42
28
  # Vector2d.parse({"x" => 150.0, "y" => 100.0})
43
29
  # Vector2d.parse(Vector2d(150, 100))
44
- Contract VectorLike, Maybe[Num] => Vector2d
45
30
  def parse(arg, second_arg = nil)
46
31
  if second_arg.nil?
47
32
  parse_single_arg(arg)
48
33
  else
49
- self.new(arg, second_arg)
34
+ new(arg, second_arg)
50
35
  end
51
36
  end
52
37
 
53
38
  private
54
39
 
55
- Contract VectorLike => Vector2d
56
40
  def parse_single_arg(arg)
57
- case arg
58
- when Vector2d
59
- arg
60
- when Array
61
- self.parse(*arg)
62
- when String
63
- parse_str(arg)
64
- when Hash
65
- parse_hash(arg.dup)
66
- else
67
- self.new(arg, arg)
68
- end
41
+ return arg if arg.is_a?(Vector2d)
42
+ return parse(*arg) if arg.is_a?(Array)
43
+ return parse_str(arg) if arg.is_a?(String)
44
+ return parse_hash(arg.dup) if arg.is_a?(Hash)
45
+
46
+ new(arg, arg)
69
47
  end
70
48
 
71
- Contract Hash => Vector2d
72
49
  def parse_hash(hash)
73
- hash[:x] ||= hash['x'] if hash.has_key?('x')
74
- hash[:y] ||= hash['y'] if hash.has_key?('y')
75
- self.new(hash[:x], hash[:y])
50
+ hash[:x] ||= hash["x"] if hash.key?("x")
51
+ hash[:y] ||= hash["y"] if hash.key?("y")
52
+ new(hash[:x], hash[:y])
76
53
  end
77
54
 
78
- Contract String => Vector2d
79
55
  def parse_str(str)
80
- if str =~ /^[\s]*[\d\.]*[\s]*x[\s]*[\d\.]*[\s]*$/
81
- x, y = str.split("x")
82
- new(x.to_f, y.to_f)
83
- else
84
- fail ArgumentError, "not a valid string input"
85
- end
56
+ raise ArgumentError, "not a valid string input" unless /^\s*[\d.]*\s*x\s*[\d.]*\s*$/.match?(str)
57
+
58
+ x, y = str.split("x")
59
+ new(x.to_f, y.to_f)
86
60
  end
87
61
  end
88
62
 
89
63
  attr_reader :x, :y
90
64
 
91
65
  def initialize(x, y)
92
- @x, @y = x, y
66
+ @x = x
67
+ @y = y
93
68
  end
94
69
 
95
70
  # Compares two vectors
@@ -97,9 +72,8 @@ class Vector2d
97
72
  # Vector2d(2, 3) == Vector2d(2, 3) # => true
98
73
  # Vector2d(2, 3) == Vector2d(1, 0) # => false
99
74
  #
100
- Contract Vector2d => Bool
101
- def ==(comp)
102
- comp.x === x && comp.y === y
75
+ def ==(other)
76
+ other.x == x && other.y == y
103
77
  end
104
78
  end
105
79
 
@@ -107,6 +81,6 @@ end
107
81
  #
108
82
  # Vector2d(2, 3) # => Vector2d(2,3)
109
83
  #
110
- def Vector2d(*args)
111
- Vector2d.parse(*args)
84
+ def Vector2d(*)
85
+ Vector2d.parse(*)
112
86
  end
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
+ "packages": {
4
+ ".": {
5
+ "release-type": "ruby",
6
+ "package-name": "vector2d",
7
+ "version-file": "lib/vector2d/version.rb"
8
+ }
9
+ }
10
+ }
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Vector2d::Calculations do
6
6
  subject(:vector) { Vector2d.new(2, 3) }
@@ -8,6 +8,7 @@ describe Vector2d::Calculations do
8
8
  describe ".cross_product" do
9
9
  let(:v1) { Vector2d.new(2, 3) }
10
10
  let(:v2) { Vector2d.new(4, 5) }
11
+
11
12
  it "calculates the cross product between two vectors" do
12
13
  expect(Vector2d.cross_product(v1, v2)).to eq(-2.0)
13
14
  end
@@ -16,6 +17,7 @@ describe Vector2d::Calculations do
16
17
  describe ".dot_product" do
17
18
  let(:v1) { Vector2d.new(2, 3) }
18
19
  let(:v2) { Vector2d.new(4, 5) }
20
+
19
21
  it "calculates the dot product between two vectors" do
20
22
  expect(Vector2d.dot_product(v1, v2)).to eq(23)
21
23
  end
@@ -24,6 +26,7 @@ describe Vector2d::Calculations do
24
26
  describe ".angle_between" do
25
27
  let(:v1) { Vector2d.new(2, 3) }
26
28
  let(:v2) { Vector2d.new(4, 5) }
29
+
27
30
  it "calculates the angle between two vectors" do
28
31
  expect(Vector2d.angle_between(v1, v2)).to be_within(0.0001).of(0.0867)
29
32
  end
@@ -32,12 +35,15 @@ describe Vector2d::Calculations do
32
35
  describe "*" do
33
36
  context "with vector" do
34
37
  subject(:vector) { Vector2d.new(2, 3) * Vector2d.new(3, 4) }
38
+
35
39
  it "multiplies the vectors" do
36
40
  expect(vector).to eq(Vector2d.new(6, 12))
37
41
  end
38
42
  end
43
+
39
44
  context "with number" do
40
45
  subject(:vector) { Vector2d.new(2, 3) * 3 }
46
+
41
47
  it "multiplies both members" do
42
48
  expect(vector).to eq(Vector2d.new(6, 9))
43
49
  end
@@ -47,12 +53,15 @@ describe Vector2d::Calculations do
47
53
  describe "/" do
48
54
  context "with vector" do
49
55
  subject(:vector) { Vector2d.new(6, 12) / Vector2d.new(2, 3) }
56
+
50
57
  it "divides the vectors" do
51
58
  expect(vector).to eq(Vector2d.new(3, 4))
52
59
  end
53
60
  end
61
+
54
62
  context "with number" do
55
63
  subject(:vector) { Vector2d.new(6, 12) / 3 }
64
+
56
65
  it "divides both members" do
57
66
  expect(vector).to eq(Vector2d.new(2, 4))
58
67
  end
@@ -62,12 +71,15 @@ describe Vector2d::Calculations do
62
71
  describe "+" do
63
72
  context "with vector" do
64
73
  subject(:vector) { Vector2d.new(2, 3) + Vector2d.new(3, 4) }
74
+
65
75
  it "adds the vectors" do
66
76
  expect(vector).to eq(Vector2d.new(5, 7))
67
77
  end
68
78
  end
79
+
69
80
  context "with number" do
70
81
  subject(:vector) { Vector2d.new(2, 3) + 2 }
82
+
71
83
  it "adds to both members" do
72
84
  expect(vector).to eq(Vector2d.new(4, 5))
73
85
  end
@@ -77,12 +89,15 @@ describe Vector2d::Calculations do
77
89
  describe "-" do
78
90
  context "with vector" do
79
91
  subject(:vector) { Vector2d.new(3, 5) - Vector2d.new(1, 2) }
92
+
80
93
  it "subtracts the vectors" do
81
94
  expect(vector).to eq(Vector2d.new(2, 3))
82
95
  end
83
96
  end
97
+
84
98
  context "with number" do
85
99
  subject(:vector) { Vector2d.new(2, 3) - 2 }
100
+
86
101
  it "subtracts from both members" do
87
102
  expect(vector).to eq(Vector2d.new(0, 1))
88
103
  end
@@ -91,13 +106,17 @@ describe Vector2d::Calculations do
91
106
 
92
107
  describe "#cross_product" do
93
108
  let(:comp) { Vector2d.new(3, 4) }
109
+
94
110
  it "calulates the cross product" do
95
- expect(vector.cross_product(comp)).to eq(Vector2d.cross_product(vector, comp))
111
+ expect(
112
+ vector.cross_product(comp)
113
+ ).to eq(Vector2d.cross_product(vector, comp))
96
114
  end
97
115
  end
98
116
 
99
117
  describe "#distance" do
100
118
  let(:comp) { Vector2d.new(3, 4) }
119
+
101
120
  it "returns the distance between two vectors" do
102
121
  expect(vector.distance(comp)).to be_within(0.0001).of(1.4142)
103
122
  end
@@ -105,6 +124,7 @@ describe Vector2d::Calculations do
105
124
 
106
125
  describe "#squared_distance" do
107
126
  let(:comp) { Vector2d.new(5, 6) }
127
+
108
128
  it "returns the squared distance between two vectors" do
109
129
  expect(vector.squared_distance(comp)).to eq(18)
110
130
  end
@@ -112,6 +132,7 @@ describe Vector2d::Calculations do
112
132
 
113
133
  describe "#dot_product" do
114
134
  let(:comp) { Vector2d.new(3, 4) }
135
+
115
136
  it "calulates the dot product" do
116
137
  expect(vector.dot_product(comp)).to eq(Vector2d.dot_product(vector, comp))
117
138
  end
@@ -119,8 +140,11 @@ describe Vector2d::Calculations do
119
140
 
120
141
  describe "#angle_between" do
121
142
  let(:comp) { Vector2d.new(3, 4) }
143
+
122
144
  it "calculates the angle between vectors" do
123
- expect(vector.angle_between(comp)).to eq(Vector2d.angle_between(vector, comp))
145
+ expect(
146
+ vector.angle_between(comp)
147
+ ).to eq(Vector2d.angle_between(vector, comp))
124
148
  end
125
149
  end
126
- end
150
+ end
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Vector2d::Coercions do
6
6
  subject(:vector) { Vector2d.new(2, 3) }
@@ -18,38 +18,42 @@ describe Vector2d::Coercions do
18
18
  end
19
19
 
20
20
  describe "#to_f_vector" do
21
- it "returns a float vector" do
22
- expect(vector.to_f_vector.x).to be_a(Float)
23
- expect(vector.to_f_vector.y).to be_a(Float)
24
- end
21
+ subject { vector.to_f_vector }
22
+
23
+ its(:x) { is_expected.to be_a(Float) }
24
+ its(:y) { is_expected.to be_a(Float) }
25
25
  end
26
26
 
27
27
  describe "#to_hash" do
28
28
  it "returns a hash" do
29
- expect(vector.to_hash).to eq({x: 2, y: 3})
29
+ expect(vector.to_hash).to eq(x: 2, y: 3)
30
30
  end
31
31
  end
32
32
 
33
33
  describe "#to_i_vector" do
34
- subject(:vector) { Vector2d.new(2.0, 3.0) }
35
- it "returns a fixnum vector" do
36
- expect(vector.to_i_vector.x).to be_a(Fixnum)
37
- expect(vector.to_i_vector.y).to be_a(Fixnum)
38
- end
34
+ subject { vector.to_i_vector }
35
+
36
+ let(:vector) { Vector2d.new(2.0, 3.0) }
37
+
38
+ its(:x) { is_expected.to be_a(Integer) }
39
+ its(:y) { is_expected.to be_a(Integer) }
39
40
  end
40
41
 
41
42
  describe "#to_s" do
42
43
  context "when fixnum" do
43
44
  subject(:vector) { Vector2d.new(2, 3) }
45
+
44
46
  it "renders a string" do
45
- expect(vector.to_s).to eq('2x3')
47
+ expect(vector.to_s).to eq("2x3")
46
48
  end
47
49
  end
50
+
48
51
  context "when float" do
49
52
  subject(:vector) { Vector2d.new(2.0, 3.0) }
53
+
50
54
  it "renders a string" do
51
- expect(vector.to_s).to eq('2.0x3.0')
55
+ expect(vector.to_s).to eq("2.0x3.0")
52
56
  end
53
57
  end
54
58
  end
55
- end
59
+ end