familia 2.0.0.pre13 → 2.0.0.pre15

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rst +29 -7
  3. data/Gemfile.lock +1 -1
  4. data/README.md +21 -2
  5. data/docs/guides/Feature-System-Autoloading.md +3 -33
  6. data/docs/guides/time-utilities.md +4 -4
  7. data/docs/migrating/v2.0.0-pre11.md +2 -2
  8. data/docs/migrating/v2.0.0-pre13.md +38 -272
  9. data/docs/migrating/v2.0.0-pre14.md +37 -0
  10. data/examples/safe_dump.rb +1 -1
  11. data/lib/familia/base.rb +1 -1
  12. data/lib/familia/data_type.rb +1 -1
  13. data/lib/familia/{autoloader.rb → features/autoloader.rb} +33 -25
  14. data/lib/familia/features/encrypted_fields.rb +2 -2
  15. data/lib/familia/features/expiration/extensions.rb +61 -0
  16. data/lib/familia/features/expiration.rb +5 -62
  17. data/lib/familia/features/external_identifier.rb +6 -4
  18. data/lib/familia/features/object_identifier.rb +2 -1
  19. data/lib/familia/features/quantization.rb +3 -3
  20. data/lib/familia/features/relationships.rb +5 -6
  21. data/lib/familia/features/safe_dump.rb +3 -5
  22. data/lib/familia/features/transient_fields.rb +3 -1
  23. data/lib/familia/features.rb +20 -11
  24. data/lib/familia/field_type.rb +1 -1
  25. data/lib/familia/horreum.rb +1 -1
  26. data/lib/familia/refinements/{time_utils.rb → time_literals.rb} +35 -4
  27. data/lib/familia/refinements.rb +1 -1
  28. data/lib/familia/utils.rb +1 -1
  29. data/lib/familia/version.rb +1 -1
  30. data/lib/familia.rb +0 -1
  31. data/try/core/autoloader_try.rb +9 -9
  32. data/try/core/extensions_try.rb +1 -1
  33. data/try/core/time_utils_try.rb +18 -18
  34. data/try/features/external_identifier/external_identifier_try.rb +26 -0
  35. data/try/features/safe_dump/module_based_extensions_try.rb +100 -0
  36. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -4
  37. data/try/helpers/test_helpers.rb +6 -6
  38. metadata +6 -5
  39. data/lib/familia/features/autoloadable.rb +0 -113
  40. data/try/features/autoloadable/autoloadable_try.rb +0 -61
@@ -1,11 +1,41 @@
1
- # frozen_string_literal: true
1
+ # lib/familia/features/autoloader.rb
2
2
 
3
- module Familia
3
+ module Familia::Features
4
4
  # Provides autoloading functionality for Ruby files based on patterns and conventions.
5
5
  #
6
6
  # Used by the Features module at library startup to load feature files, and available
7
7
  # as a utility for other modules requiring file autoloading capabilities.
8
8
  module Autoloader
9
+ using Familia::Refinements::SnakeCase
10
+
11
+ # Autoloads feature files when this module is included.
12
+ #
13
+ # Discovers and loads all Ruby files in the features/ directory relative to the
14
+ # including module's location. Typically used by Familia::Features.
15
+ #
16
+ # @param base [Module] the module including this autoloader
17
+ def self.included(base)
18
+
19
+ # Get the directory where the including module is defined
20
+ # This should be lib/familia for the Features module
21
+ base_path = File.dirname(caller_locations(1, 1).first.path)
22
+ model_name = base.name.snake_case
23
+ dir_patterns = [
24
+ File.join(base_path, 'features', '*.rb'),
25
+ File.join(base_path, model_name, 'features', '*.rb'),
26
+ File.join(base_path, model_name, 'features.rb'),
27
+ ]
28
+
29
+ # Ensure the Features module exists within the base module
30
+ unless base.const_defined?(:Features) || model_name.eql?('features')
31
+ base.const_set(:Features, Module.new)
32
+ end
33
+
34
+
35
+ # Use the shared autoload_files method
36
+ autoload_files(dir_patterns, log_prefix: "Autoloader[#{model_name}]")
37
+ end
38
+
9
39
  # Autoloads Ruby files matching the given patterns.
