superstore 2.4.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +40 -0
  3. data/.gitignore +1 -0
  4. data/.simplecov +3 -0
  5. data/Gemfile +2 -3
  6. data/LICENSE +1 -1
  7. data/MIT-LICENSE +1 -1
  8. data/README.md +4 -34
  9. data/lib/superstore/adapters/abstract_adapter.rb +1 -27
  10. data/lib/superstore/adapters/jsonb_adapter.rb +4 -132
  11. data/lib/superstore/associations/association.rb +6 -0
  12. data/lib/superstore/associations/association_scope.rb +20 -0
  13. data/lib/superstore/associations/belongs_to.rb +3 -1
  14. data/lib/superstore/associations/builder/association.rb +1 -1
  15. data/lib/superstore/associations/has_many.rb +15 -2
  16. data/lib/superstore/associations/reflection.rb +8 -2
  17. data/lib/superstore/associations.rb +9 -4
  18. data/lib/superstore/attribute_assignment.rb +7 -0
  19. data/lib/superstore/attribute_methods/primary_key.rb +20 -11
  20. data/lib/superstore/attribute_methods.rb +1 -109
  21. data/lib/superstore/attributes.rb +13 -0
  22. data/lib/superstore/base.rb +6 -34
  23. data/lib/superstore/core.rb +7 -65
  24. data/lib/superstore/model_schema.rb +35 -0
  25. data/lib/superstore/persistence.rb +26 -115
  26. data/lib/superstore/railtie.rb +3 -11
  27. data/lib/superstore/relation/scrolling.rb +48 -0
  28. data/lib/superstore/types/array_type.rb +3 -7
  29. data/lib/superstore/types/base.rb +9 -0
  30. data/lib/superstore/types/boolean_type.rb +7 -12
  31. data/lib/superstore/types/date_range_type.rb +7 -0
  32. data/lib/superstore/types/date_type.rb +7 -10
  33. data/lib/superstore/types/float_type.rb +3 -11
  34. data/lib/superstore/types/geo_point_type.rb +30 -0
  35. data/lib/superstore/types/integer_range_type.rb +15 -0
  36. data/lib/superstore/types/integer_type.rb +8 -14
  37. data/lib/superstore/types/json_type.rb +1 -1
  38. data/lib/superstore/types/range_type.rb +58 -0
  39. data/lib/superstore/types/string_type.rb +4 -4
  40. data/lib/superstore/types/time_type.rb +10 -8
  41. data/lib/superstore/types.rb +11 -9
  42. data/lib/superstore.rb +17 -19
  43. data/superstore.gemspec +8 -10
  44. data/test/support/jsonb.rb +3 -1
  45. data/test/support/models.rb +10 -4
  46. data/test/test_helper.rb +7 -3
  47. data/test/unit/adapters/adapter_test.rb +1 -3
  48. data/test/unit/associations/belongs_to_test.rb +1 -1
  49. data/test/unit/associations/has_many_test.rb +10 -2
  50. data/test/unit/attribute_methods/dirty_test.rb +8 -19
  51. data/test/unit/attribute_methods/primary_key_test.rb +1 -1
  52. data/test/unit/attribute_methods_test.rb +10 -22
  53. data/test/unit/{attribute_methods/typecasting_test.rb → attributes_test.rb} +13 -39
  54. data/test/unit/base_test.rb +4 -0
  55. data/test/unit/caching_test.rb +1 -1
  56. data/test/unit/callbacks_test.rb +4 -4
  57. data/test/unit/core_test.rb +15 -20
  58. data/test/unit/persistence_test.rb +36 -44
  59. data/test/unit/{scope/batches_test.rb → relation/scrolling_test.rb} +9 -5
  60. data/test/unit/serialization_test.rb +10 -2
  61. data/test/unit/{timestamps_test.rb → timestamp_test.rb} +5 -5
  62. data/test/unit/types/array_type_test.rb +3 -18
  63. data/test/unit/types/boolean_type_test.rb +7 -21
  64. data/test/unit/types/date_range_type_test.rb +29 -0
  65. data/test/unit/types/date_type_test.rb +15 -6
  66. data/test/unit/types/float_type_test.rb +4 -19
  67. data/test/unit/types/geo_point_type_test.rb +28 -0
  68. data/test/unit/types/integer_range_type_test.rb +28 -0
  69. data/test/unit/types/integer_type_test.rb +7 -16
  70. data/test/unit/types/string_type_test.rb +9 -13
  71. data/test/unit/types/time_type_test.rb +17 -11
  72. data/test/unit/validations_test.rb +2 -2
  73. metadata +39 -53
  74. data/.travis.yml +0 -13
  75. data/Gemfile-rails4.2 +0 -11
  76. data/lib/superstore/attribute_methods/definition.rb +0 -17
  77. data/lib/superstore/attribute_methods/dirty.rb +0 -52
  78. data/lib/superstore/attribute_methods/typecasting.rb +0 -53
  79. data/lib/superstore/caching.rb +0 -13
  80. data/lib/superstore/callbacks.rb +0 -29
  81. data/lib/superstore/connection.rb +0 -24
  82. data/lib/superstore/errors.rb +0 -10
  83. data/lib/superstore/inspect.rb +0 -25
  84. data/lib/superstore/model.rb +0 -38
  85. data/lib/superstore/schema.rb +0 -20
  86. data/lib/superstore/scope/batches.rb +0 -27
  87. data/lib/superstore/scope/finder_methods.rb +0 -51
  88. data/lib/superstore/scope/query_methods.rb +0 -52
  89. data/lib/superstore/scope.rb +0 -73
  90. data/lib/superstore/scoping.rb +0 -30
  91. data/lib/superstore/timestamps.rb +0 -19
  92. data/lib/superstore/type.rb +0 -16
  93. data/lib/superstore/types/base_type.rb +0 -23
  94. data/lib/superstore/validations.rb +0 -44
  95. data/test/unit/attribute_methods/definition_test.rb +0 -16
  96. data/test/unit/inspect_test.rb +0 -26
  97. data/test/unit/schema_test.rb +0 -15
  98. data/test/unit/scope/finder_methods_test.rb +0 -62
  99. data/test/unit/scope/query_methods_test.rb +0 -36
  100. data/test/unit/scoping_test.rb +0 -7
  101. 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 < BaseType
