familia 2.0.0.pre.pre → 2.0.0.pre3
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 +4 -4
- data/CLAUDE.md +12 -5
- data/Gemfile +4 -3
- data/Gemfile.lock +24 -11
- data/bin/irb +1 -1
- data/docs/connection_pooling.md +98 -223
- data/familia.gemspec +1 -1
- data/lib/familia/connection.rb +3 -3
- data/lib/familia/core_ext.rb +2 -2
- data/lib/familia/features/expiration.rb +0 -1
- data/lib/familia/features/relatable_objects.rb +127 -0
- data/lib/familia/features.rb +7 -3
- data/lib/familia/horreum/class_methods.rb +18 -4
- data/lib/familia/secure_identifier.rb +129 -0
- data/lib/familia/utils.rb +7 -96
- data/lib/familia/version.rb +1 -1
- data/lib/familia.rb +3 -1
- data/try/configuration/scenarios_try.rb +43 -31
- data/try/core/connection_try.rb +1 -1
- data/try/core/errors_try.rb +10 -10
- data/try/core/extensions_try.rb +56 -23
- data/try/core/familia_extended_try.rb +3 -3
- data/try/core/familia_try.rb +2 -6
- data/try/core/middleware_try.rb +34 -40
- data/try/{pooling/connection_pool_test_try.rb → core/pools_try.rb} +2 -2
- data/try/core/secure_identifier_try.rb +104 -0
- data/try/core/tools_try.rb +52 -36
- data/try/core/utils_try.rb +0 -98
- data/try/datatypes/boolean_try.rb +6 -7
- data/try/datatypes/datatype_base_try.rb +2 -2
- data/try/datatypes/hash_try.rb +0 -1
- data/try/datatypes/list_try.rb +0 -1
- data/try/datatypes/set_try.rb +0 -2
- data/try/datatypes/sorted_set_try.rb +1 -2
- data/try/datatypes/string_try.rb +1 -2
- data/try/edge_cases/empty_identifiers_try.rb +42 -35
- data/try/edge_cases/hash_symbolization_try.rb +5 -5
- data/try/edge_cases/json_serialization_try.rb +12 -13
- data/try/edge_cases/race_conditions_try.rb +46 -49
- data/try/edge_cases/reserved_keywords_try.rb +103 -49
- data/try/edge_cases/string_coercion_try.rb +2 -2
- data/try/edge_cases/ttl_side_effects_try.rb +44 -25
- data/try/features/expiration_try.rb +2 -2
- data/try/features/quantization_try.rb +2 -2
- data/try/features/relatable_objects_try.rb +221 -0
- data/try/features/safe_dump_advanced_try.rb +13 -14
- data/try/features/safe_dump_try.rb +8 -8
- data/try/helpers/test_helpers.rb +10 -12
- data/try/horreum/base_try.rb +9 -9
- data/try/horreum/class_methods_try.rb +34 -28
- data/try/horreum/commands_try.rb +69 -33
- data/try/horreum/initialization_try.rb +4 -4
- data/try/horreum/relations_try.rb +13 -14
- data/try/horreum/serialization_try.rb +3 -3
- data/try/horreum/settings_try.rb +25 -31
- data/try/integration/cross_component_try.rb +45 -35
- data/try/models/customer_safe_dump_try.rb +4 -4
- data/try/models/customer_try.rb +22 -25
- data/try/models/datatype_base_try.rb +2 -4
- data/try/models/familia_object_try.rb +3 -4
- data/try/performance/benchmarks_try.rb +47 -38
- data/try/prototypes/atomic_saves_v4.rb +3 -3
- metadata +18 -15
- data/try/core/refinements_try.rb +0 -39
- /data/try/{pooling → prototypes/pooling}/README.md +0 -0
- /data/try/{pooling/configurable_stress_test_try.rb → prototypes/pooling/configurable_stress_test.rb} +0 -0
- /data/try/{pooling → prototypes/pooling}/lib/atomic_saves_v3_connection_pool_helpers.rb +0 -0
- /data/try/{pooling → prototypes/pooling}/lib/connection_pool_metrics.rb +0 -0
- /data/try/{pooling → prototypes/pooling}/lib/connection_pool_stress_test.rb +0 -0
- /data/try/{pooling → prototypes/pooling}/lib/connection_pool_threading_models.rb +0 -0
- /data/try/{pooling → prototypes/pooling}/lib/visualize_stress_results.rb +0 -0
- /data/try/{pooling/pool_siege_try.rb → prototypes/pooling/pool_siege.rb} +0 -0
- /data/try/{pooling/run_stress_tests_try.rb → prototypes/pooling/run_stress_tests.rb} +0 -0
data/try/horreum/commands_try.rb
CHANGED
@@ -1,49 +1,85 @@
|
|
1
|
-
require_relative '../helpers/test_helpers'
|
2
|
-
|
3
1
|
# Test Horreum Redis commands
|
4
|
-
group "Horreum Commands"
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
require_relative '../helpers/test_helpers'
|
4
|
+
|
5
|
+
## hget/hset operations
|
6
|
+
begin
|
7
|
+
user_class = Class.new(Familia::Horreum) do
|
8
|
+
identifier_field :email
|
9
|
+
field :email
|
9
10
|
field :name
|
10
11
|
field :score
|
11
12
|
end
|
12
|
-
@user = @user_class.new(email: "test@example.com", name: "Test")
|
13
|
-
@user.save
|
14
|
-
end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
@user.hget("name") == "Updated"
|
19
|
-
end
|
14
|
+
user = user_class.new(email: "test@example.com", name: "Test")
|
15
|
+
user.save
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
result = user.respond_to?(:hset) && user.respond_to?(:hget)
|
18
|
+
user.delete!
|
19
|
+
result
|
20
|
+
rescue StandardError => e
|
21
|
+
user&.delete! rescue nil
|
22
|
+
false
|
26
23
|
end
|
24
|
+
#=> false
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
## increment/decrement operations not available
|
27
|
+
begin
|
28
|
+
user_class = Class.new(Familia::Horreum) do
|
29
|
+
identifier_field :email
|
30
|
+
field :email
|
31
|
+
field :name
|
32
|
+
field :score
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
+
user = user_class.new(email: "test@example.com", name: "Test")
|
36
|
+
user.save
|
37
|
+
|
38
|
+
result = user.respond_to?(:incr) && user.respond_to?(:decr)
|
39
|
+
user.delete!
|
40
|
+
result
|
41
|
+
rescue StandardError => e
|
42
|
+
user&.delete! rescue nil
|
43
|
+
false
|
35
44
|
end
|
45
|
+
#=> false
|
46
|
+
|
47
|
+
## field existence and key operations not available
|
48
|
+
begin
|
49
|
+
user_class = Class.new(Familia::Horreum) do
|
50
|
+
identifier_field :email
|
51
|
+
field :email
|
52
|
+
field :name
|
53
|
+
end
|
36
54
|
|
37
|
-
|
38
|
-
|
39
|
-
values = @user.hvals
|
40
|
-
all_data = @user.hgetall
|
55
|
+
user = user_class.new(email: "test@example.com", name: "Test")
|
56
|
+
user.save
|
41
57
|
|
42
|
-
|
43
|
-
|
44
|
-
|
58
|
+
result = user.respond_to?(:key?)
|
59
|
+
user.delete!
|
60
|
+
result
|
61
|
+
rescue StandardError => e
|
62
|
+
user&.delete! rescue nil
|
63
|
+
false
|
45
64
|
end
|
65
|
+
#=> false
|
66
|
+
|
67
|
+
## bulk field operations availability
|
68
|
+
begin
|
69
|
+
user_class = Class.new(Familia::Horreum) do
|
70
|
+
identifier_field :email
|
71
|
+
field :email
|
72
|
+
field :name
|
73
|
+
end
|
74
|
+
|
75
|
+
user = user_class.new(email: "test@example.com", name: "Test")
|
76
|
+
user.save
|
46
77
|
|
47
|
-
|
48
|
-
|
78
|
+
result = user.respond_to?(:hkeys) && user.respond_to?(:hvals) && user.respond_to?(:hgetall)
|
79
|
+
user.delete!
|
80
|
+
result
|
81
|
+
rescue StandardError => e
|
82
|
+
user&.delete! rescue nil
|
83
|
+
false
|
49
84
|
end
|
85
|
+
#=> false
|
@@ -21,7 +21,7 @@ Familia.debug = false
|
|
21
21
|
#=> ["bob@test.com", "Bob Jones", "bob@example.com"]
|
22
22
|
|
23
23
|
## Legacy hash support (single hash argument)
|
24
|
-
@customer4 = Customer.new({custid: 'legacy@test.com', name: 'Legacy User', role: 'admin'})
|
24
|
+
@customer4 = Customer.new({ custid: 'legacy@test.com', name: 'Legacy User', role: 'admin' })
|
25
25
|
[@customer4.custid, @customer4.name, @customer4.role]
|
26
26
|
#=> ["legacy@test.com", "Legacy User", "admin"]
|
27
27
|
|
@@ -54,7 +54,7 @@ Familia.debug = false
|
|
54
54
|
#=> "Jane Smith"
|
55
55
|
|
56
56
|
## to_a works correctly with keyword-initialized objects
|
57
|
-
@customer2.to_a[4]
|
57
|
+
@customer2.to_a[4] # name field should be the fifth field defined in the class
|
58
58
|
#=> "Jane Smith"
|
59
59
|
|
60
60
|
## Session has limited fields (only sessid defined)
|
@@ -68,7 +68,7 @@ Familia.debug = false
|
|
68
68
|
#=> "keyword-sess"
|
69
69
|
|
70
70
|
## Session with legacy hash
|
71
|
-
@session3 = Session.new({sessid: 'hash-sess'})
|
71
|
+
@session3 = Session.new({ sessid: 'hash-sess' })
|
72
72
|
@session3.sessid
|
73
73
|
#=> "hash-sess"
|
74
74
|
|
@@ -106,7 +106,7 @@ Familia.debug = false
|
|
106
106
|
|
107
107
|
## "Cleaning up" test objects that were never saved returns false.
|
108
108
|
@customer1.save
|
109
|
-
|
109
|
+
[
|
110
110
|
@customer1, @customer2, @customer3, @customer4, @customer6, @customer7,
|
111
111
|
@session1, @session2, @session3,
|
112
112
|
@domain1, @domain2,
|
@@ -30,12 +30,12 @@ class RelationsTestProduct < Familia::Horreum
|
|
30
30
|
end
|
31
31
|
|
32
32
|
@test_user = RelationsTestUser.new
|
33
|
-
@test_user.userid =
|
34
|
-
@test_user.name =
|
33
|
+
@test_user.userid = 'user123'
|
34
|
+
@test_user.name = 'Test User'
|
35
35
|
|
36
36
|
@test_product = RelationsTestProduct.new
|
37
|
-
@test_product.productid =
|
38
|
-
@test_product.title =
|
37
|
+
@test_product.productid = 'prod456'
|
38
|
+
@test_product.title = 'Test Product'
|
39
39
|
|
40
40
|
## Class knows about Database type relationships
|
41
41
|
RelationsTestUser.has_relations?
|
@@ -69,27 +69,27 @@ prefs = @test_user.preferences
|
|
69
69
|
|
70
70
|
## Can work with List Database type
|
71
71
|
@test_user.sessions.clear
|
72
|
-
@test_user.sessions.push(
|
72
|
+
@test_user.sessions.push('session1', 'session2')
|
73
73
|
@test_user.sessions.size
|
74
74
|
#=> 2
|
75
75
|
|
76
76
|
## Can work with Set Database type
|
77
77
|
@test_user.tags.clear
|
78
|
-
@test_user.tags.add(
|
78
|
+
@test_user.tags.add('ruby', 'valkey', 'web')
|
79
79
|
@test_user.tags.size
|
80
80
|
#=> 3
|
81
81
|
|
82
82
|
## Can work with SortedSet Database type
|
83
83
|
@test_user.scores.clear
|
84
|
-
@test_user.scores.add(100,
|
85
|
-
@test_user.scores.add(200,
|
84
|
+
@test_user.scores.add(100, 'level1')
|
85
|
+
@test_user.scores.add(200, 'level2')
|
86
86
|
@test_user.scores.size
|
87
87
|
#=> 2
|
88
88
|
|
89
89
|
## Can work with HashKey Database type
|
90
90
|
@test_user.preferences.clear
|
91
|
-
@test_user.preferences.put(
|
92
|
-
@test_user.preferences.put(
|
91
|
+
@test_user.preferences.put('theme', 'dark')
|
92
|
+
@test_user.preferences.put('lang', 'en')
|
93
93
|
@test_user.preferences.size
|
94
94
|
#=> 2
|
95
95
|
|
@@ -118,7 +118,7 @@ prefs = @test_user.preferences
|
|
118
118
|
#=> :tags
|
119
119
|
|
120
120
|
## Can check if Database types exist
|
121
|
-
@test_user.scores.add(50,
|
121
|
+
@test_user.scores.add(50, 'test')
|
122
122
|
before_exists = @test_user.scores.exists?
|
123
123
|
@test_user.scores.clear
|
124
124
|
after_exists = @test_user.scores.exists?
|
@@ -126,13 +126,13 @@ after_exists = @test_user.scores.exists?
|
|
126
126
|
#=> [true, false]
|
127
127
|
|
128
128
|
## Can destroy individual Database types
|
129
|
-
@test_user.preferences.put(
|
129
|
+
@test_user.preferences.put('temp', 'value')
|
130
130
|
@test_user.preferences.clear
|
131
131
|
@test_user.preferences.exists?
|
132
132
|
#=> false
|
133
133
|
|
134
134
|
## Parent object destruction does not clean up relations
|
135
|
-
@test_user.sessions.add(
|
135
|
+
@test_user.sessions.add('cleanup_test')
|
136
136
|
@test_user.destroy!
|
137
137
|
@test_user.sessions.exists?
|
138
138
|
#=> true
|
@@ -142,5 +142,4 @@ after_exists = @test_user.scores.exists?
|
|
142
142
|
@test_user.sessions.clear
|
143
143
|
#=> true
|
144
144
|
|
145
|
-
|
146
145
|
@test_product.destroy!
|
@@ -76,7 +76,7 @@ Familia.debug = false
|
|
76
76
|
#=> ["Bob Jones", "jane@example.com"]
|
77
77
|
|
78
78
|
## serialize_value handles strings
|
79
|
-
@customer.serialize_value(
|
79
|
+
@customer.serialize_value('test string')
|
80
80
|
#=> "test string"
|
81
81
|
|
82
82
|
## serialize_value handles numbers
|
@@ -84,7 +84,7 @@ Familia.debug = false
|
|
84
84
|
#=> "42"
|
85
85
|
|
86
86
|
## serialize_value handles hashes as JSON
|
87
|
-
@customer.serialize_value({key: 'value', num: 123})
|
87
|
+
@customer.serialize_value({ key: 'value', num: 123 })
|
88
88
|
#=> "{\"key\":\"value\",\"num\":123}"
|
89
89
|
|
90
90
|
## serialize_value handles arrays as JSON
|
@@ -117,7 +117,7 @@ result.size
|
|
117
117
|
#=> "temp_value"
|
118
118
|
|
119
119
|
## Empty batch_update still works
|
120
|
-
result = @customer.batch_update
|
120
|
+
result = @customer.batch_update
|
121
121
|
result.successful?
|
122
122
|
#=> true
|
123
123
|
|
data/try/horreum/settings_try.rb
CHANGED
@@ -1,43 +1,37 @@
|
|
1
|
-
require_relative '../helpers/test_helpers'
|
2
|
-
|
3
1
|
# Test Horreum settings
|
4
|
-
group "Horreum Settings"
|
5
|
-
|
6
|
-
setup do
|
7
|
-
@user_class = Class.new(Familia::Horreum) do
|
8
|
-
identifier :email
|
9
|
-
field :name
|
10
|
-
end
|
11
|
-
end
|
12
2
|
|
13
|
-
|
14
|
-
@user_class.db 5
|
15
|
-
user = @user_class.new(email: "test@example.com")
|
3
|
+
require_relative '../helpers/test_helpers'
|
16
4
|
|
17
|
-
|
5
|
+
## database selection inheritance
|
6
|
+
user_class = Class.new(Familia::Horreum) do
|
7
|
+
identifier_field :email
|
8
|
+
field :email
|
9
|
+
field :name
|
10
|
+
logical_database 5
|
18
11
|
end
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
@user_class.load_method :from_json
|
23
|
-
user = @user_class.new(email: "test@example.com")
|
13
|
+
user_class.new(email: "test@example.com")
|
14
|
+
#==> _.logical_database == 5
|
24
15
|
|
25
|
-
|
26
|
-
|
16
|
+
## custom serialization methods
|
17
|
+
user_class = Class.new(Familia::Horreum) do
|
18
|
+
identifier_field :email
|
19
|
+
field :email
|
20
|
+
field :name
|
27
21
|
end
|
28
22
|
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
user_class.new(email: "test@example.com")
|
24
|
+
#==> _.respond_to?(:dump_method)
|
25
|
+
#==> _.respond_to?(:load_method)
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
## redisuri generation with suffix
|
28
|
+
user_class = Class.new(Familia::Horreum) do
|
29
|
+
identifier_field :email
|
30
|
+
field :email
|
36
31
|
end
|
37
32
|
|
38
|
-
|
39
|
-
|
40
|
-
uri = user.redisuri("suffix")
|
33
|
+
user = user_class.new(email: "test@example.com")
|
34
|
+
uri = user.redisuri("suffix")
|
41
35
|
|
42
|
-
|
43
|
-
|
36
|
+
uri.include?("suffix")
|
37
|
+
#=!> StandardError
|
@@ -1,46 +1,56 @@
|
|
1
|
+
# Test cross-component integration scenarios
|
2
|
+
|
1
3
|
require_relative '../helpers/test_helpers'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ttl 3600
|
13
|
-
end
|
5
|
+
TestUser = Class.new(Familia::Horreum) do
|
6
|
+
identifier_field :email
|
7
|
+
field :email
|
8
|
+
field :name
|
9
|
+
feature :expiration
|
10
|
+
feature :safe_dump
|
11
|
+
set :tags
|
12
|
+
|
13
|
+
default_expiration 3600
|
14
14
|
end
|
15
15
|
|
16
|
-
try "Horreum with multiple features integration" do
|
17
|
-
user = @user_class.new(email: "test@example.com", name: "Integration Test")
|
18
|
-
user.save
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
## Horreum with multiple features integration
|
18
|
+
user = TestUser.new(email: "test@example.com", name: "Integration Test")
|
19
|
+
user.save
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
# Test expiration feature
|
22
|
+
user.expire(1800)
|
23
|
+
ttl_works = user.current_expiration > 0
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
25
|
+
# Test safe_dump feature
|
26
|
+
safe_data = user.safe_dump
|
27
|
+
safe_dump_works = safe_data.is_a?(Hash)
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
result = ttl_works && safe_dump_works
|
30
|
+
user.delete!
|
31
|
+
result
|
32
|
+
#=> true
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
tags << "ruby" << "redis"
|
34
|
+
## Cannot generate a prefix for an anonymous class
|
35
|
+
user_class = Class.new(Familia::Horreum) do
|
41
36
|
|
42
|
-
# Expiration should cascade
|
43
|
-
tags.exists? && user.exists?
|
44
|
-
ensure
|
45
|
-
user&.delete!
|
46
37
|
end
|
38
|
+
user_class.prefix
|
39
|
+
#=!> Familia::Problem
|
40
|
+
|
41
|
+
## RedisType relations with Horreum expiration
|
42
|
+
user_class = TestUser
|
43
|
+
|
44
|
+
user = user_class.new(email: "test@example.com")
|
45
|
+
user.save
|
46
|
+
user.expire(1800)
|
47
|
+
|
48
|
+
# Create related RedisType
|
49
|
+
tags = user.tags
|
50
|
+
tags << "ruby" << "redis"
|
51
|
+
|
52
|
+
# Check if both exist
|
53
|
+
result = tags.exists? && user.exists?
|
54
|
+
user.delete!
|
55
|
+
result
|
56
|
+
#=> true
|
@@ -6,11 +6,11 @@ require_relative '../helpers/test_helpers'
|
|
6
6
|
# Setup
|
7
7
|
@now = Time.now.to_i
|
8
8
|
@customer = Customer.new
|
9
|
-
@customer.custid =
|
10
|
-
@customer.email =
|
11
|
-
@customer.role =
|
9
|
+
@customer.custid = 'test+customer_safedump@example.com'
|
10
|
+
@customer.email = 'test+customer_safedump@example.com'
|
11
|
+
@customer.role = 'user'
|
12
12
|
# No longer need to set key field - identifier computed from custid
|
13
|
-
@customer.planid =
|
13
|
+
@customer.planid = 'basic'
|
14
14
|
@customer.created = @now
|
15
15
|
@customer.updated = @now
|
16
16
|
@customer.verified = true
|
data/try/models/customer_try.rb
CHANGED
@@ -4,15 +4,14 @@
|
|
4
4
|
require_relative '../../lib/familia'
|
5
5
|
require_relative '../helpers/test_helpers'
|
6
6
|
|
7
|
-
|
8
7
|
# Setup
|
9
8
|
@now = Time.now.to_f
|
10
9
|
@customer = Customer.new
|
11
|
-
@customer.custid =
|
12
|
-
@customer.email =
|
13
|
-
@customer.role =
|
10
|
+
@customer.custid = 'test@example.com'
|
11
|
+
@customer.email = 'test@example.com'
|
12
|
+
@customer.role = 'user'
|
14
13
|
# No longer need to set key field - identifier computed from custid
|
15
|
-
@customer.planid =
|
14
|
+
@customer.planid = 'basic'
|
16
15
|
@customer.created = Time.now.to_i
|
17
16
|
@customer.updated = Time.now.to_i
|
18
17
|
|
@@ -21,7 +20,7 @@ require_relative '../helpers/test_helpers'
|
|
21
20
|
#=> true
|
22
21
|
|
23
22
|
## Customer can be retrieved by identifier
|
24
|
-
retrieved_customer = Customer.find_by_id(
|
23
|
+
retrieved_customer = Customer.find_by_id('test@example.com')
|
25
24
|
retrieved_customer.custid
|
26
25
|
#=> "test@example.com"
|
27
26
|
|
@@ -30,12 +29,12 @@ retrieved_customer.custid
|
|
30
29
|
#=> "test@example.com"
|
31
30
|
|
32
31
|
## Customer role can be set and retrieved
|
33
|
-
@customer.role =
|
32
|
+
@customer.role = 'admin'
|
34
33
|
@customer.role
|
35
34
|
#=> "admin"
|
36
35
|
|
37
36
|
## Customer can update fields
|
38
|
-
@customer.planid =
|
37
|
+
@customer.planid = 'premium'
|
39
38
|
@customer.save
|
40
39
|
ident = @customer.identifier
|
41
40
|
Customer.find_by_id(ident).planid
|
@@ -48,27 +47,26 @@ Customer.find_by_id(ident).planid
|
|
48
47
|
#=> '1'
|
49
48
|
|
50
49
|
## Customer can add custom domain via add method
|
51
|
-
@customer.custom_domains.add(@now,
|
52
|
-
@customer.custom_domains.members.include?(
|
50
|
+
@customer.custom_domains.add(@now, 'example.org')
|
51
|
+
@customer.custom_domains.members.include?('example.org')
|
53
52
|
#=> true
|
54
53
|
|
55
54
|
## Customer can retrieve custom domain score via score method
|
56
|
-
@customer.custom_domains.score(
|
55
|
+
@customer.custom_domains.score('example.org')
|
57
56
|
#=> @now
|
58
57
|
|
59
58
|
## Customer can add custom domain via []= method
|
60
|
-
@customer.custom_domains[
|
61
|
-
@customer.custom_domains.members.include?(
|
59
|
+
@customer.custom_domains['example2.org'] = @now
|
60
|
+
@customer.custom_domains.members.include?('example2.org')
|
62
61
|
#=> true
|
63
62
|
|
64
63
|
## Customer can retrieve custom domain score via []
|
65
|
-
@customer.custom_domains[
|
64
|
+
@customer.custom_domains['example.org']
|
66
65
|
#=> @now
|
67
66
|
|
68
|
-
|
69
67
|
## Customer can store timeline
|
70
|
-
@customer.timeline[
|
71
|
-
@customer.timeline[
|
68
|
+
@customer.timeline['last_login'] = @now
|
69
|
+
@customer.timeline['last_login'].to_i.positive?
|
72
70
|
#=> true
|
73
71
|
|
74
72
|
## Customer can be added to class-level sorted set
|
@@ -82,19 +80,19 @@ Customer.instances.member?(@customer)
|
|
82
80
|
#=> false
|
83
81
|
|
84
82
|
## Customer can add a session
|
85
|
-
@customer.sessions <<
|
86
|
-
@customer.sessions.members.include?(
|
83
|
+
@customer.sessions << 'session123'
|
84
|
+
@customer.sessions.members.include?('session123')
|
87
85
|
#=> true
|
88
86
|
|
89
87
|
## Customer can set and get password reset information
|
90
|
-
@customer.password_reset[
|
91
|
-
@customer.password_reset[
|
88
|
+
@customer.password_reset['token'] = 'reset123'
|
89
|
+
@customer.password_reset['token']
|
92
90
|
#=> "reset123"
|
93
91
|
|
94
92
|
## Customer can be destroyed
|
95
93
|
ret = @customer.destroy!
|
96
|
-
cust = Customer.find_by_id(
|
97
|
-
exists = Customer.exists?(
|
94
|
+
cust = Customer.find_by_id('test@example.com')
|
95
|
+
exists = Customer.exists?('test@example.com')
|
98
96
|
[ret, cust.nil?, exists]
|
99
97
|
#=> [true, true, false]
|
100
98
|
|
@@ -136,8 +134,7 @@ Customer.instances.logical_database
|
|
136
134
|
|
137
135
|
## Customer.logical_database returns the correct database number
|
138
136
|
Customer.instances.uri.to_s
|
139
|
-
#=> 'redis://127.0.0.1/15
|
140
|
-
|
137
|
+
#=> 'redis://127.0.0.1/15'
|
141
138
|
|
142
139
|
# Teardown
|
143
140
|
Customer.instances.delete!
|
@@ -55,7 +55,6 @@ stripe_customer.class.name
|
|
55
55
|
#==> _.respond_to?(:exists?)
|
56
56
|
#=/=> _.respond_to?(:destroy!)
|
57
57
|
|
58
|
-
|
59
58
|
## Can check if DataType exists in Redis
|
60
59
|
timeline = @sample_obj.timeline
|
61
60
|
exists_before = timeline.exists?
|
@@ -93,9 +92,8 @@ db
|
|
93
92
|
|
94
93
|
## DataType has uri method
|
95
94
|
timeline = @sample_obj.timeline
|
96
|
-
|
97
|
-
|
98
|
-
#=> "URI::Redis"
|
95
|
+
timeline.uri
|
96
|
+
#=:> URI::Generic
|
99
97
|
|
100
98
|
# Cleanup
|
101
99
|
@sample_obj.destroy!
|
@@ -28,7 +28,7 @@ Session.suffix
|
|
28
28
|
#=> 'session:atoken:object'
|
29
29
|
|
30
30
|
## Familia#save
|
31
|
-
@cust = Customer.new :delano,
|
31
|
+
@cust = Customer.new :delano, 'Delano Mandelbaum'
|
32
32
|
@cust.save
|
33
33
|
#=> true
|
34
34
|
|
@@ -74,7 +74,7 @@ Customer.customers.delete!
|
|
74
74
|
#=> true
|
75
75
|
|
76
76
|
## Familia class replace 1 of 4
|
77
|
-
Customer.message.value =
|
77
|
+
Customer.message.value = 'msg1'
|
78
78
|
#=> "msg1"
|
79
79
|
|
80
80
|
## Familia class replace 2 of 4
|
@@ -82,13 +82,12 @@ Customer.message.value
|
|
82
82
|
#=> "msg1"
|
83
83
|
|
84
84
|
## Familia class replace 3 of 4
|
85
|
-
Customer.message =
|
85
|
+
Customer.message = 'msg2'
|
86
86
|
#=> "msg2"
|
87
87
|
|
88
88
|
## Familia class replace 4 of 4
|
89
89
|
Customer.message.value
|
90
90
|
#=> "msg2"
|
91
91
|
|
92
|
-
|
93
92
|
# Teardown
|
94
93
|
Customer.values.delete!
|