Better tests for where_properties

Andrew Kane committed Jun 21, 2016
commit f931754506512a4ec1efc26926908a1cc82eedce
Showing 8 changed files with 82 additions and 47 deletions
Gemfile +2 -0
@@ @@ -2,3 +2,5 @@ source "https://rubygems.org"
# Specify your gem's dependencies in ahoy.gemspec
gemspec
+
+ gem "rails", "~> 5.0.0.rc1"
ahoy/properties.rb b/lib/ahoy/properties.rb +17 -12
@@ @@ -6,25 +6,30 @@ module Ahoy
def where_properties(properties)
relation = self
column_type = columns_hash["properties"].type
- case column_type
- when :jsonb, :json
- properties.each do |k, v|
- relation = relation.where("properties ->> ? = ?", k.to_s, v.to_s)
- end
- else
- adapter_name = connection.adapter_name.downcase
- case adapter_name
- when /postgres/
+ adapter_name = connection.adapter_name.downcase
+ case adapter_name
+ when /mysql/
+ if column_type == :json
properties.each do |k, v|
- relation = relation.where("properties SIMILAR TO ?", "%[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}[,}]%")
+ relation = relation.where("properties -> ? = ?", "$.#{k.to_s}", v)
end
- when /mysql/
+ else
properties.each do |k, v|
relation = relation.where("properties REGEXP ?", "[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}[,}]")
end
+ end
+ when /postgres/
+ if column_type == :jsonb || column_type == :json
+ properties.each do |k, v|
+ relation = relation.where("properties ->> ? = ?", k.to_s, v.to_s)
+ end
else
- raise "Adapter not supported: #{adapter_name}"
+ properties.each do |k, v|
+ relation = relation.where("properties SIMILAR TO ?", "%[{,]#{{k.to_s => v}.to_json.sub(/\A\{/, "").sub(/\}\z/, "")}[,}]%")
+ end
end
+ else
+ raise "Adapter not supported: #{adapter_name}"
end
relation
end
test/properties/mysql_json_test.rb +18 -0
@@ @@ -0,0 +1,18 @@
+ require_relative "../test_helper"
+
+ ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
+
+ ActiveRecord::Migration.create_table :mysql_json_events, force: true do |t|
+ t.json :properties
+ end
+
+ class MysqlJsonEvent < MysqlBase
+ end
+
+ class MysqlJsonTest < Minitest::Test
+ include PropertiesTest
+
+ def model
+ MysqlJsonEvent
+ end
+ end
test/properties/mysql_text_test.rb +6 -8
@@ @@ -2,20 +2,18 @@ require_relative "../test_helper"
ActiveRecord::Base.establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
- ActiveRecord::Migration.create_table :ahoy_events, force: true do |t|
+ ActiveRecord::Migration.create_table :mysql_text_events, force: true do |t|
t.text :properties
end
- Ahoy.send(:remove_const, :Event) if defined?(Ahoy::Event)
-
- class Ahoy::Event < ActiveRecord::Base
- include Ahoy::Properties
-
- self.table_name = "ahoy_events"
-
+ class MysqlTextEvent < MysqlBase
serialize :properties, JSON
end
class MysqlTextTest < Minitest::Test
include PropertiesTest
+
+ def model
+ MysqlTextEvent
+ end
end
test/properties/postgresql_json_test.rb +6 -7
@@ @@ -2,18 +2,17 @@ require_relative "../test_helper"
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
- ActiveRecord::Migration.create_table :ahoy_events, force: true do |t|
+ ActiveRecord::Migration.create_table :postgresql_json_events, force: true do |t|
t.json :properties
end
- Ahoy.send(:remove_const, :Event) if defined?(Ahoy::Event)
-
- class Ahoy::Event < ActiveRecord::Base
- include Ahoy::Properties
-
- self.table_name = "ahoy_events"
+ class PostgresqlJsonEvent < PostgresqlBase
end
class PostgresqlJsonTest < Minitest::Test
include PropertiesTest
+
+ def model
+ PostgresqlJsonEvent
+ end
end
test/properties/postgresql_jsonb_test.rb +6 -7
@@ @@ -2,18 +2,17 @@ require_relative "../test_helper"
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
- ActiveRecord::Migration.create_table :ahoy_events, force: true do |t|
+ ActiveRecord::Migration.create_table :postgresql_jsonb_events, force: true do |t|
t.jsonb :properties
end
- Ahoy.send(:remove_const, :Event) if defined?(Ahoy::Event)
-
- class Ahoy::Event < ActiveRecord::Base
- include Ahoy::Properties
-
- self.table_name = "ahoy_events"
+ class PostgresqlJsonbEvent < PostgresqlBase
end
class PostgresqlJsonbTest < Minitest::Test
include PropertiesTest
+
+ def model
+ PostgresqlJsonbEvent
+ end
end
test/properties/postgresql_text_test.rb +6 -8
@@ @@ -2,20 +2,18 @@ require_relative "../test_helper"
ActiveRecord::Base.establish_connection adapter: "postgresql", database: "ahoy_test"
- ActiveRecord::Migration.create_table :ahoy_events, force: true do |t|
+ ActiveRecord::Migration.create_table :postgresql_text_events, force: true do |t|
t.text :properties
end
- Ahoy.send(:remove_const, :Event) if defined?(Ahoy::Event)
-
- class Ahoy::Event < ActiveRecord::Base
- include Ahoy::Properties
-
- self.table_name = "ahoy_events"
-
+ class PostgresqlTextEvent < PostgresqlBase
serialize :properties, JSON
end
class PostgresqlTextTest < Minitest::Test
include PropertiesTest
+
+ def model
+ PostgresqlTextEvent
+ end
end
test/test_helper.rb +21 -5
@@ @@ -6,26 +6,42 @@ require "active_record"
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"]
+ class PostgresqlBase < ActiveRecord::Base
+ include Ahoy::Properties
+ establish_connection adapter: "postgresql", database: "ahoy_test"
+ self.abstract_class = true
+ end
+
+ class MysqlBase < ActiveRecord::Base
+ include Ahoy::Properties
+ establish_connection adapter: "mysql2", username: "root", database: "ahoy_test"
+ self.abstract_class = true
+ end
+
module PropertiesTest
def setup
- Ahoy::Event.delete_all
+ model.delete_all
end
def test_empty
- assert_equal 0, Ahoy::Event.where_properties({}).count
+ assert_equal 0, count_events({})
end
def test_string
create_event hello: "world"
- assert_equal 1, Ahoy::Event.where_properties(hello: "world").count
+ assert_equal 1, count_events(hello: "world")
end
def test_number
create_event product_id: 1
- assert_equal 1, Ahoy::Event.where_properties(product_id: 1).count
+ assert_equal 1, count_events(product_id: 1)
end
def create_event(properties)
- Ahoy::Event.create(properties: properties)
+ model.create(properties: properties)
+ end
+
+ def count_events(properties)
+ model.where_properties(properties).count
end
end