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
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# try/unit/data_types/serialization_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# Test coverage for DataType serialization/deserialization behavior
|
|
6
|
+
# Issue #190: Unify DataType and Horreum serialization for type preservation
|
|
7
|
+
|
|
8
|
+
require_relative '../../support/helpers/test_helpers'
|
|
9
|
+
|
|
10
|
+
Familia.debug = false
|
|
11
|
+
|
|
12
|
+
# Create test instances
|
|
13
|
+
@bone = Bone.new('serialize_test_token')
|
|
14
|
+
|
|
15
|
+
# ========================================
|
|
16
|
+
# DataType Serialization Behavior (Issue #190)
|
|
17
|
+
# Now uses JSON serialization for type preservation
|
|
18
|
+
# ========================================
|
|
19
|
+
|
|
20
|
+
## HashKey stores string values correctly
|
|
21
|
+
@bone.props['string_field'] = 'hello'
|
|
22
|
+
@bone.props['string_field']
|
|
23
|
+
#=> 'hello'
|
|
24
|
+
|
|
25
|
+
## HashKey stores integer with type preservation
|
|
26
|
+
@bone.props['int_field'] = 42
|
|
27
|
+
@bone.props['int_field']
|
|
28
|
+
#=> 42
|
|
29
|
+
|
|
30
|
+
## HashKey stores float with type preservation
|
|
31
|
+
@bone.props['float_field'] = 3.14
|
|
32
|
+
@bone.props['float_field']
|
|
33
|
+
#=> 3.14
|
|
34
|
+
|
|
35
|
+
## HashKey stores symbol as string (symbols serialize to strings in JSON)
|
|
36
|
+
@bone.props['symbol_field'] = :active
|
|
37
|
+
@bone.props['symbol_field']
|
|
38
|
+
#=> 'active'
|
|
39
|
+
|
|
40
|
+
## HashKey stores boolean true with type preservation
|
|
41
|
+
@bone.props['bool_true'] = true
|
|
42
|
+
@bone.props['bool_true']
|
|
43
|
+
#=> true
|
|
44
|
+
|
|
45
|
+
## HashKey stores boolean true as TrueClass
|
|
46
|
+
@bone.props['bool_true'].class
|
|
47
|
+
#=> TrueClass
|
|
48
|
+
|
|
49
|
+
## HashKey stores boolean false with type preservation
|
|
50
|
+
@bone.props['bool_false'] = false
|
|
51
|
+
@bone.props['bool_false']
|
|
52
|
+
#=> false
|
|
53
|
+
|
|
54
|
+
## HashKey stores boolean false as FalseClass
|
|
55
|
+
@bone.props['bool_false'].class
|
|
56
|
+
#=> FalseClass
|
|
57
|
+
|
|
58
|
+
## HashKey stores nil with type preservation
|
|
59
|
+
@bone.props['nil_field'] = nil
|
|
60
|
+
@bone.props['nil_field']
|
|
61
|
+
#=> nil
|
|
62
|
+
|
|
63
|
+
## HashKey stores hash with type preservation
|
|
64
|
+
@bone.props['hash_field'] = { 'key' => 'value' }
|
|
65
|
+
@bone.props['hash_field']
|
|
66
|
+
#=> {'key'=>'value'}
|
|
67
|
+
|
|
68
|
+
## HashKey stores array with type preservation
|
|
69
|
+
@bone.props['array_field'] = [1, 2, 3]
|
|
70
|
+
@bone.props['array_field']
|
|
71
|
+
#=> [1, 2, 3]
|
|
72
|
+
|
|
73
|
+
# ========================================
|
|
74
|
+
# List Serialization Behavior
|
|
75
|
+
# ========================================
|
|
76
|
+
|
|
77
|
+
## List stores string values correctly
|
|
78
|
+
@bone.owners.delete!
|
|
79
|
+
@bone.owners.push('owner1')
|
|
80
|
+
@bone.owners.first
|
|
81
|
+
#=> 'owner1'
|
|
82
|
+
|
|
83
|
+
## List stores integer with type preservation
|
|
84
|
+
@bone.owners.delete!
|
|
85
|
+
@bone.owners.push(123)
|
|
86
|
+
@bone.owners.first
|
|
87
|
+
#=> 123
|
|
88
|
+
|
|
89
|
+
## List stores boolean with type preservation
|
|
90
|
+
@bone.owners.delete!
|
|
91
|
+
@bone.owners.push(true)
|
|
92
|
+
@bone.owners.first
|
|
93
|
+
#=> true
|
|
94
|
+
|
|
95
|
+
## List stores nil with type preservation
|
|
96
|
+
@bone.owners.delete!
|
|
97
|
+
@bone.owners.push(nil)
|
|
98
|
+
@bone.owners.first
|
|
99
|
+
#=> nil
|
|
100
|
+
|
|
101
|
+
# ========================================
|
|
102
|
+
# Set Serialization Behavior
|
|
103
|
+
# ========================================
|
|
104
|
+
|
|
105
|
+
## Set stores string values correctly
|
|
106
|
+
@bone.tags.delete!
|
|
107
|
+
@bone.tags.add('tag1')
|
|
108
|
+
@bone.tags.members.include?('tag1')
|
|
109
|
+
#=> true
|
|
110
|
+
|
|
111
|
+
## Set stores integer with type preservation
|
|
112
|
+
@bone.tags.delete!
|
|
113
|
+
@bone.tags.add(42)
|
|
114
|
+
@bone.tags.members.include?(42)
|
|
115
|
+
#=> true
|
|
116
|
+
|
|
117
|
+
## Set stores boolean with type preservation
|
|
118
|
+
@bone.tags.delete!
|
|
119
|
+
@bone.tags.add(true)
|
|
120
|
+
@bone.tags.members.include?(true)
|
|
121
|
+
#=> true
|
|
122
|
+
|
|
123
|
+
# ========================================
|
|
124
|
+
# SortedSet Serialization Behavior
|
|
125
|
+
# ========================================
|
|
126
|
+
|
|
127
|
+
## SortedSet stores string values correctly
|
|
128
|
+
@bone.metrics.delete!
|
|
129
|
+
@bone.metrics.add('metric1', 1.0)
|
|
130
|
+
@bone.metrics.members.include?('metric1')
|
|
131
|
+
#=> true
|
|
132
|
+
|
|
133
|
+
## SortedSet stores integer member with type preservation
|
|
134
|
+
@bone.metrics.delete!
|
|
135
|
+
@bone.metrics.add(999, 1.0)
|
|
136
|
+
@bone.metrics.members.include?(999)
|
|
137
|
+
#=> true
|
|
138
|
+
|
|
139
|
+
## SortedSet stores boolean member with type preservation
|
|
140
|
+
@bone.metrics.delete!
|
|
141
|
+
@bone.metrics.add(true, 1.0)
|
|
142
|
+
@bone.metrics.members.include?(true)
|
|
143
|
+
#=> true
|
|
144
|
+
|
|
145
|
+
# ========================================
|
|
146
|
+
# Horreum Field Serialization (for comparison)
|
|
147
|
+
# Uses JSON encoding - type preserved
|
|
148
|
+
# ========================================
|
|
149
|
+
|
|
150
|
+
## Horreum field stores string with JSON encoding
|
|
151
|
+
@customer = Customer.new
|
|
152
|
+
@customer.custid = 'serialization_test'
|
|
153
|
+
@customer.role = 'admin'
|
|
154
|
+
@customer.save
|
|
155
|
+
loaded = Customer.find_by_id('serialization_test')
|
|
156
|
+
loaded.role
|
|
157
|
+
#=> 'admin'
|
|
158
|
+
|
|
159
|
+
## Horreum field stores boolean true (JSON encoded)
|
|
160
|
+
@customer.verified = true
|
|
161
|
+
@customer.save
|
|
162
|
+
@loaded_customer = Customer.find_by_id('serialization_test')
|
|
163
|
+
@loaded_customer.verified
|
|
164
|
+
#=> true
|
|
165
|
+
|
|
166
|
+
## Horreum verified field is actually boolean, not string
|
|
167
|
+
@loaded_customer.verified.class
|
|
168
|
+
#=> TrueClass
|
|
169
|
+
|
|
170
|
+
## Horreum field stores boolean false (JSON encoded)
|
|
171
|
+
@customer.reset_requested = false
|
|
172
|
+
@customer.save
|
|
173
|
+
@loaded_customer2 = Customer.find_by_id('serialization_test')
|
|
174
|
+
@loaded_customer2.reset_requested
|
|
175
|
+
#=> false
|
|
176
|
+
|
|
177
|
+
## Horreum reset_requested field is actually boolean, not string
|
|
178
|
+
@loaded_customer2.reset_requested.class
|
|
179
|
+
#=> FalseClass
|
|
180
|
+
|
|
181
|
+
# ========================================
|
|
182
|
+
# Type Round-Trip Comparison (Unified Behavior)
|
|
183
|
+
# ========================================
|
|
184
|
+
|
|
185
|
+
## Integer round-trip in HashKey now preserves type (Issue #190)
|
|
186
|
+
@bone.props['roundtrip_int'] = 100
|
|
187
|
+
retrieved = @bone.props['roundtrip_int']
|
|
188
|
+
retrieved.class
|
|
189
|
+
#=> Integer
|
|
190
|
+
|
|
191
|
+
## Boolean round-trip in HashKey preserves type
|
|
192
|
+
@bone.props['roundtrip_bool'] = true
|
|
193
|
+
@bone.props['roundtrip_bool'].class
|
|
194
|
+
#=> TrueClass
|
|
195
|
+
|
|
196
|
+
## DataType and Horreum now use same JSON serialization
|
|
197
|
+
@session = Session.new
|
|
198
|
+
@session.sessid = 'roundtrip_test'
|
|
199
|
+
# Both DataType and Horreum fields now preserve types consistently
|
|
200
|
+
|
|
201
|
+
# ========================================
|
|
202
|
+
# Horreum serialize_value Comprehensive Tests
|
|
203
|
+
# (Issue #190: Document behavior for unification)
|
|
204
|
+
# ========================================
|
|
205
|
+
|
|
206
|
+
## Horreum serialize_value: string gets JSON encoded with quotes
|
|
207
|
+
@customer.serialize_value('hello')
|
|
208
|
+
#=> '"hello"'
|
|
209
|
+
|
|
210
|
+
## Horreum serialize_value: empty string gets JSON encoded
|
|
211
|
+
@customer.serialize_value('')
|
|
212
|
+
#=> '""'
|
|
213
|
+
|
|
214
|
+
## Horreum serialize_value: integer becomes JSON number (no quotes)
|
|
215
|
+
@customer.serialize_value(42)
|
|
216
|
+
#=> '42'
|
|
217
|
+
|
|
218
|
+
## Horreum serialize_value: zero becomes JSON number
|
|
219
|
+
@customer.serialize_value(0)
|
|
220
|
+
#=> '0'
|
|
221
|
+
|
|
222
|
+
## Horreum serialize_value: negative integer
|
|
223
|
+
@customer.serialize_value(-99)
|
|
224
|
+
#=> '-99'
|
|
225
|
+
|
|
226
|
+
## Horreum serialize_value: float becomes JSON number
|
|
227
|
+
@customer.serialize_value(3.14159)
|
|
228
|
+
#=> '3.14159'
|
|
229
|
+
|
|
230
|
+
## Horreum serialize_value: boolean true becomes JSON true
|
|
231
|
+
@customer.serialize_value(true)
|
|
232
|
+
#=> 'true'
|
|
233
|
+
|
|
234
|
+
## Horreum serialize_value: boolean false becomes JSON false
|
|
235
|
+
@customer.serialize_value(false)
|
|
236
|
+
#=> 'false'
|
|
237
|
+
|
|
238
|
+
## Horreum serialize_value: nil becomes JSON null
|
|
239
|
+
@customer.serialize_value(nil)
|
|
240
|
+
#=> 'null'
|
|
241
|
+
|
|
242
|
+
## Horreum serialize_value: symbol becomes JSON string
|
|
243
|
+
@customer.serialize_value(:active)
|
|
244
|
+
#=> '"active"'
|
|
245
|
+
|
|
246
|
+
## Horreum serialize_value: hash becomes JSON object
|
|
247
|
+
@customer.serialize_value({ name: 'test', count: 5 })
|
|
248
|
+
#=> '{"name":"test","count":5}'
|
|
249
|
+
|
|
250
|
+
## Horreum serialize_value: array becomes JSON array
|
|
251
|
+
@customer.serialize_value([1, 'two', true, nil])
|
|
252
|
+
#=> '[1,"two",true,null]'
|
|
253
|
+
|
|
254
|
+
## Horreum serialize_value: nested structures work
|
|
255
|
+
@customer.serialize_value({ users: [{ id: 1 }, { id: 2 }] })
|
|
256
|
+
#=> '{"users":[{"id":1},{"id":2}]}'
|
|
257
|
+
|
|
258
|
+
# ========================================
|
|
259
|
+
# Horreum deserialize_value Comprehensive Tests
|
|
260
|
+
# ========================================
|
|
261
|
+
|
|
262
|
+
## Horreum deserialize_value: JSON string becomes Ruby string
|
|
263
|
+
@customer.deserialize_value('"hello"')
|
|
264
|
+
#=> 'hello'
|
|
265
|
+
|
|
266
|
+
## Horreum deserialize_value: JSON number becomes Ruby integer
|
|
267
|
+
@customer.deserialize_value('42')
|
|
268
|
+
#=> 42
|
|
269
|
+
|
|
270
|
+
## Horreum deserialize_value: JSON number is actually Integer class
|
|
271
|
+
@customer.deserialize_value('42').class
|
|
272
|
+
#=> Integer
|
|
273
|
+
|
|
274
|
+
## Horreum deserialize_value: JSON float becomes Ruby float
|
|
275
|
+
@customer.deserialize_value('3.14159')
|
|
276
|
+
#=> 3.14159
|
|
277
|
+
|
|
278
|
+
## Horreum deserialize_value: JSON float is actually Float class
|
|
279
|
+
@customer.deserialize_value('3.14159').class
|
|
280
|
+
#=> Float
|
|
281
|
+
|
|
282
|
+
## Horreum deserialize_value: JSON true becomes Ruby true
|
|
283
|
+
@customer.deserialize_value('true')
|
|
284
|
+
#=> true
|
|
285
|
+
|
|
286
|
+
## Horreum deserialize_value: JSON true is TrueClass
|
|
287
|
+
@customer.deserialize_value('true').class
|
|
288
|
+
#=> TrueClass
|
|
289
|
+
|
|
290
|
+
## Horreum deserialize_value: JSON false becomes Ruby false
|
|
291
|
+
@customer.deserialize_value('false')
|
|
292
|
+
#=> false
|
|
293
|
+
|
|
294
|
+
## Horreum deserialize_value: JSON false is FalseClass
|
|
295
|
+
@customer.deserialize_value('false').class
|
|
296
|
+
#=> FalseClass
|
|
297
|
+
|
|
298
|
+
## Horreum deserialize_value: JSON null becomes Ruby nil
|
|
299
|
+
@customer.deserialize_value('null')
|
|
300
|
+
#=> nil
|
|
301
|
+
|
|
302
|
+
## Horreum deserialize_value: JSON object becomes Ruby hash
|
|
303
|
+
@customer.deserialize_value('{"name":"test","count":5}')
|
|
304
|
+
#=> {"name"=>"test", "count"=>5}
|
|
305
|
+
|
|
306
|
+
## Horreum deserialize_value: JSON array becomes Ruby array
|
|
307
|
+
@customer.deserialize_value('[1,"two",true,null]')
|
|
308
|
+
#=> [1, "two", true, nil]
|
|
309
|
+
|
|
310
|
+
## Horreum deserialize_value: nil input returns nil
|
|
311
|
+
@customer.deserialize_value(nil)
|
|
312
|
+
#=> nil
|
|
313
|
+
|
|
314
|
+
## Horreum deserialize_value: empty string returns nil
|
|
315
|
+
@customer.deserialize_value('')
|
|
316
|
+
#=> nil
|
|
317
|
+
|
|
318
|
+
## Horreum deserialize_value: plain unquoted string (legacy data) returns as-is
|
|
319
|
+
# This handles data stored before JSON encoding was used
|
|
320
|
+
@customer.deserialize_value('plain string without quotes')
|
|
321
|
+
#=> 'plain string without quotes'
|
|
322
|
+
|
|
323
|
+
# ========================================
|
|
324
|
+
# Familia Object Serialization (shared behavior)
|
|
325
|
+
# ========================================
|
|
326
|
+
|
|
327
|
+
## Horreum serialize_value: string value gets JSON encoded
|
|
328
|
+
# When storing a value from another Familia object's field
|
|
329
|
+
@ref_customer = Customer.new('reference_test@example.com')
|
|
330
|
+
@ref_customer.custid = 'reference_test@example.com'
|
|
331
|
+
# Note: Horreum.serialize_value uses JsonSerializer.dump, which JSON-encodes
|
|
332
|
+
# all values, including strings. This is different from DataType#serialize_value,
|
|
333
|
+
# which has special handling for Familia objects.
|
|
334
|
+
@customer.serialize_value(@ref_customer.custid)
|
|
335
|
+
#=> '"reference_test@example.com"'
|
|
336
|
+
|
|
337
|
+
# ========================================
|
|
338
|
+
# Round-trip Type Preservation Tests
|
|
339
|
+
# ========================================
|
|
340
|
+
|
|
341
|
+
## Round-trip: integer preserves type through Horreum serialization
|
|
342
|
+
serialized = @customer.serialize_value(42)
|
|
343
|
+
@customer.deserialize_value(serialized)
|
|
344
|
+
#=> 42
|
|
345
|
+
|
|
346
|
+
## Round-trip: integer class preserved
|
|
347
|
+
serialized = @customer.serialize_value(42)
|
|
348
|
+
@customer.deserialize_value(serialized).class
|
|
349
|
+
#=> Integer
|
|
350
|
+
|
|
351
|
+
## Round-trip: boolean true preserves type
|
|
352
|
+
serialized = @customer.serialize_value(true)
|
|
353
|
+
@customer.deserialize_value(serialized)
|
|
354
|
+
#=> true
|
|
355
|
+
|
|
356
|
+
## Round-trip: boolean true class preserved
|
|
357
|
+
serialized = @customer.serialize_value(true)
|
|
358
|
+
@customer.deserialize_value(serialized).class
|
|
359
|
+
#=> TrueClass
|
|
360
|
+
|
|
361
|
+
## Round-trip: boolean false preserves type
|
|
362
|
+
serialized = @customer.serialize_value(false)
|
|
363
|
+
@customer.deserialize_value(serialized)
|
|
364
|
+
#=> false
|
|
365
|
+
|
|
366
|
+
## Round-trip: nil preserves type
|
|
367
|
+
serialized = @customer.serialize_value(nil)
|
|
368
|
+
@customer.deserialize_value(serialized)
|
|
369
|
+
#=> nil
|
|
370
|
+
|
|
371
|
+
## Round-trip: hash preserves structure
|
|
372
|
+
serialized = @customer.serialize_value({ active: true, count: 10 })
|
|
373
|
+
@customer.deserialize_value(serialized)
|
|
374
|
+
#=> {"active"=>true, "count"=>10}
|
|
375
|
+
|
|
376
|
+
## Round-trip: array preserves structure and types
|
|
377
|
+
serialized = @customer.serialize_value([1, 'two', true, nil, 3.5])
|
|
378
|
+
@customer.deserialize_value(serialized)
|
|
379
|
+
#=> [1, "two", true, nil, 3.5]
|
|
380
|
+
|
|
381
|
+
# Cleanup
|
|
382
|
+
@bone.props.delete!
|
|
383
|
+
@bone.owners.delete!
|
|
384
|
+
@bone.tags.delete!
|
|
385
|
+
@bone.metrics.delete!
|
|
386
|
+
@customer.destroy! rescue nil
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# try/unit/familia_resolve_class_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# Unit tests for Familia.resolve_class method
|
|
6
|
+
#
|
|
7
|
+
# This test ensures the public API for resolving class references works
|
|
8
|
+
# correctly across different input types (Class, Symbol, String).
|
|
9
|
+
#
|
|
10
|
+
# Related to the fix for NoMethodError in participates_in where the private
|
|
11
|
+
# method member_by_config_name was being called directly instead of using
|
|
12
|
+
# the public resolve_class API.
|
|
13
|
+
|
|
14
|
+
require_relative '../support/helpers/test_helpers'
|
|
15
|
+
|
|
16
|
+
# Test class for resolution
|
|
17
|
+
class ResolveTestClass < Familia::Horreum
|
|
18
|
+
identifier_field :id
|
|
19
|
+
field :id
|
|
20
|
+
field :name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Test class in module for modularized class resolution
|
|
24
|
+
module ResolveTestModule
|
|
25
|
+
class ModularClass < Familia::Horreum
|
|
26
|
+
identifier_field :id
|
|
27
|
+
field :id
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
## Test resolve_class with Class object returns the class unchanged
|
|
32
|
+
@resolved_class = Familia.resolve_class(ResolveTestClass)
|
|
33
|
+
@resolved_class == ResolveTestClass
|
|
34
|
+
#=> true
|
|
35
|
+
|
|
36
|
+
## Test resolve_class with Symbol returns the correct class
|
|
37
|
+
@resolved_symbol = Familia.resolve_class(:ResolveTestClass)
|
|
38
|
+
@resolved_symbol == ResolveTestClass
|
|
39
|
+
#=> true
|
|
40
|
+
|
|
41
|
+
## Test resolve_class with String returns the correct class
|
|
42
|
+
@resolved_string = Familia.resolve_class('ResolveTestClass')
|
|
43
|
+
@resolved_string == ResolveTestClass
|
|
44
|
+
#=> true
|
|
45
|
+
|
|
46
|
+
## Test resolve_class with PascalCase symbol works
|
|
47
|
+
@resolved_pascal_sym = Familia.resolve_class(:ResolveTestClass)
|
|
48
|
+
@resolved_pascal_sym == ResolveTestClass
|
|
49
|
+
#=> true
|
|
50
|
+
|
|
51
|
+
## Test resolve_class with PascalCase string works
|
|
52
|
+
@resolved_pascal_str = Familia.resolve_class('ResolveTestClass')
|
|
53
|
+
@resolved_pascal_str == ResolveTestClass
|
|
54
|
+
#=> true
|
|
55
|
+
|
|
56
|
+
## Test resolve_class with snake_case symbol works
|
|
57
|
+
@resolved_snake = Familia.resolve_class(:resolve_test_class)
|
|
58
|
+
@resolved_snake == ResolveTestClass
|
|
59
|
+
#=> true
|
|
60
|
+
|
|
61
|
+
## Test resolve_class with snake_case string works
|
|
62
|
+
@resolved_snake_str = Familia.resolve_class('resolve_test_class')
|
|
63
|
+
@resolved_snake_str == ResolveTestClass
|
|
64
|
+
#=> true
|
|
65
|
+
|
|
66
|
+
## Test resolve_class raises ArgumentError for invalid types
|
|
67
|
+
begin
|
|
68
|
+
Familia.resolve_class(123)
|
|
69
|
+
@raised = false
|
|
70
|
+
rescue ArgumentError => e
|
|
71
|
+
@raised = true
|
|
72
|
+
@error_message = e.message
|
|
73
|
+
end
|
|
74
|
+
@raised
|
|
75
|
+
#=> true
|
|
76
|
+
|
|
77
|
+
## Test error message is descriptive
|
|
78
|
+
@error_message.include?('Expected Class, String, or Symbol')
|
|
79
|
+
#=> true
|
|
80
|
+
|
|
81
|
+
## Test resolve_class returns nil for non-existent class
|
|
82
|
+
@nonexistent = Familia.resolve_class(:NonExistentClass)
|
|
83
|
+
@nonexistent.nil?
|
|
84
|
+
#=> true
|
|
85
|
+
|
|
86
|
+
## Test resolve_class with variations of proper naming
|
|
87
|
+
# Note: All-caps or all-lowercase don't work because snake_case needs case boundaries
|
|
88
|
+
# Realistic usage: PascalCase, snake_case, or mixed-case with boundaries
|
|
89
|
+
@case_variant_snake = Familia.resolve_class('resolve_test_class')
|
|
90
|
+
@case_variant_snake == ResolveTestClass
|
|
91
|
+
#=> true
|
|
92
|
+
|
|
93
|
+
## Test resolve_class handles already snake_cased symbols
|
|
94
|
+
@already_snake = Familia.resolve_class(:resolve_test_class)
|
|
95
|
+
@already_snake == ResolveTestClass
|
|
96
|
+
#=> true
|
|
97
|
+
|
|
98
|
+
## Test resolve_class with modularized Symbol (without module prefix)
|
|
99
|
+
@modular_resolved = Familia.resolve_class(:ModularClass)
|
|
100
|
+
@modular_resolved == ResolveTestModule::ModularClass
|
|
101
|
+
#=> true
|
|
102
|
+
|
|
103
|
+
## Test resolve_class with modularized String (without module prefix)
|
|
104
|
+
@modular_resolved_str = Familia.resolve_class('ModularClass')
|
|
105
|
+
@modular_resolved_str == ResolveTestModule::ModularClass
|
|
106
|
+
#=> true
|
|
107
|
+
|
|
108
|
+
## Test resolve_class with snake_case modularized Symbol
|
|
109
|
+
@modular_snake = Familia.resolve_class(:modular_class)
|
|
110
|
+
@modular_snake == ResolveTestModule::ModularClass
|
|
111
|
+
#=> true
|
|
112
|
+
|
|
113
|
+
## Test resolve_class with Class object for modularized class
|
|
114
|
+
@modular_class_obj = Familia.resolve_class(ResolveTestModule::ModularClass)
|
|
115
|
+
@modular_class_obj == ResolveTestModule::ModularClass
|
|
116
|
+
#=> true
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# try/unit/horreum/auto_indexing_on_save_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
1
5
|
# try/horreum/auto_indexing_on_save_try.rb
|
|
2
6
|
|
|
3
7
|
#
|
|
@@ -182,7 +186,7 @@ AutoIndexWithTransient.find_by_email(@transient_email)&.id
|
|
|
182
186
|
begin
|
|
183
187
|
@transient_dup.save
|
|
184
188
|
rescue Familia::RecordExistsError => ex
|
|
185
|
-
Familia.
|
|
189
|
+
Familia.debug ex.backtrace.join("\n")
|
|
186
190
|
ex.message
|
|
187
191
|
end
|
|
188
192
|
#=:> String
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# try/unit/horreum/destroy_related_fields_cleanup_try.rb
|
|
2
|
+
#
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
1
5
|
# try/horreum/destroy_related_fields_cleanup_try.rb
|
|
2
6
|
|
|
3
7
|
# Horreum destroy! Related Fields Cleanup Tryouts
|
|
@@ -255,8 +259,9 @@ destroy_result = model.destroy!
|
|
|
255
259
|
|
|
256
260
|
# Should result in success and also complete in a reasonable amount of
|
|
257
261
|
# time (under 100ms for this test). I acknowledge this is flaky.
|
|
262
|
+
# Note: 42 results = 40 related field DELs + 1 main object DEL + 1 instances ZREM
|
|
258
263
|
[destroy_result.class, destroy_result.successful?, destroy_result.results.size]
|
|
259
|
-
#=> [MultiResult, true,
|
|
264
|
+
#=> [MultiResult, true, 42]
|
|
260
265
|
#=%> 100
|
|
261
266
|
|
|
262
267
|
## Verify transaction_fallback_integration_try.rb bug is fixed
|