10
40
  #
11
41
  # @param patterns [String, Array<String>] file patterns to match (supports Dir.glob patterns)
@@ -15,6 +45,7 @@ module Familia
15
45
  patterns = Array(patterns)
16
46
 
17
47
  patterns.each do |pattern|
48
+ Familia.ld "[#{log_prefix}] Autoloader loading features from #{pattern}"
18
49
  Dir.glob(pattern).each do |file_path|
19
50
  basename = File.basename(file_path)
20
51
 
@@ -26,28 +57,5 @@ module Familia
26
57
  end
27
58
  end
28
59
  end
29
-
30
- # Autoloads feature files when this module is included.
31
- #
32
- # Discovers and loads all Ruby files in the features/ directory relative to the
33
- # including module's location. Typically used by Familia::Features.
34
- #
35
- # @param base [Module] the module including this autoloader
36
- def self.included(base)
37
- # Get the directory where the including module is defined
38
- # This should be lib/familia for the Features module
39
- base_path = File.dirname(caller_locations(1, 1).first.path)
40
- features_dir = File.join(base_path, 'features')
41
-
42
- Familia.ld "[DEBUG] Autoloader loading features from #{features_dir}"
43
-
44
- return unless Dir.exist?(features_dir)
45
-
46
- # Use the shared autoload_files method
47
- autoload_files(
48
- File.join(features_dir, '*.rb'),
49
- log_prefix: 'Autoloader'
50
- )
51
- end
52
60
  end
53
61
  end
@@ -255,6 +255,8 @@ module Familia
255
255
  # - Insider threats with application access
256
256
  #
257
257
  module EncryptedFields
258
+ Familia::Base.add_feature self, :encrypted_fields
259
+
258
260
  def self.included(base)
259
261
  Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
260
262
  base.extend ClassMethods
@@ -430,8 +432,6 @@ module Familia
430
432
  end
431
433
  end
432
434
  end
433
-
434
- Familia::Base.add_feature self, :encrypted_fields
435
435
  end
436
436
  end
437
437
  end
@@ -0,0 +1,61 @@
1
+ # lib/familia/features/expiration/extensions.rb
2
+
3
+ module Familia
4
+ # Add a default update_expiration method for all classes that include
5
+ # Familia::Base. Since expiration is a core feature, we can confidently
6
+ # call `horreum_instance.update_expiration` without defensive programming
7
+ # even when expiration is not enabled for the horreum_instance class.
8
+ module Base
9
+ # Base implementation of update_expiration that maintains API compatibility
10
+ # with the :expiration feature's implementation.
11
+ #
12
+ # This is a no-op implementation that gets overridden by the :expiration
13
+ # feature. It accepts an optional default_expiration parameter to maintain
14
+ # interface compatibility with the overriding implementations.
15
+ #
16
+ # @param default_expiration [Numeric, nil] Time To Live in seconds
17
+ # @return [nil] Always returns nil for the base implementation
18
+ #
19
+ # @note This is a no-op implementation. Classes that need expiration
20
+ # functionality should include the :expiration feature.
21
+ #
22
+ # @example Enable expiration feature
23
+ # class MyModel < Familia::Horreum
24
+ # feature :expiration
25
+ # default_expiration 1.hour
26
+ # end
27
+ #
28
+ def update_expiration(default_expiration: nil)
29
+ Familia.ld <<~LOG
30
+ [update_expiration] Expiration feature not enabled for #{self.class}.
31
+ Key: #{dbkey} Arg: #{default_expiration} (caller: #{caller(1..1)})
32
+ LOG
33
+ nil
34
+ end
35
+
36
+ # Base implementation of ttl that returns -1 (no expiration set)
37
+ #
38
+ # @return [Integer] Always returns -1 for the base implementation
39
+ #
40
+ def ttl
41
+ -1
42
+ end
43
+
44
+ # Base implementation of expires? that returns false
45
+ #
46
+ # @return [Boolean] Always returns false for the base implementation
47
+ #
48
+ def expires?
49
+ false
50
+ end
51
+
52
+ # Base implementation of expired? that returns false
53
+ #
54
+ # @param threshold [Numeric] Ignored in base implementation
55
+ # @return [Boolean] Always returns false for the base implementation
56
+ #
57
+ def expired?(_threshold = 0)
58
+ false
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,7 @@
1
1
  # lib/familia/features/expiration.rb
