familia 2.0.0.pre19 → 2.0.0.pre22
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/.github/workflows/claude-code-review.yml +4 -9
- data/.github/workflows/code-smells.yml +64 -3
- data/.pre-commit-config.yaml +8 -6
- data/.reek.yml +10 -9
- data/.rubocop.yml +4 -0
- data/.talismanrc +5 -1
- data/CHANGELOG.rst +220 -112
- data/CLAUDE.md +28 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +20 -17
- data/bin/try +16 -0
- data/bin/tryouts +16 -0
- data/docs/1106-participates_in-bidirectional-solution.md +129 -0
- data/docs/guides/encryption.md +486 -0
- data/docs/guides/feature-encrypted-fields.md +123 -7
- data/docs/guides/feature-expiration.md +161 -117
- data/docs/guides/feature-external-identifiers.md +415 -443
- data/docs/guides/feature-object-identifiers.md +400 -269
- data/docs/guides/feature-quantization.md +120 -6
- data/docs/guides/feature-relationships-indexing.md +318 -0
- data/docs/guides/feature-relationships-methods.md +146 -604
- data/docs/guides/feature-relationships-participation.md +263 -0
- data/docs/guides/feature-relationships.md +118 -136
- data/docs/guides/feature-system-devs.md +176 -693
- data/docs/guides/feature-system.md +119 -6
- data/docs/guides/feature-transient-fields.md +81 -0
- data/docs/guides/field-system.md +778 -0
- data/docs/guides/index.md +32 -15
- data/docs/guides/logging.md +187 -0
- data/docs/guides/optimized-loading.md +674 -0
- data/docs/guides/thread-safety-monitoring.md +61 -0
- data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
- data/docs/migrating/v2.0.0-pre22.md +241 -0
- data/docs/overview.md +7 -9
- data/docs/reference/api-technical.md +267 -320
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
- data/examples/autoloader/mega_customer.rb +2 -0
- data/examples/datatype_standalone.rb +4 -3
- data/examples/encrypted_fields.rb +2 -1
- data/examples/json_usage_patterns.rb +2 -0
- data/examples/relationships.rb +3 -0
- data/examples/safe_dump.rb +2 -1
- data/examples/sampling_demo.rb +53 -0
- data/examples/single_connection_transaction_confusions.rb +2 -1
- data/familia.gemspec +2 -1
- data/lib/familia/base.rb +2 -0
- data/lib/familia/connection/behavior.rb +2 -0
- data/lib/familia/connection/handlers.rb +2 -0
- data/lib/familia/connection/individual_command_proxy.rb +2 -0
- data/lib/familia/connection/middleware.rb +34 -24
- data/lib/familia/connection/operation_core.rb +3 -2
- data/lib/familia/connection/operations.rb +2 -0
- data/lib/familia/connection/pipelined_core.rb +3 -3
- data/lib/familia/connection/transaction_core.rb +69 -2
- data/lib/familia/connection.rb +18 -3
- data/lib/familia/data_type/class_methods.rb +3 -1
- data/lib/familia/data_type/connection.rb +2 -0
- data/lib/familia/data_type/database_commands.rb +2 -0
- data/lib/familia/data_type/serialization.rb +79 -52
- data/lib/familia/data_type/settings.rb +2 -0
- data/lib/familia/data_type/types/counter.rb +2 -0
- data/lib/familia/data_type/types/hashkey.rb +7 -5
- data/lib/familia/data_type/types/listkey.rb +2 -0
- data/lib/familia/data_type/types/lock.rb +2 -0
- data/lib/familia/data_type/types/sorted_set.rb +7 -10
- data/lib/familia/data_type/types/stringkey.rb +24 -0
- data/lib/familia/data_type/types/unsorted_set.rb +2 -0
- data/lib/familia/data_type.rb +2 -0
- data/lib/familia/encryption/encrypted_data.rb +4 -2
- data/lib/familia/encryption/manager.rb +2 -0
- data/lib/familia/encryption/provider.rb +2 -0
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/registry.rb +2 -0
- data/lib/familia/encryption/request_cache.rb +2 -0
- data/lib/familia/encryption.rb +9 -2
- data/lib/familia/errors.rb +2 -0
- data/lib/familia/features/autoloader.rb +2 -0
- data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
- data/lib/familia/features/encrypted_fields.rb +2 -2
- data/lib/familia/features/expiration/extensions.rb +3 -1
- data/lib/familia/features/expiration.rb +12 -4
- data/lib/familia/features/external_identifier.rb +62 -7
- data/lib/familia/features/object_identifier.rb +49 -0
- data/lib/familia/features/quantization.rb +3 -1
- data/lib/familia/features/relationships/README.md +3 -1
- data/lib/familia/features/relationships/collection_operations.rb +2 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +138 -9
- data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +97 -21
- data/lib/familia/features/relationships/indexing.rb +3 -0
- data/lib/familia/features/relationships/indexing_relationship.rb +3 -1
- data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
- data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
- data/lib/familia/features/relationships/participation.rb +155 -69
- data/lib/familia/features/relationships/participation_membership.rb +69 -0
- data/lib/familia/features/relationships/participation_relationship.rb +34 -6
- data/lib/familia/features/relationships/score_encoding.rb +2 -0
- data/lib/familia/features/relationships.rb +5 -3
- data/lib/familia/features/safe_dump.rb +2 -0
- data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
- data/lib/familia/features/transient_fields.rb +2 -0
- data/lib/familia/features.rb +2 -0
- data/lib/familia/field_type.rb +3 -1
- data/lib/familia/horreum/connection.rb +17 -1
- data/lib/familia/horreum/database_commands.rb +8 -1
- data/lib/familia/horreum/definition.rb +16 -6
- data/lib/familia/horreum/management.rb +353 -52
- data/lib/familia/horreum/persistence.rb +179 -108
- data/lib/familia/horreum/related_fields.rb +2 -0
- data/lib/familia/horreum/serialization.rb +23 -4
- data/lib/familia/horreum/settings.rb +2 -0
- data/lib/familia/horreum/utils.rb +2 -0
- data/lib/familia/horreum.rb +15 -1
- data/lib/familia/identifier_extractor.rb +3 -1
- data/lib/familia/instrumentation.rb +156 -0
- data/lib/familia/json_serializer.rb +2 -0
- data/lib/familia/logging.rb +92 -32
- data/lib/familia/refinements/dear_json.rb +2 -0
- data/lib/familia/refinements/stylize_words.rb +2 -14
- data/lib/familia/refinements/time_literals.rb +2 -0
- data/lib/familia/refinements.rb +2 -0
- data/lib/familia/secure_identifier.rb +10 -2
- data/lib/familia/settings.rb +2 -0
- data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
- data/lib/familia/thread_safety/monitor.rb +328 -0
- data/lib/familia/utils.rb +13 -0
- data/lib/familia/verifiable_identifier.rb +3 -1
- data/lib/familia/version.rb +3 -1
- data/lib/familia.rb +31 -4
- data/lib/middleware/database_command_counter.rb +152 -0
- data/lib/middleware/database_logger.rb +295 -170
- data/lib/multi_result.rb +61 -31
- data/try/edge_cases/empty_identifiers_try.rb +2 -0
- data/try/edge_cases/hash_symbolization_try.rb +2 -0
- data/try/edge_cases/json_serialization_try.rb +2 -0
- data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
- data/try/edge_cases/race_conditions_try.rb +4 -0
- data/try/edge_cases/reserved_keywords_try.rb +4 -0
- data/try/edge_cases/string_coercion_try.rb +2 -0
- data/try/edge_cases/ttl_side_effects_try.rb +4 -0
- data/try/features/count_any_edge_cases_try.rb +486 -0
- data/try/features/count_any_methods_try.rb +197 -0
- data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
- data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
- data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
- data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
- data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
- data/try/features/encrypted_fields/memory_security_try.rb +4 -0
- data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
- data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
- data/try/features/encryption/config_persistence_try.rb +4 -0
- data/try/features/encryption/core_try.rb +4 -0
- data/try/features/encryption/instance_variable_scope_try.rb +4 -0
- data/try/features/encryption/module_loading_try.rb +4 -0
- data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
- data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
- data/try/features/encryption/roundtrip_validation_try.rb +4 -0
- data/try/features/encryption/secure_memory_handling_try.rb +4 -0
- data/try/features/expiration/expiration_try.rb +4 -0
- data/try/features/external_identifier/external_identifier_try.rb +305 -8
- data/try/features/feature_dependencies_try.rb +2 -0
- data/try/features/feature_improvements_try.rb +2 -0
- data/try/features/field_groups_try.rb +2 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
- data/try/features/object_identifier/object_identifier_try.rb +140 -0
- data/try/features/quantization/quantization_try.rb +4 -0
- data/try/features/real_feature_integration_try.rb +2 -0
- data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
- data/try/features/relationships/indexing_rebuild_try.rb +606 -0
- data/try/features/relationships/indexing_try.rb +2 -0
- data/try/features/relationships/participation_bidirectional_try.rb +242 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
- data/try/features/relationships/participation_commands_verification_try.rb +2 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
- data/try/features/relationships/participation_reverse_index_try.rb +15 -13
- data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
- data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
- data/try/features/relationships/relationships_api_changes_try.rb +2 -0
- data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
- data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
- data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
- data/try/features/relationships/relationships_performance_try.rb +4 -0
- data/try/features/relationships/relationships_performance_working_try.rb +4 -0
- data/try/features/relationships/relationships_try.rb +6 -4
- data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
- data/try/features/safe_dump/safe_dump_try.rb +4 -0
- data/try/features/transient_fields/redacted_string_try.rb +2 -0
- data/try/features/transient_fields/refresh_reset_try.rb +3 -0
- data/try/features/transient_fields/simple_refresh_test.rb +3 -0
- data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
- data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
- data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
- data/try/integration/connection/fiber_context_preservation_try.rb +4 -0
- data/try/integration/connection/handler_constraints_try.rb +4 -0
- data/try/integration/connection/isolated_dbclient_try.rb +4 -0
- data/try/integration/connection/middleware_reconnect_try.rb +2 -0
- data/try/integration/connection/operation_mode_guards_try.rb +4 -0
- data/try/integration/connection/pipeline_fallback_integration_try.rb +3 -0
- data/try/integration/connection/pools_try.rb +4 -0
- data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
- data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
- data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
- data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
- data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
- data/try/integration/connection/transaction_modes_try.rb +4 -0
- data/try/integration/conventional_inheritance_try.rb +4 -0
- data/try/integration/create_method_try.rb +4 -0
- data/try/integration/cross_component_try.rb +4 -0
- data/try/integration/data_types/datatype_pipelines_try.rb +9 -3
- data/try/integration/data_types/datatype_transactions_try.rb +17 -7
- data/try/integration/database_consistency_try.rb +4 -0
- data/try/integration/familia_extended_try.rb +4 -0
- data/try/integration/familia_members_methods_try.rb +4 -0
- data/try/integration/models/customer_safe_dump_try.rb +4 -0
- data/try/integration/models/customer_try.rb +7 -3
- data/try/integration/models/datatype_base_try.rb +4 -0
- data/try/integration/models/familia_object_try.rb +4 -0
- data/try/integration/persistence_operations_try.rb +4 -0
- data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
- data/try/integration/save_methods_consistency_try.rb +241 -0
- data/try/integration/scenarios_try.rb +4 -0
- data/try/integration/secure_identifier_try.rb +4 -0
- data/try/integration/transaction_safety_core_try.rb +176 -0
- data/try/integration/transaction_safety_workflow_try.rb +291 -0
- data/try/integration/verifiable_identifier_try.rb +4 -0
- data/try/investigation/pipeline_routing/README.md +228 -0
- data/try/performance/benchmarks_try.rb +4 -0
- data/try/performance/transaction_safety_benchmark_try.rb +238 -0
- data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
- data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
- data/try/support/debugging/cache_behavior_tracer.rb +4 -0
- data/try/support/debugging/debug_aad_process.rb +3 -0
- data/try/support/debugging/debug_concealed_internal.rb +3 -0
- data/try/support/debugging/debug_concealed_reveal.rb +3 -0
- data/try/support/debugging/debug_context_aad.rb +3 -0
- data/try/support/debugging/debug_context_simple.rb +3 -0
- data/try/support/debugging/debug_cross_context.rb +3 -0
- data/try/support/debugging/debug_database_load.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
- data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
- data/try/support/debugging/debug_field_decrypt.rb +3 -0
- data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
- data/try/support/debugging/debug_load_path.rb +3 -0
- data/try/support/debugging/debug_method_definition.rb +3 -0
- data/try/support/debugging/debug_method_resolution.rb +3 -0
- data/try/support/debugging/debug_minimal.rb +3 -0
- data/try/support/debugging/debug_provider.rb +3 -0
- data/try/support/debugging/debug_secure_behavior.rb +3 -0
- data/try/support/debugging/debug_string_class.rb +3 -0
- data/try/support/debugging/debug_test.rb +3 -0
- data/try/support/debugging/debug_test_design.rb +3 -0
- data/try/support/debugging/encryption_method_tracer.rb +4 -0
- data/try/support/debugging/provider_diagnostics.rb +4 -0
- data/try/support/helpers/test_cleanup.rb +4 -0
- data/try/support/helpers/test_helpers.rb +5 -0
- data/try/support/memory/memory_basic_test.rb +4 -0
- data/try/support/memory/memory_detailed_test.rb +4 -0
- data/try/support/memory/memory_search_for_string.rb +4 -0
- data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
- data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
- data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
- data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
- data/try/support/prototypes/atomic_saves_v4.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
- data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
- data/try/support/prototypes/pooling/pool_siege.rb +4 -2
- data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
- data/try/thread_safety/README.md +496 -0
- data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
- data/try/thread_safety/connection_chain_race_try.rb +148 -0
- data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
- data/try/thread_safety/feature_registry_race_try.rb +226 -0
- data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
- data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
- data/try/thread_safety/field_registration_race_try.rb +222 -0
- data/try/thread_safety/logger_initialization_race_try.rb +170 -0
- data/try/thread_safety/middleware_registration_race_try.rb +154 -0
- data/try/thread_safety/module_config_race_try.rb +175 -0
- data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
- data/try/unit/core/autoloader_try.rb +4 -0
- data/try/unit/core/base_enhancements_try.rb +4 -0
- data/try/unit/core/connection_try.rb +4 -0
- data/try/unit/core/errors_try.rb +4 -0
- data/try/unit/core/extensions_try.rb +4 -0
- data/try/unit/core/familia_logger_try.rb +2 -0
- data/try/unit/core/familia_try.rb +4 -0
- data/try/unit/core/middleware_sampling_try.rb +335 -0
- data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
- data/try/unit/core/middleware_thread_safety_try.rb +245 -0
- data/try/unit/core/middleware_try.rb +4 -0
- data/try/unit/core/settings_try.rb +4 -0
- data/try/unit/core/time_utils_try.rb +4 -0
- data/try/unit/core/tools_try.rb +4 -0
- data/try/unit/core/utils_try.rb +37 -0
- data/try/unit/data_types/boolean_try.rb +39 -22
- data/try/unit/data_types/counter_try.rb +4 -0
- data/try/unit/data_types/datatype_base_try.rb +4 -0
- data/try/unit/data_types/hash_try.rb +6 -2
- data/try/unit/data_types/list_try.rb +4 -0
- data/try/unit/data_types/lock_try.rb +4 -0
- data/try/unit/data_types/serialization_try.rb +386 -0
- data/try/unit/data_types/sorted_set_try.rb +4 -0
- data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
- data/try/unit/data_types/string_try.rb +4 -0
- data/try/unit/data_types/unsortedset_try.rb +4 -0
- data/try/unit/familia_resolve_class_try.rb +116 -0
- data/try/unit/horreum/auto_indexing_on_save_try.rb +5 -1
- data/try/unit/horreum/automatic_index_validation_try.rb +2 -0
- data/try/unit/horreum/base_try.rb +4 -0
- data/try/unit/horreum/class_methods_try.rb +4 -0
- data/try/unit/horreum/commands_try.rb +4 -0
- data/try/unit/horreum/defensive_initialization_try.rb +4 -0
- data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +6 -1
- data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
- data/try/unit/horreum/field_categories_try.rb +4 -0
- data/try/unit/horreum/field_definition_try.rb +4 -0
- data/try/unit/horreum/initialization_try.rb +4 -0
- data/try/unit/horreum/json_type_preservation_try.rb +2 -0
- data/try/unit/horreum/optimized_loading_try.rb +156 -0
- data/try/unit/horreum/relations_try.rb +4 -0
- data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
- data/try/unit/horreum/serialization_try.rb +4 -0
- data/try/unit/horreum/settings_try.rb +4 -0
- data/try/unit/horreum/unique_index_edge_cases_try.rb +4 -0
- data/try/unit/horreum/unique_index_guard_validation_try.rb +2 -0
- data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
- data/try/unit/middleware/database_logger_methods_try.rb +251 -0
- data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
- data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
- data/try/unit/thread_safety_monitor_try.rb +149 -0
- metadata +69 -17
- data/.github/workflows/code-quality.yml +0 -138
- data/changelog.d/20251011_012003_delano_159_datatype_transaction_pipeline_support.rst +0 -91
- data/changelog.d/20251011_203905_delano_next.rst +0 -30
- data/changelog.d/20251011_212633_delano_next.rst +0 -13
- data/changelog.d/20251011_221253_delano_next.rst +0 -26
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
- data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
- data/docs/archive/FAMILIA_UPDATE.md +0 -226
- data/docs/archive/README.md +0 -64
- data/docs/archive/api-reference.md +0 -333
- data/docs/guides/core-field-system.md +0 -806
- data/docs/guides/implementation.md +0 -276
- data/docs/guides/security-model.md +0 -183
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# try/features/external_identifier/external_identifier_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
2
4
|
|
|
3
5
|
require_relative '../../support/helpers/test_helpers'
|
|
4
6
|
|
|
@@ -15,10 +17,28 @@ class ExternalIdTest < Familia::Horreum
|
|
|
15
17
|
field :name
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
# Class with custom prefix
|
|
20
|
+
# Class with custom format using different prefix
|
|
19
21
|
class CustomPrefixTest < Familia::Horreum
|
|
20
22
|
feature :object_identifier
|
|
21
|
-
feature :external_identifier,
|
|
23
|
+
feature :external_identifier, format: 'cust_%{id}'
|
|
24
|
+
identifier_field :id
|
|
25
|
+
field :id
|
|
26
|
+
field :name
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Class with custom format template using hyphen separator
|
|
30
|
+
class CustomFormatTest < Familia::Horreum
|
|
31
|
+
feature :object_identifier
|
|
32
|
+
feature :external_identifier, format: 'ext-%{id}'
|
|
33
|
+
identifier_field :id
|
|
34
|
+
field :id
|
|
35
|
+
field :name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Class with format template without traditional prefix
|
|
39
|
+
class NoPrefixFormatTest < Familia::Horreum
|
|
40
|
+
feature :object_identifier
|
|
41
|
+
feature :external_identifier, format: 'api/%{id}'
|
|
22
42
|
identifier_field :id
|
|
23
43
|
field :id
|
|
24
44
|
field :name
|
|
@@ -77,6 +97,28 @@ custom_obj = CustomPrefixTest.new
|
|
|
77
97
|
custom_obj.extid.start_with?('cust_')
|
|
78
98
|
#==> true
|
|
79
99
|
|
|
100
|
+
## Custom format with hyphen separator
|
|
101
|
+
format_obj = CustomFormatTest.new
|
|
102
|
+
format_obj.extid.start_with?('ext-')
|
|
103
|
+
#==> true
|
|
104
|
+
|
|
105
|
+
## Custom format uses hyphen not underscore
|
|
106
|
+
format_obj = CustomFormatTest.new
|
|
107
|
+
extid = format_obj.extid
|
|
108
|
+
extid.include?('-') && !extid.include?('_')
|
|
109
|
+
#==> true
|
|
110
|
+
|
|
111
|
+
## Format without prefix placeholder uses literal format
|
|
112
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
113
|
+
no_prefix_obj.extid.start_with?('api/')
|
|
114
|
+
#==> true
|
|
115
|
+
|
|
116
|
+
## Format without prefix does not include underscore
|
|
117
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
118
|
+
extid = no_prefix_obj.extid
|
|
119
|
+
!extid.include?('_') && !extid.include?('ext')
|
|
120
|
+
#==> true
|
|
121
|
+
|
|
80
122
|
## External ID is URL-safe base-36 format
|
|
81
123
|
obj = ExternalIdTest.new
|
|
82
124
|
extid = obj.extid
|
|
@@ -154,13 +196,21 @@ obj1.extid != obj2.extid
|
|
|
154
196
|
ExternalIdTest.field_types[:extid]
|
|
155
197
|
#=:> Familia::Features::ExternalIdentifier::ExternalIdentifierFieldType
|
|
156
198
|
|
|
157
|
-
## Feature options contain
|
|
158
|
-
ExternalIdTest.feature_options(:external_identifier)[:
|
|
159
|
-
#=> "
|
|
199
|
+
## Feature options contain default format
|
|
200
|
+
ExternalIdTest.feature_options(:external_identifier)[:format]
|
|
201
|
+
#=> "ext_%{id}"
|
|
202
|
+
|
|
203
|
+
## Custom prefix format options
|
|
204
|
+
CustomPrefixTest.feature_options(:external_identifier)[:format]
|
|
205
|
+
#=> "cust_%{id}"
|
|
160
206
|
|
|
161
|
-
## Custom
|
|
162
|
-
|
|
163
|
-
#=> "
|
|
207
|
+
## Custom format with hyphen options
|
|
208
|
+
CustomFormatTest.feature_options(:external_identifier)[:format]
|
|
209
|
+
#=> "ext-%{id}"
|
|
210
|
+
|
|
211
|
+
## No traditional prefix format options
|
|
212
|
+
NoPrefixFormatTest.feature_options(:external_identifier)[:format]
|
|
213
|
+
#=> "api/%{id}"
|
|
164
214
|
|
|
165
215
|
## External ID is shorter than UUID objid
|
|
166
216
|
obj = ExternalIdTest.new
|
|
@@ -224,3 +274,250 @@ destroy_test_obj.destroy!
|
|
|
224
274
|
# Verify mapping was cleaned up
|
|
225
275
|
ExternalIdTest.extid_lookup.key?(destroy_extid)
|
|
226
276
|
#=> false
|
|
277
|
+
|
|
278
|
+
# ========================================
|
|
279
|
+
# Comprehensive Format Option Test Coverage
|
|
280
|
+
# ========================================
|
|
281
|
+
|
|
282
|
+
## Format option: default format produces ext_ prefix
|
|
283
|
+
default_obj = ExternalIdTest.new
|
|
284
|
+
default_obj.extid.start_with?('ext_')
|
|
285
|
+
#==> true
|
|
286
|
+
|
|
287
|
+
## Format option: custom format with different prefix works
|
|
288
|
+
custom_prefix_obj = CustomPrefixTest.new
|
|
289
|
+
custom_prefix_obj.extid.start_with?('cust_')
|
|
290
|
+
#==> true
|
|
291
|
+
|
|
292
|
+
## Format option: custom format with hyphen separator works
|
|
293
|
+
hyphen_obj = CustomFormatTest.new
|
|
294
|
+
hyphen_obj.extid.start_with?('ext-')
|
|
295
|
+
#==> true
|
|
296
|
+
|
|
297
|
+
## Format option: hyphen format does not contain underscore
|
|
298
|
+
hyphen_obj = CustomFormatTest.new
|
|
299
|
+
!hyphen_obj.extid.include?('_')
|
|
300
|
+
#==> true
|
|
301
|
+
|
|
302
|
+
## Format option: format without prefix works
|
|
303
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
304
|
+
no_prefix_obj.extid.start_with?('api/')
|
|
305
|
+
#==> true
|
|
306
|
+
|
|
307
|
+
## Format option: no prefix format uses slash separator
|
|
308
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
309
|
+
no_prefix_obj.extid.include?('/')
|
|
310
|
+
#==> true
|
|
311
|
+
|
|
312
|
+
## Format option: %{id} placeholder is properly interpolated
|
|
313
|
+
obj = ExternalIdTest.new
|
|
314
|
+
# The extid should not contain the literal string '%{id}'
|
|
315
|
+
!obj.extid.include?('%{id}')
|
|
316
|
+
#==> true
|
|
317
|
+
|
|
318
|
+
## Format option: generated ID part is base36 alphanumeric
|
|
319
|
+
obj = ExternalIdTest.new
|
|
320
|
+
extid = obj.extid
|
|
321
|
+
id_part = extid.gsub(/^ext_/, '')
|
|
322
|
+
id_part.match?(/\A[0-9a-z]+\z/)
|
|
323
|
+
#==> true
|
|
324
|
+
|
|
325
|
+
## Format option: hyphen format ID part is base36 alphanumeric
|
|
326
|
+
hyphen_obj = CustomFormatTest.new
|
|
327
|
+
extid = hyphen_obj.extid
|
|
328
|
+
id_part = extid.gsub(/^ext-/, '')
|
|
329
|
+
id_part.match?(/\A[0-9a-z]+\z/)
|
|
330
|
+
#==> true
|
|
331
|
+
|
|
332
|
+
## Format option: no prefix format ID part is base36 alphanumeric
|
|
333
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
334
|
+
extid = no_prefix_obj.extid
|
|
335
|
+
id_part = extid.gsub(/^api\//, '')
|
|
336
|
+
id_part.match?(/\A[0-9a-z]+\z/)
|
|
337
|
+
#==> true
|
|
338
|
+
|
|
339
|
+
## Format option: different formats produce different prefixes but same ID length
|
|
340
|
+
default_obj = ExternalIdTest.new
|
|
341
|
+
custom_obj = CustomPrefixTest.new
|
|
342
|
+
hyphen_obj = CustomFormatTest.new
|
|
343
|
+
# All should have similar length IDs (within a few characters due to prefix differences)
|
|
344
|
+
default_id_len = default_obj.extid.length
|
|
345
|
+
custom_id_len = custom_obj.extid.length
|
|
346
|
+
hyphen_id_len = hyphen_obj.extid.length
|
|
347
|
+
(default_id_len - custom_id_len).abs <= 5 && (default_id_len - hyphen_id_len).abs <= 5
|
|
348
|
+
#==> true
|
|
349
|
+
|
|
350
|
+
## Format option: custom formats maintain determinism
|
|
351
|
+
obj = CustomPrefixTest.new
|
|
352
|
+
first_extid = obj.extid
|
|
353
|
+
second_extid = obj.extid
|
|
354
|
+
first_extid == second_extid
|
|
355
|
+
#==> true
|
|
356
|
+
|
|
357
|
+
## Format option: formats work correctly with save/load cycle
|
|
358
|
+
format_save_obj = CustomFormatTest.new(id: 'format_save_test', name: 'Format Save Test')
|
|
359
|
+
original_extid = format_save_obj.extid
|
|
360
|
+
format_save_obj.save
|
|
361
|
+
loaded_obj = CustomFormatTest.new(id: 'format_save_test')
|
|
362
|
+
loaded_obj.extid == original_extid
|
|
363
|
+
#==> true
|
|
364
|
+
|
|
365
|
+
## Format option: find_by_extid works with custom formats
|
|
366
|
+
findable_custom = CustomPrefixTest.new(id: 'findable_custom', name: 'Findable Custom')
|
|
367
|
+
findable_custom.save
|
|
368
|
+
found_custom = CustomPrefixTest.find_by_extid(findable_custom.extid)
|
|
369
|
+
found_custom&.id
|
|
370
|
+
#=> "findable_custom"
|
|
371
|
+
|
|
372
|
+
## Format option: find_by_extid works with hyphen format
|
|
373
|
+
findable_hyphen = CustomFormatTest.new(id: 'findable_hyphen', name: 'Findable Hyphen')
|
|
374
|
+
findable_hyphen.save
|
|
375
|
+
found_hyphen = CustomFormatTest.find_by_extid(findable_hyphen.extid)
|
|
376
|
+
found_hyphen&.id
|
|
377
|
+
#=> "findable_hyphen"
|
|
378
|
+
|
|
379
|
+
## Format option: find_by_extid works with no-prefix format
|
|
380
|
+
findable_no_prefix = NoPrefixFormatTest.new(id: 'findable_no_prefix', name: 'Findable No Prefix')
|
|
381
|
+
findable_no_prefix.save
|
|
382
|
+
found_no_prefix = NoPrefixFormatTest.find_by_extid(findable_no_prefix.extid)
|
|
383
|
+
found_no_prefix&.id
|
|
384
|
+
#=> "findable_no_prefix"
|
|
385
|
+
|
|
386
|
+
# Cleanup format test objects
|
|
387
|
+
findable_custom.destroy! rescue nil
|
|
388
|
+
findable_hyphen.destroy! rescue nil
|
|
389
|
+
findable_no_prefix.destroy! rescue nil
|
|
390
|
+
|
|
391
|
+
# ========================================
|
|
392
|
+
# extid? Method Test Coverage
|
|
393
|
+
# ========================================
|
|
394
|
+
|
|
395
|
+
## extid? returns false for nil
|
|
396
|
+
ExternalIdTest.extid?(nil)
|
|
397
|
+
#=> false
|
|
398
|
+
|
|
399
|
+
## extid? returns false for empty string
|
|
400
|
+
ExternalIdTest.extid?('')
|
|
401
|
+
#=> false
|
|
402
|
+
|
|
403
|
+
## extid? returns false for whitespace-only string
|
|
404
|
+
ExternalIdTest.extid?(' ')
|
|
405
|
+
#=> false
|
|
406
|
+
|
|
407
|
+
## extid? returns true for valid extid with default format
|
|
408
|
+
# Valid format: ext_ prefix + exactly 25 alphanumeric characters
|
|
409
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghijklmno')
|
|
410
|
+
#=> true
|
|
411
|
+
|
|
412
|
+
## extid? returns true for valid extid with uppercase characters
|
|
413
|
+
# The pattern allows [0-9a-zA-Z] for the ID part
|
|
414
|
+
ExternalIdTest.extid?('ext_0123456789ABCDEFGHIJKLMNO')
|
|
415
|
+
#=> true
|
|
416
|
+
|
|
417
|
+
## extid? returns true for valid extid with mixed case
|
|
418
|
+
ExternalIdTest.extid?('ext_0123456789AbCdEfGhIjKlMnO')
|
|
419
|
+
#=> true
|
|
420
|
+
|
|
421
|
+
## extid? returns true for generated extid
|
|
422
|
+
obj = ExternalIdTest.new
|
|
423
|
+
ExternalIdTest.extid?(obj.extid)
|
|
424
|
+
#=> true
|
|
425
|
+
|
|
426
|
+
## extid? returns false for wrong prefix
|
|
427
|
+
ExternalIdTest.extid?('xxx_0123456789abcdefghijklmno')
|
|
428
|
+
#=> false
|
|
429
|
+
|
|
430
|
+
## extid? returns false for missing prefix
|
|
431
|
+
ExternalIdTest.extid?('0123456789abcdefghijklmno')
|
|
432
|
+
#=> false
|
|
433
|
+
|
|
434
|
+
## extid? accepts ID part with 24 chars (within 20-32 range)
|
|
435
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghijklmn')
|
|
436
|
+
#=> true
|
|
437
|
+
|
|
438
|
+
## extid? accepts ID part with 26 chars (within 20-32 range)
|
|
439
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghijklmnop')
|
|
440
|
+
#=> true
|
|
441
|
+
|
|
442
|
+
## extid? returns false for ID part too short (19 chars, below minimum)
|
|
443
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghi')
|
|
444
|
+
#=> false
|
|
445
|
+
|
|
446
|
+
## extid? returns false for ID part too long (33 chars, above maximum)
|
|
447
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghijklmnopqrstuvw')
|
|
448
|
+
#=> false
|
|
449
|
+
|
|
450
|
+
## extid? returns false for invalid characters in ID (underscore)
|
|
451
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghij_lmno')
|
|
452
|
+
#=> false
|
|
453
|
+
|
|
454
|
+
## extid? returns false for invalid characters in ID (hyphen)
|
|
455
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghij-lmno')
|
|
456
|
+
#=> false
|
|
457
|
+
|
|
458
|
+
## extid? returns false for invalid characters in ID (special chars)
|
|
459
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghij!@#$%')
|
|
460
|
+
#=> false
|
|
461
|
+
|
|
462
|
+
## extid? with custom prefix format returns true for valid extid
|
|
463
|
+
CustomPrefixTest.extid?('cust_0123456789abcdefghijklmno')
|
|
464
|
+
#=> true
|
|
465
|
+
|
|
466
|
+
## extid? with custom prefix format returns false for default prefix
|
|
467
|
+
CustomPrefixTest.extid?('ext_0123456789abcdefghijklmno')
|
|
468
|
+
#=> false
|
|
469
|
+
|
|
470
|
+
## extid? with custom prefix format returns true for generated extid
|
|
471
|
+
custom_obj = CustomPrefixTest.new
|
|
472
|
+
CustomPrefixTest.extid?(custom_obj.extid)
|
|
473
|
+
#=> true
|
|
474
|
+
|
|
475
|
+
## extid? with hyphen format returns true for valid extid
|
|
476
|
+
CustomFormatTest.extid?('ext-0123456789abcdefghijklmno')
|
|
477
|
+
#=> true
|
|
478
|
+
|
|
479
|
+
## extid? with hyphen format returns false for underscore format
|
|
480
|
+
CustomFormatTest.extid?('ext_0123456789abcdefghijklmno')
|
|
481
|
+
#=> false
|
|
482
|
+
|
|
483
|
+
## extid? with hyphen format returns true for generated extid
|
|
484
|
+
hyphen_obj = CustomFormatTest.new
|
|
485
|
+
CustomFormatTest.extid?(hyphen_obj.extid)
|
|
486
|
+
#=> true
|
|
487
|
+
|
|
488
|
+
## extid? with no-prefix format returns true for valid extid
|
|
489
|
+
NoPrefixFormatTest.extid?('api/0123456789abcdefghijklmno')
|
|
490
|
+
#=> true
|
|
491
|
+
|
|
492
|
+
## extid? with no-prefix format returns false for default format
|
|
493
|
+
NoPrefixFormatTest.extid?('ext_0123456789abcdefghijklmno')
|
|
494
|
+
#=> false
|
|
495
|
+
|
|
496
|
+
## extid? with no-prefix format returns true for generated extid
|
|
497
|
+
no_prefix_obj = NoPrefixFormatTest.new
|
|
498
|
+
NoPrefixFormatTest.extid?(no_prefix_obj.extid)
|
|
499
|
+
#=> true
|
|
500
|
+
|
|
501
|
+
## extid? returns false for partial match at start
|
|
502
|
+
ExternalIdTest.extid?('ext_0123456789abcdefghijklmno_extra')
|
|
503
|
+
#=> false
|
|
504
|
+
|
|
505
|
+
## extid? returns false for partial match with leading chars
|
|
506
|
+
ExternalIdTest.extid?('prefix_ext_0123456789abcdefghijklmno')
|
|
507
|
+
#=> false
|
|
508
|
+
|
|
509
|
+
## extid? returns false for spaces in ID
|
|
510
|
+
ExternalIdTest.extid?('ext_0123456789 bcdefghijklmno')
|
|
511
|
+
#=> false
|
|
512
|
+
|
|
513
|
+
## extid? returns false for just the prefix
|
|
514
|
+
ExternalIdTest.extid?('ext_')
|
|
515
|
+
#=> false
|
|
516
|
+
|
|
517
|
+
## extid? with Symbol input (symbols support =~ matching)
|
|
518
|
+
ExternalIdTest.extid?(:ext_0123456789abcdefghijklmno)
|
|
519
|
+
#=> true
|
|
520
|
+
|
|
521
|
+
## extid? with Symbol input returns false for invalid format
|
|
522
|
+
ExternalIdTest.extid?(:invalid_symbol)
|
|
523
|
+
#=> false
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# try/features/object_identifier/object_identifier_integration_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
2
4
|
|
|
3
5
|
require_relative '../../support/helpers/test_helpers'
|
|
4
6
|
|
|
@@ -19,7 +21,7 @@ end
|
|
|
19
21
|
# Class with custom configurations for both features
|
|
20
22
|
class ::CustomIntegrationTest < Familia::Horreum
|
|
21
23
|
feature :object_identifier, generator: :hex
|
|
22
|
-
feature :external_identifier,
|
|
24
|
+
feature :external_identifier, format: 'custom_%{id}'
|
|
23
25
|
identifier_field :id
|
|
24
26
|
field :id
|
|
25
27
|
field :name
|
|
@@ -96,8 +98,9 @@ original_extid = persistence_obj.extid
|
|
|
96
98
|
persistence_obj.save
|
|
97
99
|
|
|
98
100
|
# Load from Valkey/Redis
|
|
99
|
-
loaded_obj = PersistenceTest.load(
|
|
100
|
-
|
|
101
|
+
loaded_obj = PersistenceTest.load('persistence_test')
|
|
102
|
+
loaded_obj.objid == original_objid && loaded_obj.extid == original_extid
|
|
103
|
+
#==> true
|
|
101
104
|
|
|
102
105
|
## objid persists after save/load
|
|
103
106
|
persistence_obj = PersistenceTest.new
|
|
@@ -169,17 +172,17 @@ opts.key?(:external_identifier)
|
|
|
169
172
|
IntegrationTest.feature_options(:object_identifier)[:generator]
|
|
170
173
|
#=> :uuid_v7
|
|
171
174
|
|
|
172
|
-
##
|
|
173
|
-
IntegrationTest.feature_options(:external_identifier)[:
|
|
174
|
-
#=> "
|
|
175
|
+
## Format default configuration is applied correctly
|
|
176
|
+
IntegrationTest.feature_options(:external_identifier)[:format]
|
|
177
|
+
#=> "ext_%{id}"
|
|
175
178
|
|
|
176
179
|
## Custom generator configuration is applied correctly
|
|
177
180
|
CustomIntegrationTest.feature_options(:object_identifier)[:generator]
|
|
178
181
|
#=> :hex
|
|
179
182
|
|
|
180
|
-
## Custom
|
|
181
|
-
CustomIntegrationTest.feature_options(:external_identifier)[:
|
|
182
|
-
#=> "
|
|
183
|
+
## Custom format configuration is applied correctly
|
|
184
|
+
CustomIntegrationTest.feature_options(:external_identifier)[:format]
|
|
185
|
+
#=> "custom_%{id}"
|
|
183
186
|
|
|
184
187
|
## objid is URL-safe (UUID format)
|
|
185
188
|
obj = IntegrationTest.new
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# try/features/object_identifier/object_identifier_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
2
4
|
|
|
3
5
|
require_relative '../../support/helpers/test_helpers'
|
|
4
6
|
|
|
@@ -199,3 +201,141 @@ race_obj.save # Save so find_by_objid can locate
|
|
|
199
201
|
found = BasicObjectTest.find_by_objid(generated_objid)
|
|
200
202
|
found && found.id == "race_test_123"
|
|
201
203
|
#=> true
|
|
204
|
+
|
|
205
|
+
# ========================================
|
|
206
|
+
# objid? Method Test Coverage
|
|
207
|
+
# ========================================
|
|
208
|
+
|
|
209
|
+
## objid? returns false for nil
|
|
210
|
+
BasicObjectTest.objid?(nil)
|
|
211
|
+
#=> false
|
|
212
|
+
|
|
213
|
+
## objid? returns false for empty string
|
|
214
|
+
BasicObjectTest.objid?('')
|
|
215
|
+
#=> false
|
|
216
|
+
|
|
217
|
+
## objid? returns false for whitespace-only string
|
|
218
|
+
BasicObjectTest.objid?(' ')
|
|
219
|
+
#=> false
|
|
220
|
+
|
|
221
|
+
## objid? returns true for valid UUID v7 format
|
|
222
|
+
# UUID v7 format: xxxxxxxx-xxxx-7xxx-xxxx-xxxxxxxxxxxx (version char is '7')
|
|
223
|
+
BasicObjectTest.objid?('01234567-89ab-7def-89ab-0123456789ab')
|
|
224
|
+
#=> true
|
|
225
|
+
|
|
226
|
+
## objid? returns true for generated UUID v7 objid
|
|
227
|
+
obj = BasicObjectTest.new
|
|
228
|
+
BasicObjectTest.objid?(obj.objid)
|
|
229
|
+
#=> true
|
|
230
|
+
|
|
231
|
+
## objid? returns false for UUID v4 in UUID v7 class
|
|
232
|
+
# Version char is '4' instead of '7'
|
|
233
|
+
BasicObjectTest.objid?('01234567-89ab-4def-89ab-0123456789ab')
|
|
234
|
+
#=> false
|
|
235
|
+
|
|
236
|
+
## objid? returns false for wrong version char
|
|
237
|
+
BasicObjectTest.objid?('01234567-89ab-5def-89ab-0123456789ab')
|
|
238
|
+
#=> false
|
|
239
|
+
|
|
240
|
+
## objid? returns false for missing hyphens
|
|
241
|
+
BasicObjectTest.objid?('0123456789ab7def89ab0123456789ab')
|
|
242
|
+
#=> false
|
|
243
|
+
|
|
244
|
+
## objid? returns false for wrong length (too short)
|
|
245
|
+
BasicObjectTest.objid?('01234567-89ab-7def-89ab-012345678')
|
|
246
|
+
#=> false
|
|
247
|
+
|
|
248
|
+
## objid? returns false for wrong length (too long)
|
|
249
|
+
BasicObjectTest.objid?('01234567-89ab-7def-89ab-0123456789abcd')
|
|
250
|
+
#=> false
|
|
251
|
+
|
|
252
|
+
## objid? returns false for hyphens in wrong positions
|
|
253
|
+
BasicObjectTest.objid?('0123456-789ab-7def-89ab-0123456789ab')
|
|
254
|
+
#=> false
|
|
255
|
+
|
|
256
|
+
## objid? returns false for UUID with non-hex characters
|
|
257
|
+
# Validates that all characters are valid hexadecimal digits
|
|
258
|
+
BasicObjectTest.objid?('gggggggg-gggg-7ggg-gggg-gggggggggggg')
|
|
259
|
+
#=> false
|
|
260
|
+
|
|
261
|
+
## objid? with UUID v4 generator returns true for valid v4 format
|
|
262
|
+
UuidV4Test.objid?('01234567-89ab-4def-89ab-0123456789ab')
|
|
263
|
+
#=> true
|
|
264
|
+
|
|
265
|
+
## objid? with UUID v4 generator returns true for generated objid
|
|
266
|
+
v4_obj = UuidV4Test.new
|
|
267
|
+
UuidV4Test.objid?(v4_obj.objid)
|
|
268
|
+
#=> true
|
|
269
|
+
|
|
270
|
+
## objid? with UUID v4 generator returns false for v7 format
|
|
271
|
+
UuidV4Test.objid?('01234567-89ab-7def-89ab-0123456789ab')
|
|
272
|
+
#=> false
|
|
273
|
+
|
|
274
|
+
## objid? with hex generator returns true for valid hex string
|
|
275
|
+
HexTest.objid?('0123456789abcdef')
|
|
276
|
+
#=> true
|
|
277
|
+
|
|
278
|
+
## objid? with hex generator returns true for generated hex objid
|
|
279
|
+
hex_obj = HexTest.new
|
|
280
|
+
HexTest.objid?(hex_obj.objid)
|
|
281
|
+
#=> true
|
|
282
|
+
|
|
283
|
+
## objid? with hex generator returns true for uppercase hex
|
|
284
|
+
HexTest.objid?('0123456789ABCDEF')
|
|
285
|
+
#=> true
|
|
286
|
+
|
|
287
|
+
## objid? with hex generator returns true for mixed case hex
|
|
288
|
+
HexTest.objid?('0123456789AbCdEf')
|
|
289
|
+
#=> true
|
|
290
|
+
|
|
291
|
+
## objid? with hex generator returns false for non-hex chars
|
|
292
|
+
HexTest.objid?('0123456789ghijkl')
|
|
293
|
+
#=> false
|
|
294
|
+
|
|
295
|
+
## objid? with hex generator returns false for UUID format
|
|
296
|
+
HexTest.objid?('01234567-89ab-7def-89ab-0123456789ab')
|
|
297
|
+
#=> false
|
|
298
|
+
|
|
299
|
+
## objid? with hex generator returns true for short hex
|
|
300
|
+
HexTest.objid?('abc')
|
|
301
|
+
#=> true
|
|
302
|
+
|
|
303
|
+
## objid? with hex generator returns true for long hex
|
|
304
|
+
HexTest.objid?('0123456789abcdef0123456789abcdef')
|
|
305
|
+
#=> true
|
|
306
|
+
|
|
307
|
+
## objid? with custom proc generator returns false (unsupported)
|
|
308
|
+
CustomProcTest.objid?('custom_12345678')
|
|
309
|
+
#=> false
|
|
310
|
+
|
|
311
|
+
## objid? with custom proc generator returns false for any input
|
|
312
|
+
CustomProcTest.objid?('anything')
|
|
313
|
+
#=> false
|
|
314
|
+
|
|
315
|
+
## objid? UUID validation checks position 8 for hyphen
|
|
316
|
+
BasicObjectTest.objid?('01234567X89ab-7def-89ab-0123456789ab')
|
|
317
|
+
#=> false
|
|
318
|
+
|
|
319
|
+
## objid? UUID validation checks position 13 for hyphen
|
|
320
|
+
BasicObjectTest.objid?('01234567-89abX7def-89ab-0123456789ab')
|
|
321
|
+
#=> false
|
|
322
|
+
|
|
323
|
+
## objid? UUID validation checks position 18 for hyphen
|
|
324
|
+
BasicObjectTest.objid?('01234567-89ab-7defX89ab-0123456789ab')
|
|
325
|
+
#=> false
|
|
326
|
+
|
|
327
|
+
## objid? UUID validation checks position 23 for hyphen
|
|
328
|
+
BasicObjectTest.objid?('01234567-89ab-7def-89abX0123456789ab')
|
|
329
|
+
#=> false
|
|
330
|
+
|
|
331
|
+
## objid? returns false for partial UUID match
|
|
332
|
+
BasicObjectTest.objid?('01234567-89ab-7def')
|
|
333
|
+
#=> false
|
|
334
|
+
|
|
335
|
+
## objid? with Symbol input for UUID v7 (symbols support string comparison)
|
|
336
|
+
BasicObjectTest.objid?(:'01234567-89ab-7def-89ab-0123456789ab')
|
|
337
|
+
#=> true
|
|
338
|
+
|
|
339
|
+
## objid? with Symbol input returns false for invalid format
|
|
340
|
+
BasicObjectTest.objid?(:invalid_objid)
|
|
341
|
+
#=> false
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# try/features/relationships/indexing_commands_verification_try.rb
|
|
2
2
|
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
3
5
|
# Verification of proper Redis command generation for indexing operations
|
|
4
6
|
# This test ensures the indexing system uses proper DataType methods instead of direct Redis calls
|
|
5
7
|
#
|