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 | |