2
2
 
3
+ require_relative 'expiration/extensions'
4
+
3
5
  module Familia
4
6
  module Features
5
7
  # Expiration is a feature that provides Time To Live (TTL) management for Familia
@@ -149,7 +151,9 @@ module Familia
149
151
  module Expiration
150
152
  @default_expiration = nil
151
153
 
152
- using Familia::Refinements::TimeUtils
154
+ Familia::Base.add_feature self, :expiration
155
+
156
+ using Familia::Refinements::TimeLiterals
153
157
 
154
158
  def self.included(base)
155
159
  Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
@@ -354,67 +358,6 @@ module Familia
354
358
  redis.persist(dbkey)
355
359
  end
356
360
 
357
- Familia::Base.add_feature self, :expiration
358
- end
359
- end
360
- end
361
-
362
- module Familia
363
- # Add a default update_expiration method for all classes that include
364
- # Familia::Base. Since expiration is a core feature, we can confidently
365
- # call `horreum_instance.update_expiration` without defensive programming
366
- # even when expiration is not enabled for the horreum_instance class.
367
- module Base
368
- # Base implementation of update_expiration that maintains API compatibility
369
- # with the :expiration feature's implementation.
370
- #
371
- # This is a no-op implementation that gets overridden by the :expiration
372
- # feature. It accepts an optional default_expiration parameter to maintain
373
- # interface compatibility with the overriding implementations.
374
- #
375
- # @param default_expiration [Numeric, nil] Time To Live in seconds
376
- # @return [nil] Always returns nil for the base implementation
377
- #
378
- # @note This is a no-op implementation. Classes that need expiration
379
- # functionality should include the :expiration feature.
380
- #
381
- # @example Enable expiration feature
382
- # class MyModel < Familia::Horreum
383
- # feature :expiration
384
- # default_expiration 1.hour
385
- # end
386
- #
387
- def update_expiration(default_expiration: nil)
388
- Familia.ld <<~LOG
389
- [update_expiration] Expiration feature not enabled for #{self.class}.
390
- Key: #{dbkey} Arg: #{default_expiration} (caller: #{caller(1..1)})
391
- LOG
392
- nil
393
- end
394
-
395
- # Base implementation of ttl that returns -1 (no expiration set)
396
- #
397
- # @return [Integer] Always returns -1 for the base implementation
398
- #
399
- def ttl
400
- -1
401
- end
402
-
403
- # Base implementation of expires? that returns false
404
- #
405
- # @return [Boolean] Always returns false for the base implementation
406
- #
407
- def expires?
408
- false
409
- end
410
-
411
- # Base implementation of expired? that returns false
412
- #
413
- # @param threshold [Numeric] Ignored in base implementation
414
- # @return [Boolean] Always returns false for the base implementation
415
- #
416
- def expired?(_threshold = 0)
417
- false
418
361
  end
419
362
  end
420
363
  end
@@ -5,6 +5,9 @@ module Familia
5
5
  # Familia::Features::ExternalIdentifier
6
6
  #
7
7
  module ExternalIdentifier
8
+
9
+ Familia::Base.add_feature self, :external_identifier, depends_on: [:object_identifier]
10
+
8
11
  def self.included(base)
9
12
  Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
10
13
  base.extend ClassMethods
@@ -99,7 +102,7 @@ module Familia
99
102
  klass.define_method :"#{method_name}=" do |value|
100
103
  # Remove old mapping if extid is changing
101
104
  old_value = instance_variable_get(:"@#{field_name}")
102
- self.class.extid_lookup.del(old_value) if old_value && old_value != value && respond_to?(:identifier)
105
+ self.class.extid_lookup.remove_field(old_value) if old_value && old_value != value
103
106
 
104
107
  # Set the new value
105
108
  instance_variable_set(:"@#{field_name}", value)