4
- REGEX = /\A[-+]?\d+\Z/
5
- def encode(int)
6
- raise ArgumentError.new("#{int.inspect} is not an Integer.") unless int.kind_of?(Integer)
7
-
8
- int
9
- end
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
@@ -1,6 +1,6 @@
1
1
  module Superstore
2
2
  module Types
3
- class JsonType < BaseType
3
+ class JsonType < Base
4
4
  end
5
5
  end
6
6
  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 < BaseType
4
- def encode(str)
5
- raise ArgumentError.new("#{str.inspect} is not a String") unless str.kind_of?(String)
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 typecast(value)
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 < BaseType
4
- def encode(time)
5
- raise ArgumentError.new("#{time.inspect} does not respond to #to_time") unless time.is_a?(Time) || time.respond_to?(:to_time)
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 decode(str)
11
- Time.parse(str).in_time_zone if str
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
@@ -1,9 +1,11 @@
1
- Superstore::Type.register(:array, Superstore::Types::ArrayType)
2
- Superstore::Type.register(:boolean, Superstore::Types::BooleanType)
3
- Superstore::Type.register(:date, Superstore::Types::DateType)
4
- Superstore::Type.register(:float, Superstore::Types::FloatType)
5
- Superstore::Type.register(:geo_point, Superstore::Types::JsonType)
6
- Superstore::Type.register(:integer, Superstore::Types::IntegerType)
7
- Superstore::Type.register(:json, Superstore::Types::JsonType)
8
- Superstore::Type.register(:time, Superstore::Types::TimeType)
9
- Superstore::Type.register(:string, Superstore::Types::StringType)
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 'global_id/identification'
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 :Caching
14
- autoload :Callbacks
11
+ autoload :AttributeAssignment
12
+ autoload :Attributes
15
13
  autoload :Connection
16
14
  autoload :Core
17
15
  autoload :Identity
18
- autoload :Inspect
19
- autoload :Model
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 :BaseType
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 = '2.4.3'
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', 'Infogroup']
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(ISC MIT)
9
+ s.licenses = %w[ISC MIT]
12
10
 
