superstore 2.4.3 → 3.0.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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +40 -0
- data/.gitignore +1 -0
- data/.simplecov +3 -0
- data/Gemfile +2 -3
- data/LICENSE +1 -1
- data/MIT-LICENSE +1 -1
- data/README.md +4 -34
- data/lib/superstore/adapters/abstract_adapter.rb +1 -27
- data/lib/superstore/adapters/jsonb_adapter.rb +4 -132
- data/lib/superstore/associations/association.rb +6 -0
- data/lib/superstore/associations/association_scope.rb +20 -0
- data/lib/superstore/associations/belongs_to.rb +3 -1
- data/lib/superstore/associations/builder/association.rb +1 -1
- data/lib/superstore/associations/has_many.rb +15 -2
- data/lib/superstore/associations/reflection.rb +8 -2
- data/lib/superstore/associations.rb +9 -4
- data/lib/superstore/attribute_assignment.rb +7 -0
- data/lib/superstore/attribute_methods/primary_key.rb +20 -11
- data/lib/superstore/attribute_methods.rb +1 -109
- data/lib/superstore/attributes.rb +13 -0
- data/lib/superstore/base.rb +6 -34
- data/lib/superstore/core.rb +7 -65
- data/lib/superstore/model_schema.rb +35 -0
- data/lib/superstore/persistence.rb +26 -115
- data/lib/superstore/railtie.rb +3 -11
- data/lib/superstore/relation/scrolling.rb +48 -0
- data/lib/superstore/types/array_type.rb +3 -7
- data/lib/superstore/types/base.rb +9 -0
- data/lib/superstore/types/boolean_type.rb +7 -12
- data/lib/superstore/types/date_range_type.rb +7 -0
- data/lib/superstore/types/date_type.rb +7 -10
- data/lib/superstore/types/float_type.rb +3 -11
- data/lib/superstore/types/geo_point_type.rb +30 -0
- data/lib/superstore/types/integer_range_type.rb +15 -0
- data/lib/superstore/types/integer_type.rb +8 -14
- data/lib/superstore/types/json_type.rb +1 -1
- data/lib/superstore/types/range_type.rb +58 -0
- data/lib/superstore/types/string_type.rb +4 -4
- data/lib/superstore/types/time_type.rb +10 -8
- data/lib/superstore/types.rb +11 -9
- data/lib/superstore.rb +17 -19
- data/superstore.gemspec +8 -10
- data/test/support/jsonb.rb +3 -1
- data/test/support/models.rb +10 -4
- data/test/test_helper.rb +7 -3
- data/test/unit/adapters/adapter_test.rb +1 -3
- data/test/unit/associations/belongs_to_test.rb +1 -1
- data/test/unit/associations/has_many_test.rb +10 -2
- data/test/unit/attribute_methods/dirty_test.rb +8 -19
- data/test/unit/attribute_methods/primary_key_test.rb +1 -1
- data/test/unit/attribute_methods_test.rb +10 -22
- data/test/unit/{attribute_methods/typecasting_test.rb → attributes_test.rb} +13 -39
- data/test/unit/base_test.rb +4 -0
- data/test/unit/caching_test.rb +1 -1
- data/test/unit/callbacks_test.rb +4 -4
- data/test/unit/core_test.rb +15 -20
- data/test/unit/persistence_test.rb +36 -44
- data/test/unit/{scope/batches_test.rb → relation/scrolling_test.rb} +9 -5
- data/test/unit/serialization_test.rb +10 -2
- data/test/unit/{timestamps_test.rb → timestamp_test.rb} +5 -5
- data/test/unit/types/array_type_test.rb +3 -18
- data/test/unit/types/boolean_type_test.rb +7 -21
- data/test/unit/types/date_range_type_test.rb +29 -0
- data/test/unit/types/date_type_test.rb +15 -6
- data/test/unit/types/float_type_test.rb +4 -19
- data/test/unit/types/geo_point_type_test.rb +28 -0
- data/test/unit/types/integer_range_type_test.rb +28 -0
- data/test/unit/types/integer_type_test.rb +7 -16
- data/test/unit/types/string_type_test.rb +9 -13
- data/test/unit/types/time_type_test.rb +17 -11
- data/test/unit/validations_test.rb +2 -2
- metadata +39 -53
- data/.travis.yml +0 -13
- data/Gemfile-rails4.2 +0 -11
- data/lib/superstore/attribute_methods/definition.rb +0 -17
- data/lib/superstore/attribute_methods/dirty.rb +0 -52
- data/lib/superstore/attribute_methods/typecasting.rb +0 -53
- data/lib/superstore/caching.rb +0 -13
- data/lib/superstore/callbacks.rb +0 -29
- data/lib/superstore/connection.rb +0 -24
- data/lib/superstore/errors.rb +0 -10
- data/lib/superstore/inspect.rb +0 -25
- data/lib/superstore/model.rb +0 -38
- data/lib/superstore/schema.rb +0 -20
- data/lib/superstore/scope/batches.rb +0 -27
- data/lib/superstore/scope/finder_methods.rb +0 -51
- data/lib/superstore/scope/query_methods.rb +0 -52
- data/lib/superstore/scope.rb +0 -73
- data/lib/superstore/scoping.rb +0 -30
- data/lib/superstore/timestamps.rb +0 -19
- data/lib/superstore/type.rb +0 -16
- data/lib/superstore/types/base_type.rb +0 -23
- data/lib/superstore/validations.rb +0 -44
- data/test/unit/attribute_methods/definition_test.rb +0 -16
- data/test/unit/inspect_test.rb +0 -26
- data/test/unit/schema_test.rb +0 -15
- data/test/unit/scope/finder_methods_test.rb +0 -62
- data/test/unit/scope/query_methods_test.rb +0 -36
- data/test/unit/scoping_test.rb +0 -7
- data/test/unit/types/base_type_test.rb +0 -11
@@ -0,0 +1,15 @@
|
|
1
|
+
module Superstore
|
2
|
+
module Types
|
3
|
+
class IntegerRangeType < RangeType
|
4
|
+
self.subtype = IntegerType.new
|
5
|
+
|
6
|
+
def serialize_for_open_ended(value)
|
7
|
+
value&.abs == Float::INFINITY ? nil : super
|
8
|
+
end
|
9
|
+
|
10
|
+
def convert_min(method, value)
|
11
|
+
value.nil? ? -Float::INFINITY : super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
module Superstore
|
2
2
|
module Types
|
3
|
-
class IntegerType <
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def decode(str)
|
12
|
-
str.to_i unless str.empty?
|
13
|
-
end
|
14
|
-
|
15
|
-
def typecast(value)
|
16
|
-
value.to_i
|
3
|
+
class IntegerType < Base
|
4
|
+
def cast_value(value)
|
5
|
+
if value.is_a?(String)
|
6
|
+
Integer(value, 10)
|
7
|
+
else
|
8
|
+
Integer(value)
|
9
|
+
end
|
10
|
+
rescue
|
17
11
|
end
|
18
12
|
end
|
19
13
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Superstore
|
2
|
+
module Types
|
3
|
+
class RangeType < Base
|
4
|
+
class_attribute :subtype
|
5
|
+
|
6
|
+
def serialize(range)
|
7
|
+
if range
|
8
|
+
[
|
9
|
+
serialize_for_open_ended(range.begin),
|
10
|
+
serialize_for_open_ended(range.end)
|
11
|
+
]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def deserialize(range_tuple)
|
16
|
+
if range_tuple.is_a? Range
|
17
|
+
range_tuple
|
18
|
+
elsif range_tuple.is_a?(Array)
|
19
|
+
range = convert_min(:deserialize, range_tuple[0]) .. convert_max(:deserialize, range_tuple[1])
|
20
|
+
cast_value(range)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def cast_value(value)
|
25
|
+
if is_beginless_date_range?(value)
|
26
|
+
nil
|
27
|
+
elsif value.is_a?(Range) && (value.end.nil? || value.begin <= value.end)
|
28
|
+
value
|
29
|
+
elsif value.is_a?(Array) && value.size == 2
|
30
|
+
begin
|
31
|
+
range = convert_min(:cast_value, value[0])..convert_max(:cast_value, value[1])
|
32
|
+
cast_value(range)
|
33
|
+
rescue ArgumentError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def serialize_for_open_ended(value)
|
41
|
+
subtype.serialize(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def convert_min(method, value)
|
45
|
+
subtype.send(method, value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def convert_max(method, value)
|
49
|
+
subtype.send(method, value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_beginless_date_range?(value)
|
53
|
+
(value.is_a?(Range) && value.begin.nil? && value.end.is_a?(Date)) ||
|
54
|
+
(value.is_a?(Array) && value[0].nil? && value[1].is_a?(Date))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Superstore
|
2
2
|
module Types
|
3
|
-
class StringType <
|
4
|
-
def
|
5
|
-
|
3
|
+
class StringType < Base
|
4
|
+
def serialize(str)
|
5
|
+
return if str.nil?
|
6
6
|
|
7
7
|
unless str.encoding == Encoding::UTF_8
|
8
8
|
(str.frozen? ? str.dup : str).force_encoding('UTF-8')
|
@@ -11,7 +11,7 @@ module Superstore
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def cast_value(value)
|
15
15
|
value.to_s
|
16
16
|
end
|
17
17
|
end
|
@@ -1,16 +1,18 @@
|
|
1
1
|
module Superstore
|
2
2
|
module Types
|
3
|
-
class TimeType <
|
4
|
-
def
|
5
|
-
|
6
|
-
time = time.to_time unless time.is_a?(Time)
|
7
|
-
time.utc.xmlschema(6)
|
3
|
+
class TimeType < Base
|
4
|
+
def serialize(time)
|
5
|
+
time.utc.xmlschema(6) if time
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
Time.
|
12
|
-
rescue
|
8
|
+
def deserialize(str)
|
9
|
+
Time.rfc3339(str).in_time_zone if str
|
10
|
+
rescue ArgumentError
|
11
|
+
Time.parse(str).in_time_zone rescue nil
|
12
|
+
end
|
13
13
|
|
14
|
+
def cast_value(value)
|
15
|
+
value.to_time.in_time_zone rescue nil
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/lib/superstore/types.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
ActiveRecord::Type.register(:superstore_array, Superstore::Types::ArrayType)
|
2
|
+
ActiveRecord::Type.register(:superstore_boolean, Superstore::Types::BooleanType)
|
3
|
+
ActiveRecord::Type.register(:superstore_date, Superstore::Types::DateType)
|
4
|
+
ActiveRecord::Type.register(:superstore_date_range, Superstore::Types::DateRangeType)
|
5
|
+
ActiveRecord::Type.register(:superstore_float, Superstore::Types::FloatType)
|
6
|
+
ActiveRecord::Type.register(:superstore_geo_point, Superstore::Types::GeoPointType)
|
7
|
+
ActiveRecord::Type.register(:superstore_integer, Superstore::Types::IntegerType)
|
8
|
+
ActiveRecord::Type.register(:superstore_integer_range, Superstore::Types::IntegerRangeType)
|
9
|
+
ActiveRecord::Type.register(:superstore_json, Superstore::Types::JsonType)
|
10
|
+
ActiveRecord::Type.register(:superstore_time, Superstore::Types::TimeType)
|
11
|
+
ActiveRecord::Type.register(:superstore_string, Superstore::Types::StringType)
|
data/lib/superstore.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'active_support/all'
|
2
2
|
require 'active_model'
|
3
|
-
require '
|
4
|
-
require 'oj'
|
5
|
-
require 'superstore/errors'
|
3
|
+
require 'active_record'
|
6
4
|
|
7
5
|
module Superstore
|
8
6
|
extend ActiveSupport::Autoload
|
@@ -10,30 +8,20 @@ module Superstore
|
|
10
8
|
autoload :AttributeMethods
|
11
9
|
autoload :Base
|
12
10
|
autoload :Associations
|
13
|
-
autoload :
|
14
|
-
autoload :
|
11
|
+
autoload :AttributeAssignment
|
12
|
+
autoload :Attributes
|
15
13
|
autoload :Connection
|
16
14
|
autoload :Core
|
17
15
|
autoload :Identity
|
18
|
-
autoload :
|
19
|
-
autoload :
|
16
|
+
autoload :Inheritance
|
17
|
+
autoload :ModelSchema
|
20
18
|
autoload :Persistence
|
21
|
-
autoload :Schema
|
22
|
-
autoload :CassandraSchema
|
23
|
-
autoload :Scope
|
24
|
-
autoload :Scoping
|
25
|
-
autoload :Timestamps
|
26
|
-
autoload :Type
|
27
|
-
autoload :Validations
|
28
19
|
|
29
20
|
module AttributeMethods
|
30
21
|
extend ActiveSupport::Autoload
|
31
22
|
|
32
23
|
eager_autoload do
|
33
|
-
autoload :Definition
|
34
|
-
autoload :Dirty
|
35
24
|
autoload :PrimaryKey
|
36
|
-
autoload :Typecasting
|
37
25
|
end
|
38
26
|
end
|
39
27
|
|
@@ -42,13 +30,13 @@ module Superstore
|
|
42
30
|
|
43
31
|
autoload :AbstractAdapter
|
44
32
|
autoload :JsonbAdapter
|
45
|
-
autoload :CassandraAdapter
|
46
33
|
end
|
47
34
|
|
48
35
|
module Associations
|
49
36
|
extend ActiveSupport::Autoload
|
50
37
|
|
51
38
|
autoload :Association
|
39
|
+
autoload :AssociationScope
|
52
40
|
autoload :Reflection
|
53
41
|
autoload :BelongsTo
|
54
42
|
autoload :HasMany
|
@@ -64,16 +52,26 @@ module Superstore
|
|
64
52
|
end
|
65
53
|
end
|
66
54
|
|
55
|
+
module Relation
|
56
|
+
extend ActiveSupport::Autoload
|
57
|
+
|
58
|
+
autoload :Scrolling
|
59
|
+
end
|
60
|
+
|
67
61
|
module Types
|
68
62
|
extend ActiveSupport::Autoload
|
69
63
|
|
70
|
-
autoload :
|
64
|
+
autoload :Base
|
71
65
|
autoload :ArrayType
|
72
66
|
autoload :BooleanType
|
73
67
|
autoload :DateType
|
68
|
+
autoload :DateRangeType
|
74
69
|
autoload :FloatType
|
70
|
+
autoload :GeoPointType
|
75
71
|
autoload :IntegerType
|
72
|
+
autoload :IntegerRangeType
|
76
73
|
autoload :JsonType
|
74
|
+
autoload :RangeType
|
77
75
|
autoload :StringType
|
78
76
|
autoload :TimeType
|
79
77
|
end
|
data/superstore.gemspec
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
1
|
Gem::Specification.new do |s|
|
4
2
|
s.name = 'superstore'
|
5
|
-
s.version = '
|
3
|
+
s.version = '3.0.0'
|
6
4
|
s.description = 'ActiveModel-based JSONB document store'
|
7
5
|
s.summary = 'ActiveModel for JSONB documents'
|
8
|
-
s.authors = ['Michael Koziarski', '
|
6
|
+
s.authors = ['Michael Koziarski', 'Data Axle']
|
9
7
|
s.email = 'developer@matthewhiggins.com'
|
10
8
|
s.homepage = 'http://github.com/data-axle/superstore'
|
11
|
-
s.licenses = %w
|
9
|
+
s.licenses = %w[ISC MIT]
|
12
10
|
|
13
|
-
s.required_ruby_version = '>=
|
14
|
-
s.required_rubygems_version = '>=
|
11
|
+
s.required_ruby_version = '>= 3.0.0'
|
12
|
+
s.required_rubygems_version = '>= 3.2.0'
|
15
13
|
|
16
14
|
s.extra_rdoc_files = ['README.md']
|
17
15
|
s.files = `git ls-files`.split("\n")
|
18
16
|
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
19
17
|
s.require_paths = ['lib']
|
20
18
|
|
21
|
-
s.add_runtime_dependency('activemodel', '>=
|
22
|
-
s.add_runtime_dependency('
|
23
|
-
s.add_runtime_dependency('oj')
|
19
|
+
s.add_runtime_dependency('activemodel', '>= 6.1')
|
20
|
+
s.add_runtime_dependency('activerecord', '>= 6.1')
|
24
21
|
|
25
22
|
s.add_development_dependency('bundler')
|
23
|
+
s.add_development_dependency('rails', '~> 6.1')
|
26
24
|
end
|
data/test/support/jsonb.rb
CHANGED
data/test/support/models.rb
CHANGED
@@ -2,18 +2,24 @@ class User < ActiveRecord::Base
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class Label < ActiveRecord::Base
|
5
|
+
belongs_to :issue
|
5
6
|
end
|
6
7
|
|
7
8
|
class Issue < Superstore::Base
|
8
|
-
|
9
|
-
|
9
|
+
attribute :description, type: :string
|
10
|
+
attribute :title, type: :string
|
11
|
+
attribute :parent_issue_id, type: :string
|
12
|
+
attribute :comments, type: :json
|
13
|
+
attribute :created_at, type: :time
|
14
|
+
attribute :updated_at, type: :time
|
10
15
|
|
11
16
|
before_create { self.description ||= 'funny' }
|
12
17
|
|
13
|
-
has_many :labels
|
18
|
+
has_many :labels, inverse_of: :issue
|
19
|
+
has_many :children_issues, class_name: 'Issue', foreign_key: :parent_issue_id, inverse_of: :parent_issue, superstore: true
|
20
|
+
belongs_to :parent_issue, class_name: 'Issue', superstore: true
|
14
21
|
|
15
22
|
def self.for_key key
|
16
23
|
where_ids(key)
|
17
24
|
end
|
18
25
|
end
|
19
|
-
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
require 'simplecov'
|
3
|
+
|
1
4
|
require 'rails'
|
2
5
|
|
3
6
|
I18n.config.enforce_available_locales = false
|
@@ -5,7 +8,7 @@ ActiveSupport::TestCase.test_order = :random
|
|
5
8
|
|
6
9
|
require 'active_record'
|
7
10
|
require 'rails/test_help'
|
8
|
-
require 'mocha/
|
11
|
+
require 'mocha/api'
|
9
12
|
|
10
13
|
require 'superstore'
|
11
14
|
|
@@ -18,7 +21,7 @@ module Superstore
|
|
18
21
|
def temp_object(&block)
|
19
22
|
Class.new(Superstore::Base) do
|
20
23
|
self.table_name = 'issues'
|
21
|
-
|
24
|
+
attribute :force_save, type: :string
|
22
25
|
before_save { self.force_save = 'junk' }
|
23
26
|
|
24
27
|
def self.name
|
@@ -33,8 +36,9 @@ module Superstore
|
|
33
36
|
module Types
|
34
37
|
class TestCase < Superstore::TestCase
|
35
38
|
attr_accessor :type
|
39
|
+
|
36
40
|
setup do
|
37
|
-
@type = self.class.name.sub(/Test$/, '').constantize.new
|
41
|
+
@type = self.class.name.sub(/Test$/, '').constantize.new
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -4,7 +4,7 @@ class Superstore::Associations::HasManyTest < Superstore::TestCase
|
|
4
4
|
class TestObject < Issue
|
5
5
|
end
|
6
6
|
|
7
|
-
test 'has_many' do
|
7
|
+
test 'has_many active_record association' do
|
8
8
|
issue = TestObject.create!
|
9
9
|
label = Label.create! name: 'important', issue_id: issue.id
|
10
10
|
|
@@ -13,10 +13,18 @@ class Superstore::Associations::HasManyTest < Superstore::TestCase
|
|
13
13
|
|
14
14
|
test 'create supports preloaded records' do
|
15
15
|
issue = TestObject.create!
|
16
|
-
issue.labels = Label.all
|
16
|
+
issue.labels = Label.all
|
17
17
|
|
18
18
|
issue.labels.create! name: 'blue'
|
19
19
|
|
20
20
|
assert_equal 1, issue.labels.size
|
21
21
|
end
|
22
|
+
|
23
|
+
test 'has_many superstore association' do
|
24
|
+
parent_issue = Issue.create!
|
25
|
+
child_issue = Issue.create! parent_issue: parent_issue
|
26
|
+
|
27
|
+
assert_equal [child_issue], parent_issue.children_issues
|
28
|
+
assert_equal parent_issue.object_id, parent_issue.children_issues.first.parent_issue.object_id
|
29
|
+
end
|
22
30
|
end
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
4
4
|
test 'save clears dirty' do
|
5
5
|
record = temp_object do
|
6
|
-
|
6
|
+
attribute :name, type: :string
|
7
7
|
end.new name: 'foo'
|
8
8
|
|
9
9
|
assert record.changed?
|
@@ -16,7 +16,7 @@ class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
|
16
16
|
|
17
17
|
test 'reload clears dirty' do
|
18
18
|
record = temp_object do
|
19
|
-
|
19
|
+
attribute :name, type: :string
|
20
20
|
end.create! name: 'foo'
|
21
21
|
|
22
22
|
record.name = 'bar'
|
@@ -27,9 +27,9 @@ class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
|
27
27
|
assert !record.changed?
|
28
28
|
end
|
29
29
|
|
30
|
-
test '
|
30
|
+
test 'cast_value float before dirty check' do
|
31
31
|
record = temp_object do
|
32
|
-
|
32
|
+
attribute :price, type: :float
|
33
33
|
end.create(price: 5.01)
|
34
34
|
|
35
35
|
record.price = '5.01'
|
@@ -39,9 +39,9 @@ class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
|
39
39
|
assert record.changed?
|
40
40
|
end
|
41
41
|
|
42
|
-
test '
|
42
|
+
test 'cast_value boolean before dirty check' do
|
43
43
|
record = temp_object do
|
44
|
-
|
44
|
+
attribute :awesome, type: :boolean
|
45
45
|
end.create(awesome: false)
|
46
46
|
|
47
47
|
record.awesome = false
|
@@ -51,20 +51,9 @@ class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
|
51
51
|
assert record.changed?
|
52
52
|
end
|
53
53
|
|
54
|
-
test 'unapplied_changes' do
|
55
|
-
record = temp_object do
|
56
|
-
float :price
|
57
|
-
string :color
|
58
|
-
end.create(price: 5.01, color: 'green')
|
59
|
-
|
60
|
-
record.color = 'blue'
|
61
|
-
|
62
|
-
assert_equal({'color' => 'blue'}, record.unapplied_changes)
|
63
|
-
end
|
64
|
-
|
65
54
|
test 'write_attribute' do
|
66
55
|
object = temp_object do
|
67
|
-
|
56
|
+
attribute :name, type: :string
|
68
57
|
end
|
69
58
|
|
70
59
|
expected = {"name"=>[nil, "foo"]}
|
@@ -83,7 +72,7 @@ class Superstore::AttributeMethods::DirtyTest < Superstore::TestCase
|
|
83
72
|
|
84
73
|
test 'dirty and restore to original value' do
|
85
74
|
object = temp_object do
|
86
|
-
|
75
|
+
attribute :name, type: :string
|
87
76
|
end
|
88
77
|
|
89
78
|
record = object.create(name: 'foo')
|
@@ -12,10 +12,6 @@ class Superstore::AttributeMethodsTest < Superstore::TestCase
|
|
12
12
|
assert_equal 'foo', issue.read_attribute(:description)
|
13
13
|
end
|
14
14
|
|
15
|
-
test 'read primary_key' do
|
16
|
-
refute_nil Issue.new[:id]
|
17
|
-
end
|
18
|
-
|
19
15
|
test 'hash accessor aliases' do
|
20
16
|
issue = Issue.new
|
21
17
|
|
@@ -34,32 +30,24 @@ class Superstore::AttributeMethodsTest < Superstore::TestCase
|
|
34
30
|
assert_equal 'foo', issue.description
|
35
31
|
end
|
36
32
|
|
37
|
-
class
|
38
|
-
|
39
|
-
self[:title] = val + ' lol'
|
40
|
-
end
|
41
|
-
end
|
33
|
+
class ModelWithOverride < Superstore::Base
|
34
|
+
attribute :title, type: :string
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
assert_equal 'hey lol', issue.title
|
36
|
+
def title=(v)
|
37
|
+
super "#{v} lol"
|
38
|
+
end
|
47
39
|
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
string :system
|
52
|
-
end
|
41
|
+
test 'override' do
|
42
|
+
issue = ModelWithOverride.new(title: 'hey')
|
53
43
|
|
54
|
-
|
55
|
-
r = ReservedWord.new(system: 'hello')
|
56
|
-
assert_equal 'hello', r.system
|
44
|
+
assert_equal 'hey lol', issue.title
|
57
45
|
end
|
58
46
|
|
59
47
|
test 'has_attribute?' do
|
60
|
-
refute Issue.new.
|
48
|
+
refute Issue.new.has_attribute?(:unknown)
|
49
|
+
assert Issue.new.has_attribute?(:description)
|
61
50
|
assert Issue.new(description: nil).has_attribute?(:description)
|
62
|
-
assert Issue.new(description: false).has_attribute?(:description)
|
63
51
|
assert Issue.new(description: 'hey').has_attribute?(:description)
|
64
52
|
end
|
65
53
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class Superstore::
|
3
|
+
class Superstore::AttributesTest < Superstore::TestCase
|
4
4
|
class TestIssue < Superstore::Base
|
5
5
|
self.table_name = 'issues'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
attribute :enabled, type: :boolean
|
8
|
+
attribute :rating, type: :float
|
9
|
+
attribute :price, type: :integer
|
10
|
+
attribute :orders, type: :json
|
11
|
+
attribute :name, type: :string
|
12
|
+
attribute :age_range, type: :integer_range
|
12
13
|
end
|
13
14
|
|
14
15
|
class TestChildIssue < TestIssue
|
15
|
-
|
16
|
+
attribute :description, type: :string
|
16
17
|
end
|
17
18
|
|
18
19
|
test 'attributes not shared' do
|
@@ -21,15 +22,6 @@ class Superstore::AttributeMethods::TypecastingTest < Superstore::TestCase
|
|
21
22
|
assert_nothing_raised { TestChildIssue.new.description }
|
22
23
|
end
|
23
24
|
|
24
|
-
test 'typecast_attribute' do
|
25
|
-
assert_equal 1, TestIssue.typecast_attribute('price', 1)
|
26
|
-
assert_equal 1, TestIssue.typecast_attribute(:price, 1)
|
27
|
-
|
28
|
-
assert_raise NoMethodError do
|
29
|
-
TestIssue.typecast_attribute('wtf', 1)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
25
|
test 'boolean attribute' do
|
34
26
|
issue = TestIssue.create! enabled: '1'
|
35
27
|
assert_equal true, issue.enabled
|
@@ -76,29 +68,11 @@ class Superstore::AttributeMethods::TypecastingTest < Superstore::TestCase
|
|
76
68
|
assert_equal '42', issue.name
|
77
69
|
end
|
78
70
|
|
79
|
-
test '
|
80
|
-
|
81
|
-
|
82
|
-
end
|
71
|
+
test 'integer_range' do
|
72
|
+
issue = TestIssue.create! age_range: ['70', nil]
|
73
|
+
assert_equal 70.., issue.age_range
|
83
74
|
|
84
|
-
|
85
|
-
|
86
|
-
}
|
87
|
-
issue = MultipleAttributesIssue.new :hello => 'hey', :greetings => 'how r u', :bye => 'see ya'
|
88
|
-
|
89
|
-
assert_equal 'how r u', issue.greetings
|
90
|
-
end
|
91
|
-
|
92
|
-
test 'multiple attributes with options' do
|
93
|
-
class MultipleAttributesIssue < Superstore::Base
|
94
|
-
self.table_name = 'issues'
|
95
|
-
end
|
96
|
-
|
97
|
-
MultipleAttributesIssue.expects(:attribute).with(:hello, { :unique => :true, :type => :string })
|
98
|
-
MultipleAttributesIssue.expects(:attribute).with(:world, { :unique => :true, :type => :string })
|
99
|
-
|
100
|
-
class MultipleAttributesIssue < Superstore::Base
|
101
|
-
string :hello, :world, :unique => :true
|
102
|
-
end
|
75
|
+
issue = TestIssue.find issue.id
|
76
|
+
assert_equal 70.., issue.age_range
|
103
77
|
end
|
104
78
|
end
|
data/test/unit/base_test.rb
CHANGED
data/test/unit/caching_test.rb
CHANGED
@@ -16,6 +16,6 @@ class Superstore::CachingTest < Superstore::TestCase
|
|
16
16
|
updated_at = Time.now
|
17
17
|
issue = Issue.create!(id: 1, updated_at: updated_at)
|
18
18
|
|
19
|
-
assert_equal "issues/1-#{updated_at.utc.to_s(:
|
19
|
+
assert_equal "issues/1-#{updated_at.utc.to_s(:usec)}", issue.cache_key
|
20
20
|
end
|
21
21
|
end
|