@@ -153,7 +156,7 @@ module Familia
153
156
  find_by_id(primary_id)
154
157
  rescue Familia::NotFound
155
158
  # If the object was deleted but mapping wasn't cleaned up
156
- extid_lookup.del(extid)
159
+ extid_lookup.remove_field(extid)
157
160
  nil
158
161
  end
159
162
  end
@@ -236,7 +239,7 @@ module Familia
236
239
  def destroy!
237
240
  # Clean up extid mapping when object is destroyed
238
241
  current_extid = instance_variable_get(:@extid)
239
- self.class.extid_lookup.del(current_extid) if current_extid
242
+ self.class.extid_lookup.remove_field(current_extid) if current_extid
240
243
 
241
244
  super if defined?(super)
242
245
  end
@@ -304,7 +307,6 @@ module Familia
304
307
  end
305
308
  end
306
309
 
307
- Familia::Base.add_feature self, :external_identifier, depends_on: [:object_identifier]
308
310
  end
309
311
  end
310
312
  end
@@ -81,6 +81,8 @@ module Familia
81
81
  # - Custom generators allow domain-specific security requirements
82
82
  #
83
83
  module ObjectIdentifier
84
+ Familia::Base.add_feature self, :object_identifier, depends_on: []
85
+
84
86
  DEFAULT_GENERATOR = :uuid_v7
85
87
 
86
88
  def self.included(base)
@@ -301,7 +303,6 @@ module Familia
301
303
  Familia.trace :OBJID_INIT, dbclient, "Generator strategy: #{generator}", caller(1..1)
302
304
  end
303
305
 
304
- Familia::Base.add_feature self, :object_identifier, depends_on: []
305
306
  end
306
307
  end
307
308
  end
@@ -246,7 +246,9 @@ module Familia
246
246
  #
247
247
  module Quantization
248
248
 
249
- using Familia::Refinements::TimeUtils
249
+ Familia::Base.add_feature self, :quantization
250
+
251
+ using Familia::Refinements::TimeLiterals
250
252
 
251
253
  def self.included(base)
252
254
  Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
@@ -397,8 +399,6 @@ module Familia
397
399
  end
398
400
 
399
401
  extend ClassMethods
400
-
401
- Familia::Base.add_feature self, :quantization
402
402
  end
403
403
  end
404
404
  end
@@ -98,9 +98,13 @@ module Familia
98
98
  # { owner: team, collection: :domains }
99
99
  # ], min_permission: :read)
100
100
  module Relationships
101
+
102
+ # Register the feature with Familia
103
+ Familia::Base.add_feature Relationships, :relationships
104
+
101
105
  # Feature initialization
102
106
  def self.included(base)
103
- puts "[DEBUG] Relationships included in #{base}"
107
+ Familia.ld "[#{base}] Relationships included"
104
108
  base.extend ClassMethods
105
109
  base.include InstanceMethods
106
110
 
@@ -108,11 +112,8 @@ module Familia
108
112
  base.include ScoreEncoding
109
113
  base.include RedisOperations
110
114
 
111
- puts '[DEBUG] Including Tracking module'
112
115
  base.include Tracking
113
- puts '[DEBUG] Extending with Tracking::ClassMethods'
114
116
  base.extend Tracking::ClassMethods
115
- puts "[DEBUG] Base now responds to tracked_in: #{base.respond_to?(:tracked_in)}"
116
117
 
117
118
  base.include Indexing
118
119
  base.extend Indexing::ClassMethods
@@ -466,8 +467,6 @@ module Familia
466
467
  end
467
468
  end
468
469
 
469
- # Register the feature with Familia
470
- Familia::Base.add_feature Relationships, :relationships
471
470
  end
472
471
  end
473
472
  end
@@ -41,15 +41,15 @@ module Familia::Features
41
41
  # of symbols in the order they were defined.
42
42
  #
43
43
  module SafeDump
44
- include Familia::Features::Autoloadable
44
+
45
+ Familia::Base.add_feature self, :safe_dump
46
+
45
47
  using Familia::Refinements::SnakeCase
46
48
 
47
49
  @dump_method = :to_json
48
50
  @load_method = :from_json
49
51
 
