diff options
Diffstat (limited to 'activerecord/test/cases/adapters/postgresql/json_test.rb')
-rw-r--r-- | activerecord/test/cases/adapters/postgresql/json_test.rb | 155 |
1 files changed, 141 insertions, 14 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index d64037eec0..340ca29c0e 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -1,12 +1,14 @@ # encoding: utf-8 - require "cases/helper" -require 'active_record/base' -require 'active_record/connection_adapters/postgresql_adapter' +require 'support/schema_dumping_helper' + +module PostgresqlJSONSharedTestCases + include SchemaDumpingHelper -class PostgresqlJSONTest < ActiveRecord::TestCase class JsonDataType < ActiveRecord::Base self.table_name = 'json_data_type' + + store_accessor :settings, :resolution end def setup @@ -14,13 +16,14 @@ class PostgresqlJSONTest < ActiveRecord::TestCase begin @connection.transaction do @connection.create_table('json_data_type') do |t| - t.json 'payload', :default => {} + t.public_send column_type, 'payload', default: {} # t.json 'payload', default: {} + t.public_send column_type, 'settings' # t.json 'settings' end end rescue ActiveRecord::StatementInvalid - return skip "do not test on PG without json" + skip "do not test on PG without json" end - @column = JsonDataType.columns.find { |c| c.name == 'payload' } + @column = JsonDataType.columns_hash['payload'] end def teardown @@ -28,20 +31,63 @@ class PostgresqlJSONTest < ActiveRecord::TestCase end def test_column - assert_equal :json, @column.type + column = JsonDataType.columns_hash["payload"] + assert_equal column_type, column.type + assert_equal column_type.to_s, column.sql_type + assert_not column.number? + assert_not column.binary? + assert_not column.array + end + + def test_default + @connection.add_column 'json_data_type', 'permissions', column_type, default: '{"users": "read", "posts": ["read", "write"]}' + JsonDataType.reset_column_information + + assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.column_defaults['permissions']) + assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.new.permissions) + ensure + JsonDataType.reset_column_information + end + + def test_change_table_supports_json + @connection.transaction do + @connection.change_table('json_data_type') do |t| + t.public_send column_type, 'users', default: '{}' # t.json 'users', default: '{}' + end + JsonDataType.reset_column_information + column = JsonDataType.columns_hash['users'] + assert_equal column_type, column.type + + raise ActiveRecord::Rollback # reset the schema change + end + ensure + JsonDataType.reset_column_information + end + + def test_schema_dumping + output = dump_table_schema("json_data_type") + assert_match(/t.#{column_type.to_s}\s+"payload",\s+default: {}/, output) + end + + def test_cast_value_on_write + x = JsonDataType.new payload: {"string" => "foo", :symbol => :bar} + assert_equal({"string" => "foo", :symbol => :bar}, x.payload_before_type_cast) + assert_equal({"string" => "foo", "symbol" => "bar"}, x.payload) + x.save + assert_equal({"string" => "foo", "symbol" => "bar"}, x.reload.payload) end def test_type_cast_json - assert @column + column = JsonDataType.columns_hash["payload"] data = "{\"a_key\":\"a_value\"}" - hash = @column.class.string_to_json data + hash = column.type_cast_from_database(data) assert_equal({'a_key' => 'a_value'}, hash) - assert_equal({'a_key' => 'a_value'}, @column.type_cast(data)) + assert_equal({'a_key' => 'a_value'}, column.type_cast_from_database(data)) - assert_equal({}, @column.type_cast("{}")) - assert_equal({'key'=>nil}, @column.type_cast('{"key": null}')) - assert_equal({'c'=>'}','"a"'=>'b "a b'}, @column.type_cast(%q({"c":"}", "\"a\"":"b \"a b"}))) + assert_equal({}, column.type_cast_from_database("{}")) + assert_equal({'key'=>nil}, column.type_cast_from_database('{"key": null}')) + assert_equal({'c'=>'}','"a"'=>'b "a b'}, column.type_cast_from_database(%q({"c":"}", "\"a\"":"b \"a b"}))) end def test_rewrite @@ -68,4 +114,85 @@ class PostgresqlJSONTest < ActiveRecord::TestCase x = JsonDataType.first assert_equal(nil, x.payload) end + + def test_select_array_json_value + @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| + x = JsonDataType.first + assert_equal(['v0', {'k1' => 'v1'}], x.payload) + end + + def test_rewrite_array_json_value + @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| + x = JsonDataType.first + x.payload = ['v1', {'k2' => 'v2'}, 'v3'] + assert x.save! + end + + def test_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution + + x.save! + x = JsonDataType.first + assert_equal "320×480", x.resolution + + x.resolution = "640×1136" + x.save! + + x = JsonDataType.first + assert_equal "640×1136", x.resolution + end + + def test_duplication_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution + + y = x.dup + assert_equal "320×480", y.resolution + end + + def test_yaml_round_trip_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution + + y = YAML.load(YAML.dump(x)) + assert_equal "320×480", y.resolution + end + + def test_changes_in_place + json = JsonDataType.new + assert_not json.changed? + + json.payload = { 'one' => 'two' } + assert json.changed? + assert json.payload_changed? + + json.save! + assert_not json.changed? + + json.payload['three'] = 'four' + assert json.payload_changed? + + json.save! + json.reload + + assert_equal({ 'one' => 'two', 'three' => 'four' }, json.payload) + assert_not json.changed? + end +end + +class PostgresqlJSONTest < ActiveRecord::TestCase + include PostgresqlJSONSharedTestCases + + def column_type + :json + end +end + +class PostgresqlJSONBTest < ActiveRecord::TestCase + include PostgresqlJSONSharedTestCases + + def column_type + :jsonb + end end |