13
- s.required_ruby_version = '>= 2.0.0'
14
- s.required_rubygems_version = '>= 1.3.5'
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', '>= 3.0')
22
- s.add_runtime_dependency('globalid')
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
@@ -1,6 +1,8 @@
1
1
  class JsonbInitializer
2
2
  def self.initialize!
3
- Superstore::Base.adapter.create_table('issues')
3
+ ActiveRecord::Migration.create_table :issues, id: :string do |t|
4
+ t.jsonb :document, null: false
5
+ end
4
6
  end
5
7
  end
6
8
 
@@ -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
- string :description
9
- string :title
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/setup'
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
- string :force_save
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(Issue)
41
+ @type = self.class.name.sub(/Test$/, '').constantize.new
38
42
  end
39
43
  end
40
44
  end
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class Superstore::Adapters::AdapterTest < Superstore::TestCase
4
- test 'create_table' do
5
- end
6
- end
4
+ end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  class Superstore::Associations::BelongsTest < Superstore::TestCase
4
4
  class TestObject < Superstore::Base
5
5
  self.table_name = 'issues'
6
- string :user_id
6
+ attribute :user_id, type: :string
7
7
  belongs_to :user, primary_key: :special_id
8
8
  end
9
9
 
@@ -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.to_a
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
- string :name
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
- string :name
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 'typecast float before dirty check' do
30
+ test 'cast_value float before dirty check' do
31
31
  record = temp_object do
32
- float :price
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 'typecast boolean before dirty check' do
42
+ test 'cast_value boolean before dirty check' do
43
43
  record = temp_object do
44
- boolean :awesome
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
- string :name
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
- string :name
75
+ attribute :name, type: :string
87
76
  end
88
77
 
89
78
  record = object.create(name: 'foo')
@@ -19,7 +19,7 @@ class Superstore::AttributeMethods::PrimaryKeyTest < Superstore::TestCase
19
19
  end
20
20
 
21
21
  test 'attributes' do
22
- issue = Issue.new
22
+ issue = Issue.new(id: 'lol')
23
23
 
24
24
  assert_not_nil issue.attributes['id']
25
25
  end
@@ -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 ChildIssue < Issue
38
- def title=(val)
39
- self[:title] = val + ' lol'
40
- end
41
- end
33
+ class ModelWithOverride < Superstore::Base
34
+ attribute :title, type: :string
42
35
 
43
- test 'override' do
44
- issue = ChildIssue.new(title: 'hey')
45
-
46
- assert_equal 'hey lol', issue.title
36
+ def title=(v)
37
+ super "#{v} lol"
38
+ end
47
39
  end
48
40
 
49
- class ReservedWord < Superstore::Base
50
- self.table_name = 'issues'
51
- string :system
52
- end
41
+ test 'override' do
42
+ issue = ModelWithOverride.new(title: 'hey')
53
43
 
54
- test 'reserved words' do
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.attribute_exists?(:description)
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::AttributeMethods::TypecastingTest < Superstore::TestCase
3
+ class Superstore::AttributesTest < Superstore::TestCase
4
4
  class TestIssue < Superstore::Base
5
5
  self.table_name = 'issues'
6
6
 
7
- boolean :enabled
8
- float :rating
9
- integer :price
10
- json :orders
11
- string :name
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
- string :description
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 'multiple attributes definition' do
80
- class MultipleAttributesIssue < Superstore::Base
81
- self.table_name = 'issues'
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
- assert_nothing_raised {
85
- MultipleAttributesIssue.string :hello, :greetings, :bye
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
@@ -17,4 +17,8 @@ class Superstore::BaseTest < Superstore::TestCase
17
17
  assert_equal 'sons', Son.table_name
18
18
  assert_equal 'sons', Grandson.table_name
19
19
  end
20
+
21
+ test 'translations' do
22
+ assert_equal :activerecord, Son.i18n_scope
23
+ end
20
24
  end
@@ -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(:nsec)}", issue.cache_key
19
+ assert_equal "issues/1-#{updated_at.utc.to_s(:usec)}", issue.cache_key
20
20
  end
21
21
  end