50
52
  def self.included(base)
51
- # Call the Autoloadable module's included method for post-inclusion setup
52
- super
53
53
 
54
54
  Familia.trace(:LOADED, self, base, caller(1..1)) if Familia.debug?
55
55
  base.extend ClassMethods
@@ -153,8 +153,6 @@ module Familia::Features
153
153
  end
154
154
 
155
155
  extend ClassMethods
156
-
157
- Familia::Base.add_feature self, :safe_dump
158
156
  end
159
157
  end
160
158
  # rubocop:enable ThreadSafety/ClassInstanceVariable
@@ -104,6 +104,9 @@ module Familia
104
104
  # (HashiCorp Vault, AWS Secrets Manager) or languages with secure memory handling.
105
105
  #
106
106
  module TransientFields
107
+
108
+ Familia::Base.add_feature self, :transient_fields, depends_on: nil
109
+
107
110
  def self.included(base)
108
111
  Familia.trace :LOADED, self, base, caller(1..1) if Familia.debug?
109
112
  base.extend ClassMethods
@@ -221,7 +224,6 @@ module Familia
221
224
  end
222
225
  end
223
226
 
224
- Familia::Base.add_feature self, :transient_fields, depends_on: nil
225
227
  end
226
228
  end
227
229
  end
@@ -1,7 +1,7 @@
1
1
  # lib/familia/features.rb
2
2
 
3
3
  # Load the Autoloader first, then use it to load all other features
4
- require_relative 'autoloader'
4
+ require_relative 'features/autoloader'
5
5
 
6
6
  module Familia
7
7
  FeatureDefinition = Data.define(:name, :depends_on)
@@ -25,12 +25,21 @@ module Familia
25
25
  # feature options. When you enable a feature with options in different models,
26
26
  # each model stores its own separate configuration without interference.
27
27
  #
28
- # ## Project Organization with Autoloadable
28
+ # ## Project Organization with Autoloader
29
29
  #
30
- # For large projects, use {Familia::Features::Autoloadable} to automatically load
30
+ # For large projects, use {Familia::Features::Autoloader} to automatically load
31
31
  # project-specific features from a dedicated directory structure. This helps
32
32
  # organize complex models by separating features into individual files.
33
33
  #
34
+ # ### Class Reopening (Deprecated)
35
+ #
36
+ # Direct class reopening still works but generates deprecation warnings:
37
+ #
38
+ # # app/models/customer/safe_dump_extensions.rb
39
+ # class Customer
40
+ # safe_dump_fields :name, :email # Works but not recommended
41
+ # end
42
+ #
34
43
  # @example Different models with different feature options
35
44
  # class UserModel < Familia::Horreum
36
45
  # feature :object_identifier, generator: :uuid_v4
@@ -57,15 +66,15 @@ module Familia
57
66
  # # In your model file: app/models/customer.rb
58
67
  # class Customer < Familia::Horreum
59
68
  # module Features
60
- # include Familia::Features::Autoloadable
69
+ # include Familia::Features::Autoloader
61
70
  # # Automatically loads all .rb files from app/models/customer/features/
62
71
  # end
63
72
  # end
64
73
  #
65
- # @see Familia::Features::Autoloadable For automatic feature loading
74
+ # @see Familia::Features::Autoloader For automatic feature loading
66
75
  #
67
76
  module Features
68
- include Familia::Autoloader
77
+ include Familia::Features::Autoloader
69
78
 
70
79
  @features_enabled = nil
71
80
  attr_reader :features_enabled
@@ -110,8 +119,8 @@ module Familia
110
119
 
111
120
  # If there's a value provided check that it's a valid feature
112
121
  feature_name = feature_name.to_sym
113
- feature_class = Familia::Base.find_feature(feature_name, self)
114
- unless feature_class
122
+ feature_module = Familia::Base.find_feature(feature_name, self)
123
+ unless feature_module
115
124
  raise Familia::Problem, "Unsupported feature: #{feature_name}"
116
125
  end
117
126
 
@@ -146,11 +155,11 @@ module Familia
146
155
  end
147
156
 
148
157
  # Extend the Familia::Base subclass (e.g. Customer) with the feature module
