Skip to content

Commit

Permalink
test: add equality operator for StringIO
Browse files Browse the repository at this point in the history
  • Loading branch information
olavloite committed Jan 19, 2025
1 parent a108251 commit 918ac6a
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 0 deletions.
5 changes: 5 additions & 0 deletions acceptance/cases/models/binary_identifiers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def test_includes_works

user = User.all.includes(:projects).first
assert user
project_count = 0
user.projects.each do |_|
project_count += 1
end
assert_equal 3, project_count
assert_equal 3, user.projects.count
end

Expand Down
2 changes: 2 additions & 0 deletions acceptance/models/binary_project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

# frozen_string_literal: true

require_relative 'string_io'

class BinaryProject < ActiveRecord::Base
belongs_to :owner, class_name: 'User'

Expand Down
28 changes: 28 additions & 0 deletions acceptance/models/string_io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2025 Google LLC
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.

# frozen_string_literal: true

# Add equality and hash functions to StringIO to use it for sets.
class StringIO
def ==(o)
o.class == self.class && self.to_base64 == o.to_base64
end

def eql?(o)
self == o
end

def hash
to_base64.hash
end

def to_base64
self.rewind
value = self.read
Base64.strict_encode64 value.force_encoding("ASCII-8BIT")
end
end
2 changes: 2 additions & 0 deletions acceptance/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

# frozen_string_literal: true

require_relative 'string_io'

class User < ActiveRecord::Base
has_many :binary_projects, foreign_key: :owner_id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

# frozen_string_literal: true

require_relative "string_io"

class BinaryProject < ActiveRecord::Base
belongs_to :owner, class_name: 'User'

Expand Down
21 changes: 21 additions & 0 deletions test/activerecord_spanner_mock_server/models/string_io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

class StringIO
def ==(o)
o.class == self.class && self.to_base64 == o.to_base64
end

def eql?(o)
self == o
end

def hash
to_base64.hash
end

def to_base64
self.rewind
value = self.read
Base64.strict_encode64 value.force_encoding("ASCII-8BIT")
end
end
2 changes: 2 additions & 0 deletions test/activerecord_spanner_mock_server/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

# frozen_string_literal: true

require_relative "string_io"

class User < ActiveRecord::Base
has_many :binary_projects, foreign_key: :owner_id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,61 @@ def test_binary_id_association
assert_equal to_base64(user.id), mutation.insert.values[0][3]
end

def test_binary_id_association_includes
col_id = Field.new name: "id", type: Type.new(code: TypeCode::BYTES)
col_email = Field.new name: "email", type: Type.new(code: TypeCode::STRING)
col_full_name = Field.new name: "full_name", type: Type.new(code: TypeCode::STRING)

metadata = ResultSetMetadata.new row_type: StructType.new
metadata.row_type.fields.push col_id, col_email, col_full_name
result_set = ResultSet.new metadata: metadata

user_id = to_base64(StringIO.new(SecureRandom.random_bytes(16)))
row = ListValue.new
row.values.push(
Value.new(string_value: user_id),
Value.new(string_value: "[email protected]"),
Value.new(string_value: "Test User")
)
result_set.rows.push row
statement_result = StatementResult.new(result_set)

sql = "SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT @p1"
@mock.put_statement_result sql, statement_result

col_id = Field.new name: "id", type: Type.new(code: TypeCode::BYTES)
col_name = Field.new name: "name", type: Type.new(code: TypeCode::STRING)
col_description = Field.new name: "description", type: Type.new(code: TypeCode::STRING)
col_owner = Field.new name: "owner_id", type: Type.new(code: TypeCode::BYTES)

metadata = ResultSetMetadata.new row_type: StructType.new
metadata.row_type.fields.push col_id, col_name, col_description, col_owner
result_set = ResultSet.new metadata: metadata

project_count = 3
(1..project_count).each { |i|
row = ListValue.new
row.values.push(
Value.new(string_value: to_base64(StringIO.new(SecureRandom.random_bytes(16)))),
Value.new(string_value: "Test Project #{i}"),
Value.new(string_value: "Test Project Description #{i}"),
Value.new(string_value: user_id)
)
result_set.rows.push row
}
statement_result = StatementResult.new(result_set)
projects_sql = "SELECT `binary_projects`.* FROM `binary_projects` WHERE `binary_projects`.`owner_id` = @p1"
@mock.put_statement_result projects_sql, statement_result

users = User.all.includes(:binary_projects)
u1 = users.first
found = 0
u1.binary_projects.each do |_|
found += 1
end
assert_equal project_count, found
end

def test_skip_binary_deserialization
ENV["SPANNER_BYTES_DESERIALIZE_DISABLED"] = "true"
begin
Expand Down

0 comments on commit 918ac6a

Please sign in to comment.