149
- include feature_class
158
+ include feature_module
150
159
 
151
160
  # Trigger post-inclusion autoloading for features that support it
152
- if feature_class.respond_to?(:post_inclusion_autoload)
153
- feature_class.post_inclusion_autoload(self, feature_name, options)
161
+ if feature_module.respond_to?(:post_inclusion_autoload)
162
+ feature_module.post_inclusion_autoload(self, feature_name, options)
154
163
  end
155
164
 
156
165
  # NOTE: Do we want to extend Familia::DataType here? That would make it
@@ -29,7 +29,7 @@ module Familia
29
29
  class FieldType
30
30
  attr_reader :name, :options, :method_name, :fast_method_name, :on_conflict, :loggable
31
31
 
32
- using Familia::Refinements::TimeUtils
32
+ using Familia::Refinements::TimeLiterals
33
33
 
34
34
  # Initialize a new field type
35
35
  #
@@ -31,7 +31,7 @@ module Familia
31
31
  include Familia::Horreum::Core
32
32
  include Familia::Horreum::Settings
33
33
 
34
- using Familia::Refinements::TimeUtils
34
+ using Familia::Refinements::TimeLiterals
35
35
 
36
36
  # Singleton Class Context
37
37
  #
@@ -1,10 +1,41 @@
1
- # lib/familia/refinements/time_utils.rb
1
+ # lib/familia/refinements/time_literals.rb
2
2
 
3
3
  module Familia
4
4
  module Refinements
5
5
 
6
- # Familia::Refinements::TimeUtils
7
- module TimeUtils
6
+ # Familia::Refinements::TimeLiterals
7
+ #
8
+ # This module provides a set of refinements for `Numeric` and `String` to
9
+ # enable readable and expressive time duration and timestamp manipulation.
10
+ #
11
+ # The name "TimeLiterals" reflects its core purpose: to allow us to treat
12
+ # numeric values directly as "literals" of time units (e.g., `5.minutes`,
13
+ # `1.day`). It extends this concept to include conversions between these
14
+ # literal time quantities, parsing string representations of time
15
+ # durations, and performing common timestamp-based calculations
16
+ # in an intuitive manner.
17
+ #
18
+ # @example Expressing durations
19
+ # 5.minutes.ago #=> A Time object 5 minutes in the past
20
+ # 1.day.from_now #=> A Time object 1 day in the future
21
+ # (2.5).hours #=> 9000.0 (seconds)
22
+ #
23
+ # @example Converting between units
24
+ # 3600.in_hours #=> 1.0
25
+ # 86400.in_days #=> 1.0
26
+ #
27
+ # @example Parsing string durations
28
+ # "30m".in_seconds #=> 1800.0
29
+ # "2.5h".in_seconds #=> 9000.0
30
+ #
31
+ # @example Timestamp calculations
32
+ # timestamp = 2.days.ago.to_i
33
+ # timestamp.days_old #=> ~2.0
34
+ # timestamp.older_than?(1.day) #=> true
35
+ #
36
+ # @note `to_bytes` also lives here until we find it a better home!
37
+ #
38
+ module TimeLiterals
8
39
  # Time unit constants
9
40
  PER_MICROSECOND = 0.000001
10
41
  PER_MILLISECOND = 0.001
@@ -65,7 +96,7 @@ module Familia
65
96
  alias_method :month, :months
66
97
  alias_method :year, :years
67
98
 
68
- # Fun aliases
99
+ # Shortest aliases
69
100
  alias_method :ms, :milliseconds
70
101
  alias_method :μs, :microseconds
71
102
 
@@ -2,4 +2,4 @@
2
2
 
3
3
  require_relative 'refinements/logger_trace'
4
4
  require_relative 'refinements/snake_case'
5
- require_relative 'refinements/time_utils'
5
+ require_relative 'refinements/time_literals'
data/lib/familia/utils.rb CHANGED
@@ -6,7 +6,7 @@ module Familia
6
6
  #
7
7
  module Utils
8
8
 
9
- using Familia::Refinements::TimeUtils
9
+ using Familia::Refinements::TimeLiterals
10
10
 
11
11
  # Joins array elements with Familia delimiter
12
12
  # @param val [Array] elements to join
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Familia
4
4
  # Version information for the Familia
5
- VERSION = '2.0.0.pre13'.freeze unless defined?(Familia::VERSION)
5
+ VERSION = '2.0.0.pre15'.freeze unless defined?(Familia::VERSION)
6
6
  end
data/lib/familia.rb CHANGED
@@ -82,7 +82,6 @@ module Familia
82
82
  end
83
83
 
84
84
  require_relative 'familia/base'
85
- require_relative 'familia/features/autoloadable'
86
85
  require_relative 'familia/features'
87
86
  require_relative 'familia/data_type'
88
87
  require_relative 'familia/horreum'
@@ -30,16 +30,16 @@ File.write(@excluded_file, <<~RUBY)
30
30
  $autoloader_file_loaded = true
31
31
  RUBY
32
32
 
33
- ## Test that Familia::Autoloader exists and is a module
34
- Familia::Autoloader.is_a?(Module)
33
+ ## Test that Familia::Features::Autoloader exists and is a module
34
+ Familia::Features::Autoloader.is_a?(Module)
35
35
  #=> true
36
36
 
37
37
  ## Test that autoload_files class method exists
38
- Familia::Autoloader.respond_to?(:autoload_files)
38
+ Familia::Features::Autoloader.respond_to?(:autoload_files)
39
39
  #=> true
40
40
 
41
41
  ## Test that included class method exists
42
- Familia::Autoloader.respond_to?(:included)
42
+ Familia::Features::Autoloader.respond_to?(:included)
43
43
  #=> true
44
44
 
45
45
  ## Test autoload_files with single pattern
@@ -47,7 +47,7 @@ $test_feature1_loaded = false
47
47
  $test_feature2_loaded = false
48
48
  $autoloader_file_loaded = false
49
49
 
50
- Familia::Autoloader.autoload_files(File.join(@features_dir, '*.rb'))
50
+ Familia::Features::Autoloader.autoload_files(File.join(@features_dir, '*.rb'))
51
51
  $test_feature1_loaded && $test_feature2_loaded
52
52
  #=> true
53
53
 
@@ -64,7 +64,7 @@ File.write(@exclude_file, '$exclude_me_loaded = true')
64
64
  $include_me_loaded = false
65
65
  $exclude_me_loaded = false
66
66
 
67
- Familia::Autoloader.autoload_files(
67
+ Familia::Features::Autoloader.autoload_files(
68
68
  File.join(@exclude_features_dir, '*.rb'),
69
69
  exclude: ['autoloader.rb']
70
70
  )
@@ -88,7 +88,7 @@ File.write(@pattern_file2, '$pattern2_loaded = true')
88
88
  $pattern1_loaded = false
89
89
  $pattern2_loaded = false
90
90
 
91
- Familia::Autoloader.autoload_files([
91
+ Familia::Features::Autoloader.autoload_files([
92
92
  File.join(@pattern_dir1, '*.rb'),
93
93
  File.join(@pattern_dir2, '*.rb')
94
94
  ])
@@ -99,11 +99,11 @@ $pattern1_loaded && $pattern2_loaded
99
99
  ## Test that included method loads features from features directory
100
100
  # Create a mock module that includes Autoloader
101
101
  @mock_features_module = Module.new do
102
- include Familia::Autoloader
102
+ include Familia::Features::Autoloader
103
103
  end
104
104
 
105
105
  # The Features module already includes Autoloader, so test indirectly
106
- Familia::Features.ancestors.include?(Familia::Autoloader)
106
+ Familia::Features.ancestors.include?(Familia::Features::Autoloader)
107
107
  #=> true
108
108
 
109
109
  # Cleanup test files and directories
@@ -1,7 +1,7 @@
1
1
  require_relative '../helpers/test_helpers'
2
2
 
3
3
  module RefinedContext
4
- using Familia::Refinements::TimeUtils
4
+ using Familia::Refinements::TimeLiterals
5
5
 
6
6
  # This helper evaluates code within the refined context using eval.
7
7
  # This works because eval executes the code as if it were written