typia 13.1.1 → 13.2.0
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.
- package/README.md +3 -0
- package/lib/_virtual/_rolldown/runtime.mjs +1 -5
- package/lib/executable/FileSystemIdentity.d.ts +44 -0
- package/lib/executable/FileSystemIdentity.js +213 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +133 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +272 -106
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +239 -95
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/functional.d.ts +15 -12
- package/lib/functional.js.map +1 -1
- package/lib/functional.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +32 -0
- package/lib/internal/_ProtobufReader.js +148 -48
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +137 -41
- package/lib/internal/_ProtobufReader.mjs.map +1 -1
- package/lib/internal/_createStandardSchema.js +18 -1
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs +12 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_decimal.d.ts +14 -0
- package/lib/internal/_decimal.js +61 -0
- package/lib/internal/_decimal.js.map +1 -0
- package/lib/internal/_decimal.mjs +49 -0
- package/lib/internal/_decimal.mjs.map +1 -0
- package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
- package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
- package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
- package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
- package/lib/internal/_isFormatByte.js +2 -5
- package/lib/internal/_isFormatByte.js.map +1 -1
- package/lib/internal/_isFormatByte.mjs +2 -5
- package/lib/internal/_isFormatByte.mjs.map +1 -1
- package/lib/internal/_isFormatDate.js +15 -2
- package/lib/internal/_isFormatDate.js.map +1 -1
- package/lib/internal/_isFormatDate.mjs +22 -2
- package/lib/internal/_isFormatDate.mjs.map +1 -1
- package/lib/internal/_isFormatDateTime.js +21 -2
- package/lib/internal/_isFormatDateTime.js.map +1 -1
- package/lib/internal/_isFormatDateTime.mjs +13 -2
- package/lib/internal/_isFormatDateTime.mjs.map +1 -1
- package/lib/internal/_isFormatIri.js +3 -2
- package/lib/internal/_isFormatIri.js.map +1 -1
- package/lib/internal/_isFormatIri.mjs +3 -2
- package/lib/internal/_isFormatIri.mjs.map +1 -1
- package/lib/internal/_isFormatIriReference.js +10 -2
- package/lib/internal/_isFormatIriReference.js.map +1 -1
- package/lib/internal/_isFormatIriReference.mjs +9 -2
- package/lib/internal/_isFormatIriReference.mjs.map +1 -1
- package/lib/internal/_isFormatUriReference.js +1 -1
- package/lib/internal/_isFormatUriReference.js.map +1 -1
- package/lib/internal/_isFormatUriReference.mjs +1 -1
- package/lib/internal/_isFormatUriReference.mjs.map +1 -1
- package/lib/internal/_isMultipleOf.d.ts +1 -0
- package/lib/internal/_isMultipleOf.js +13 -0
- package/lib/internal/_isMultipleOf.js.map +1 -0
- package/lib/internal/_isMultipleOf.mjs +12 -0
- package/lib/internal/_isMultipleOf.mjs.map +1 -0
- package/lib/internal/_isTypeFloat.js +1 -1
- package/lib/internal/_isTypeFloat.js.map +1 -1
- package/lib/internal/_isTypeFloat.mjs +1 -1
- package/lib/internal/_isTypeFloat.mjs.map +1 -1
- package/lib/internal/_isTypeInt64.js +1 -0
- package/lib/internal/_isTypeInt64.js.map +1 -1
- package/lib/internal/_isTypeInt64.mjs.map +1 -1
- package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeInt64Bigint.js +15 -0
- package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
- package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
- package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
- package/lib/internal/_isTypeUint64.js +1 -0
- package/lib/internal/_isTypeUint64.js.map +1 -1
- package/lib/internal/_isTypeUint64.mjs.map +1 -1
- package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeUint64Bigint.js +10 -0
- package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
- package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
- package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
- package/lib/internal/_isUniqueItems.js +96 -109
- package/lib/internal/_isUniqueItems.js.map +1 -1
- package/lib/internal/_isUniqueItems.mjs +62 -50
- package/lib/internal/_isUniqueItems.mjs.map +1 -1
- package/lib/internal/_jsonStringifyArray.d.ts +1 -0
- package/lib/internal/_jsonStringifyArray.js +48 -0
- package/lib/internal/_jsonStringifyArray.js.map +1 -0
- package/lib/internal/_jsonStringifyArray.mjs +40 -0
- package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
- package/lib/internal/_jsonStringifyElement.d.ts +1 -0
- package/lib/internal/_jsonStringifyElement.js +23 -0
- package/lib/internal/_jsonStringifyElement.js.map +1 -0
- package/lib/internal/_jsonStringifyElement.mjs +23 -0
- package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
- package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
- package/lib/internal/_jsonStringifyProperty.js +31 -0
- package/lib/internal/_jsonStringifyProperty.js.map +1 -0
- package/lib/internal/_jsonStringifyProperty.mjs +31 -0
- package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
- package/lib/internal/_llmApplicationFinalize.js +1 -1
- package/lib/internal/_llmApplicationFinalize.js.map +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs.map +1 -1
- package/lib/internal/_notationAny.js +8 -1
- package/lib/internal/_notationAny.js.map +1 -1
- package/lib/internal/_notationAny.mjs +7 -1
- package/lib/internal/_notationAny.mjs.map +1 -1
- package/lib/internal/_notationAssign.d.ts +1 -0
- package/lib/internal/_notationAssign.js +18 -0
- package/lib/internal/_notationAssign.js.map +1 -0
- package/lib/internal/_notationAssign.mjs +17 -0
- package/lib/internal/_notationAssign.mjs.map +1 -0
- package/lib/internal/_notationCamel.js +30 -9
- package/lib/internal/_notationCamel.js.map +1 -1
- package/lib/internal/_notationCamel.mjs +13 -5
- package/lib/internal/_notationCamel.mjs.map +1 -1
- package/lib/internal/_notationKebab.d.ts +1 -0
- package/lib/internal/_notationKebab.js +15 -0
- package/lib/internal/_notationKebab.js.map +1 -0
- package/lib/internal/_notationKebab.mjs +15 -0
- package/lib/internal/_notationKebab.mjs.map +1 -0
- package/lib/internal/_notationKeyCollision.d.ts +1 -0
- package/lib/internal/_notationKeyCollision.js +8 -0
- package/lib/internal/_notationKeyCollision.js.map +1 -0
- package/lib/internal/_notationKeyCollision.mjs +8 -0
- package/lib/internal/_notationKeyCollision.mjs.map +1 -0
- package/lib/internal/_notationPascal.js +20 -5
- package/lib/internal/_notationPascal.js.map +1 -1
- package/lib/internal/_notationPascal.mjs +10 -5
- package/lib/internal/_notationPascal.mjs.map +1 -1
- package/lib/internal/_notationSnake.js +25 -22
- package/lib/internal/_notationSnake.js.map +1 -1
- package/lib/internal/_notationSnake.mjs +11 -11
- package/lib/internal/_notationSnake.mjs.map +1 -1
- package/lib/internal/_plainCloneAny.js +174 -38
- package/lib/internal/_plainCloneAny.js.map +1 -1
- package/lib/internal/_plainCloneAny.mjs +126 -22
- package/lib/internal/_plainCloneAny.mjs.map +1 -1
- package/lib/internal/_randomArray.d.ts +1 -1
- package/lib/internal/_randomArray.js +11 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +9 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.d.ts +2 -1
- package/lib/internal/_randomFormatByte.js +25 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +20 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +3 -4
- package/lib/internal/_randomFormatDate.js +3 -10
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -6
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +3 -4
- package/lib/internal/_randomFormatDatetime.js +26 -8
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +17 -6
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +23 -14
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +22 -13
- package/lib/internal/_randomFormatDuration.mjs.map +1 -1
- package/lib/internal/_randomFormatEmail.d.ts +2 -1
- package/lib/internal/_randomFormatEmail.js +8 -1
- package/lib/internal/_randomFormatEmail.js.map +1 -1
- package/lib/internal/_randomFormatEmail.mjs +5 -1
- package/lib/internal/_randomFormatEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +8 -1
- package/lib/internal/_randomFormatHostname.js +45 -2
- package/lib/internal/_randomFormatHostname.js.map +1 -1
- package/lib/internal/_randomFormatHostname.mjs +38 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
- package/lib/internal/_randomFormatIdnEmail.js +16 -2
- package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
- package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
- package/lib/internal/_randomFormatIdnHostname.js +26 -1
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv4.d.ts +2 -1
- package/lib/internal/_randomFormatIpv4.js +32 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +23 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +58 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +45 -1
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatIri.d.ts +2 -1
- package/lib/internal/_randomFormatIri.js +1 -1
- package/lib/internal/_randomFormatIri.js.map +1 -1
- package/lib/internal/_randomFormatIri.mjs +1 -1
- package/lib/internal/_randomFormatIri.mjs.map +1 -1
- package/lib/internal/_randomFormatIriReference.d.ts +2 -1
- package/lib/internal/_randomFormatIriReference.js +1 -1
- package/lib/internal/_randomFormatIriReference.js.map +1 -1
- package/lib/internal/_randomFormatIriReference.mjs +1 -1
- package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatJsonPointer.js +20 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +15 -1
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatPassword.d.ts +2 -1
- package/lib/internal/_randomFormatPassword.js +7 -5
- package/lib/internal/_randomFormatPassword.js.map +1 -1
- package/lib/internal/_randomFormatPassword.mjs +5 -1
- package/lib/internal/_randomFormatPassword.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.d.ts +2 -1
- package/lib/internal/_randomFormatRegex.js +15 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +14 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +20 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +34 -7
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +37 -4
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomFormatUri.d.ts +2 -1
- package/lib/internal/_randomFormatUri.js +1 -1
- package/lib/internal/_randomFormatUri.js.map +1 -1
- package/lib/internal/_randomFormatUri.mjs +1 -1
- package/lib/internal/_randomFormatUri.mjs.map +1 -1
- package/lib/internal/_randomFormatUriReference.d.ts +2 -1
- package/lib/internal/_randomFormatUriReference.js +1 -1
- package/lib/internal/_randomFormatUriReference.js.map +1 -1
- package/lib/internal/_randomFormatUriReference.mjs +1 -1
- package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
- package/lib/internal/_randomFormatUriTemplate.js +1 -1
- package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
- package/lib/internal/_randomFormatUrl.d.ts +2 -1
- package/lib/internal/_randomFormatUrl.js +21 -1
- package/lib/internal/_randomFormatUrl.js.map +1 -1
- package/lib/internal/_randomFormatUrl.mjs +18 -1
- package/lib/internal/_randomFormatUrl.mjs.map +1 -1
- package/lib/internal/_randomFormatUuid.d.ts +2 -1
- package/lib/internal/_randomFormatUuid.js +3 -2
- package/lib/internal/_randomFormatUuid.js.map +1 -1
- package/lib/internal/_randomFormatUuid.mjs +3 -2
- package/lib/internal/_randomFormatUuid.mjs.map +1 -1
- package/lib/internal/_randomInteger.js +59 -28
- package/lib/internal/_randomInteger.js.map +1 -1
- package/lib/internal/_randomInteger.mjs +56 -16
- package/lib/internal/_randomInteger.mjs.map +1 -1
- package/lib/internal/_randomMultiple.d.ts +8 -0
- package/lib/internal/_randomMultiple.js +168 -0
- package/lib/internal/_randomMultiple.js.map +1 -0
- package/lib/internal/_randomMultiple.mjs +158 -0
- package/lib/internal/_randomMultiple.mjs.map +1 -0
- package/lib/internal/_randomNumber.js +42 -42
- package/lib/internal/_randomNumber.js.map +1 -1
- package/lib/internal/_randomNumber.mjs +41 -27
- package/lib/internal/_randomNumber.mjs.map +1 -1
- package/lib/internal/_randomPattern.d.ts +2 -1
- package/lib/internal/_randomPattern.js +19 -4
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +10 -4
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +64 -0
- package/lib/internal/_randomStringLength.js +84 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +79 -0
- package/lib/internal/_randomStringLength.mjs.map +1 -0
- package/lib/internal/_stringLength.d.ts +1 -0
- package/lib/internal/_stringLength.js +11 -0
- package/lib/internal/_stringLength.js.map +1 -0
- package/lib/internal/_stringLength.mjs +10 -0
- package/lib/internal/_stringLength.mjs.map +1 -0
- package/lib/internal/_validateReport.js +4 -1
- package/lib/internal/_validateReport.js.map +1 -1
- package/lib/internal/_validateReport.mjs +2 -1
- package/lib/internal/_validateReport.mjs.map +1 -1
- package/lib/internal/private/__notationRename.d.ts +14 -0
- package/lib/internal/private/__notationRename.js +25 -0
- package/lib/internal/private/__notationRename.js.map +1 -0
- package/lib/internal/private/__notationRename.mjs +24 -0
- package/lib/internal/private/__notationRename.mjs.map +1 -0
- package/lib/internal/private/__randomComposition.d.ts +23 -0
- package/lib/internal/private/__randomComposition.js +48 -0
- package/lib/internal/private/__randomComposition.js.map +1 -0
- package/lib/internal/private/__randomComposition.mjs +54 -0
- package/lib/internal/private/__randomComposition.mjs.map +1 -0
- package/lib/internal/private/__randomEpoch.d.ts +19 -0
- package/lib/internal/private/__randomEpoch.js +31 -0
- package/lib/internal/private/__randomEpoch.js.map +1 -0
- package/lib/internal/private/__randomEpoch.mjs +28 -0
- package/lib/internal/private/__randomEpoch.mjs.map +1 -0
- package/lib/json.d.ts +2 -2
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +2 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +20 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/native/adapter/plugin_options.go +117 -0
- package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
- package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
- package/native/cmd/ttsc-typia/build.go +84 -64
- package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
- package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
- package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
- package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
- package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
- package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
- package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
- package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
- package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
- package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
- package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
- package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
- package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
- package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
- package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
- package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
- package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
- package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
- package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
- package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
- package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
- package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
- package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
- package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
- package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
- package/native/cmd/ttsc-typia/main_wasm.go +21 -2
- package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
- package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
- package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
- package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
- package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
- package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
- package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
- package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
- package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
- package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
- package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
- package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
- package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
- package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
- package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
- package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
- package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
- package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
- package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
- package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
- package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
- package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
- package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
- package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
- package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
- package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -0
- package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
- package/native/cmd/ttsc-typia/symbol_index_domain_transform_test.go +316 -0
- package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
- package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +251 -39
- package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
- package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
- package/native/cmd/ttsc-typia/transform_helpers_test.go +236 -3
- package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
- package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
- package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
- package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
- package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
- package/native/core/factories/FormatCheatSheet.go +40 -7
- package/native/core/factories/IdentifierFactory.go +131 -4
- package/native/core/factories/MetadataCommentTagFactory.go +83 -40
- package/native/core/factories/MetadataTypeTagFactory.go +13 -1
- package/native/core/factories/NumericRangeFactory.go +60 -17
- package/native/core/factories/ProtobufFactory.go +13 -5
- package/native/core/factories/factory_utility_coverage_test.go +8 -2
- package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
- package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
- package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
- package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
- package/native/core/factories/internal/metadata/MetadataHelper.go +226 -17
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +141 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +5 -12
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +111 -29
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +5 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +45 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +5 -0
- package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
- package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
- package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
- package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
- package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
- package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
- package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
- package/native/core/programmers/IsProgrammer.go +15 -1
- package/native/core/programmers/RandomProgrammer.go +51 -14
- package/native/core/programmers/compare/CompareEqualProgrammer.go +410 -8
- package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
- package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
- package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
- package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
- package/native/core/programmers/helpers/CloneJoiner.go +32 -0
- package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
- package/native/core/programmers/helpers/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +161 -51
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -118
- package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
- package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
- package/native/core/programmers/iterate/check_template.go +344 -32
- package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
- package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
- package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
- package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
- package/native/core/programmers/iterate/json_schema_object.go +49 -7
- package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +674 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
- package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
- package/native/core/programmers/iterate/template_runtime_pattern.go +63 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +21 -11
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
- package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
- package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
- package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
- package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
- package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
- package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
- package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
- package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
- package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
- package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +41 -22
- package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
- package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
- package/native/core/schemas/metadata/MetadataCollection.go +266 -25
- package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +24 -22
- package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
- package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
- package/native/core/utils/PatternUtil.go +13 -0
- package/native/core/utils/PromiseTypeFactory.go +59 -0
- package/native/core/utils/ProtobufNameEncoder.go +8 -0
- package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
- package/native/go.mod +9 -1
- package/native/transform/CallExpressionTransformer.go +12 -0
- package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
- package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
- package/package.json +12 -4
- package/src/executable/FileSystemIdentity.ts +222 -0
- package/src/executable/TypiaGenerateWizard.ts +386 -113
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +161 -46
- package/src/internal/_createStandardSchema.ts +15 -1
- package/src/internal/_decimal.ts +69 -0
- package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
- package/src/internal/_isFormatByte.ts +2 -5
- package/src/internal/_isFormatDate.ts +15 -2
- package/src/internal/_isFormatDateTime.ts +28 -2
- package/src/internal/_isFormatIri.ts +5 -2
- package/src/internal/_isFormatIriReference.ts +11 -3
- package/src/internal/_isFormatUriReference.ts +1 -1
- package/src/internal/_isMultipleOf.ts +8 -0
- package/src/internal/_isTypeFloat.ts +1 -1
- package/src/internal/_isTypeInt64.ts +1 -0
- package/src/internal/_isTypeInt64Bigint.ts +12 -0
- package/src/internal/_isTypeUint64.ts +1 -0
- package/src/internal/_isTypeUint64Bigint.ts +7 -0
- package/src/internal/_isUniqueItems.ts +134 -132
- package/src/internal/_jsonStringifyArray.ts +50 -0
- package/src/internal/_jsonStringifyElement.ts +19 -0
- package/src/internal/_jsonStringifyProperty.ts +30 -0
- package/src/internal/_llmApplicationFinalize.ts +6 -1
- package/src/internal/_notationAny.ts +9 -4
- package/src/internal/_notationAssign.ts +20 -0
- package/src/internal/_notationCamel.ts +31 -10
- package/src/internal/_notationKebab.ts +11 -0
- package/src/internal/_notationKeyCollision.ts +9 -0
- package/src/internal/_notationPascal.ts +19 -6
- package/src/internal/_notationSnake.ts +24 -21
- package/src/internal/_plainCloneAny.ts +208 -33
- package/src/internal/_randomArray.ts +13 -4
- package/src/internal/_randomFormatByte.ts +31 -1
- package/src/internal/_randomFormatDate.ts +6 -17
- package/src/internal/_randomFormatDatetime.ts +34 -15
- package/src/internal/_randomFormatDuration.ts +30 -13
- package/src/internal/_randomFormatEmail.ts +8 -2
- package/src/internal/_randomFormatHostname.ts +48 -1
- package/src/internal/_randomFormatIdnEmail.ts +18 -2
- package/src/internal/_randomFormatIdnHostname.ts +34 -2
- package/src/internal/_randomFormatIpv4.ts +43 -2
- package/src/internal/_randomFormatIpv6.ts +67 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +28 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +22 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +26 -6
- package/src/internal/_randomFormatTime.ts +46 -10
- package/src/internal/_randomFormatUri.ts +3 -1
- package/src/internal/_randomFormatUriReference.ts +3 -1
- package/src/internal/_randomFormatUriTemplate.ts +3 -1
- package/src/internal/_randomFormatUrl.ts +25 -2
- package/src/internal/_randomFormatUuid.ts +10 -6
- package/src/internal/_randomInteger.ts +87 -40
- package/src/internal/_randomMultiple.ts +245 -0
- package/src/internal/_randomNumber.ts +72 -55
- package/src/internal/_randomPattern.ts +29 -4
- package/src/internal/_randomStringLength.ts +116 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +21 -0
- package/src/internal/private/__randomComposition.ts +50 -0
- package/src/internal/private/__randomEpoch.ts +34 -0
- package/src/json.ts +2 -2
- package/src/module.ts +4 -6
- package/src/notations.ts +20 -4
- package/lib/internal/private/__notationCapitalize.d.ts +0 -1
- package/lib/internal/private/__notationCapitalize.js +0 -6
- package/lib/internal/private/__notationCapitalize.js.map +0 -1
- package/lib/internal/private/__notationCapitalize.mjs +0 -6
- package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
- package/lib/internal/private/__notationUnsnake.d.ts +0 -4
- package/lib/internal/private/__notationUnsnake.js +0 -26
- package/lib/internal/private/__notationUnsnake.js.map +0 -1
- package/lib/internal/private/__notationUnsnake.mjs +0 -15
- package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
- package/native/adapter/visit.go +0 -173
- package/native/adapter/visit_property_chain_edges_test.go +0 -129
- package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
- package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
- package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
- package/native/core/programmers/iterate/check_union_array_like.go +0 -422
- package/native/core/programmers/iterate/prune_object_properties.go +0 -105
- package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
- package/native/core/programmers/iterate/stringify_native.go +0 -14
- package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
- package/native/core/schemas/metadata/MetadataApplication.go +0 -41
- package/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestCompareTemplateLiteralUnionTransform verifies template-literal object
|
|
12
|
+
// union members retain their runtime domains during equality dispatch.
|
|
13
|
+
//
|
|
14
|
+
// The #2225 first-match fallback must use the same structural template
|
|
15
|
+
// membership decision as is and clone. Weakening both template domains to
|
|
16
|
+
// `typeof string` routes valid `b_*` values through the `a_*` comparator and
|
|
17
|
+
// drops `b`.
|
|
18
|
+
//
|
|
19
|
+
// 1. Transform direct and factory is, clone, and equals calls for a tag-free
|
|
20
|
+
// template-literal object union and the same union nested in an object.
|
|
21
|
+
// 2. Prove is accepts both witnesses and clone selects the `b_*` member while
|
|
22
|
+
// preserving their different `b` values.
|
|
23
|
+
// 3. Exercise equal, cross-member, invalid-discriminator, nested, literal-
|
|
24
|
+
// discriminated, non-discriminable, and non-union controls at runtime.
|
|
25
|
+
func TestCompareTemplateLiteralUnionTransform(t *testing.T) {
|
|
26
|
+
project := compareTemplateLiteralUnionProject(t)
|
|
27
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
28
|
+
return runTransform([]string{
|
|
29
|
+
"--cwd", project,
|
|
30
|
+
"--tsconfig", "tsconfig.json",
|
|
31
|
+
"--file", "src/main.ts",
|
|
32
|
+
"--output", "js",
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
if code != 0 {
|
|
36
|
+
t.Fatalf("compare template-literal union transform failed: code=%d stderr=\n%s", code, errText)
|
|
37
|
+
}
|
|
38
|
+
compareTemplateLiteralUnionRunRuntimeCases(t, project, out)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func compareTemplateLiteralUnionProject(t *testing.T) string {
|
|
42
|
+
t.Helper()
|
|
43
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
44
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
45
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
46
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
47
|
+
}
|
|
48
|
+
dir, err := os.MkdirTemp(base, "compare-template-literal-union-")
|
|
49
|
+
if err != nil {
|
|
50
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
51
|
+
}
|
|
52
|
+
t.Cleanup(func() {
|
|
53
|
+
_ = os.RemoveAll(dir)
|
|
54
|
+
})
|
|
55
|
+
src := filepath.Join(dir, "src")
|
|
56
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
57
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
58
|
+
}
|
|
59
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareTemplateLiteralUnionTSConfig), 0o644); err != nil {
|
|
60
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
61
|
+
}
|
|
62
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareTemplateLiteralUnionSource), 0o644); err != nil {
|
|
63
|
+
t.Fatalf("write source: %v", err)
|
|
64
|
+
}
|
|
65
|
+
return dir
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func compareTemplateLiteralUnionRunRuntimeCases(t *testing.T, project string, js string) {
|
|
69
|
+
t.Helper()
|
|
70
|
+
node, err := exec.LookPath("node")
|
|
71
|
+
if err != nil {
|
|
72
|
+
t.Skip("node executable not found")
|
|
73
|
+
}
|
|
74
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
75
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
76
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
77
|
+
}
|
|
78
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
79
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "throw-type-guard-error-stub.cjs"), []byte(compareTemplateLiteralUnionThrowStub), 0o644); err != nil {
|
|
80
|
+
t.Fatalf("write throw stub: %v", err)
|
|
81
|
+
}
|
|
82
|
+
js = strings.ReplaceAll(js, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
|
|
83
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
84
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
85
|
+
t.Fatalf("write runtime module: %v", err)
|
|
86
|
+
}
|
|
87
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
88
|
+
if err := os.WriteFile(runner, []byte(compareTemplateLiteralUnionRuntimeRunner), 0o644); err != nil {
|
|
89
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
90
|
+
}
|
|
91
|
+
cmd := exec.Command(node, runner)
|
|
92
|
+
cmd.Dir = runtimeDir
|
|
93
|
+
output, err := cmd.CombinedOutput()
|
|
94
|
+
if err != nil {
|
|
95
|
+
t.Fatalf("compare template-literal union runtime cases failed: %v\n%s", err, output)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const compareTemplateLiteralUnionTSConfig = `{
|
|
100
|
+
"compilerOptions": {
|
|
101
|
+
"target": "ES2022",
|
|
102
|
+
"module": "commonjs",
|
|
103
|
+
"moduleResolution": "bundler",
|
|
104
|
+
"ignoreDeprecations": "6.0",
|
|
105
|
+
"types": ["*"],
|
|
106
|
+
"esModuleInterop": true,
|
|
107
|
+
"strict": true,
|
|
108
|
+
"skipLibCheck": true
|
|
109
|
+
},
|
|
110
|
+
"include": ["src"]
|
|
111
|
+
}
|
|
112
|
+
`
|
|
113
|
+
|
|
114
|
+
const compareTemplateLiteralUnionThrowStub = `module.exports._throwTypeGuardError = (props) => {
|
|
115
|
+
const error = new Error("guard: " + props.expected);
|
|
116
|
+
error.name = "TypeGuardError";
|
|
117
|
+
throw error;
|
|
118
|
+
};
|
|
119
|
+
`
|
|
120
|
+
|
|
121
|
+
const compareTemplateLiteralUnionSource = `import typia from "typia";
|
|
122
|
+
|
|
123
|
+
type TemplateUnion =
|
|
124
|
+
| { kind: ` + "`a_${string}`" + `; common: string }
|
|
125
|
+
| { kind: ` + "`b_${string}`" + `; common: string; b?: string };
|
|
126
|
+
type Nested = { value: TemplateUnion };
|
|
127
|
+
|
|
128
|
+
export const isTemplate = typia.createIs<TemplateUnion>();
|
|
129
|
+
export const cloneTemplate = typia.plain.createClone<TemplateUnion>();
|
|
130
|
+
export const eqTemplateFactory = typia.compare.createEquals<TemplateUnion>();
|
|
131
|
+
export const eqTemplateDirect = (x: TemplateUnion, y: TemplateUnion) =>
|
|
132
|
+
typia.compare.equals<TemplateUnion>(x, y);
|
|
133
|
+
|
|
134
|
+
export const isNested = typia.createIs<Nested>();
|
|
135
|
+
export const cloneNested = typia.plain.createClone<Nested>();
|
|
136
|
+
export const eqNestedFactory = typia.compare.createEquals<Nested>();
|
|
137
|
+
export const eqNestedDirect = (x: Nested, y: Nested) =>
|
|
138
|
+
typia.compare.equals<Nested>(x, y);
|
|
139
|
+
|
|
140
|
+
export const eqLiteral = typia.compare.createEquals<
|
|
141
|
+
{ kind: "a"; value: number } | { kind: "b"; value: string }
|
|
142
|
+
>();
|
|
143
|
+
export const eqOptional = typia.compare.createEquals<
|
|
144
|
+
{ a?: number } | { b?: string }
|
|
145
|
+
>();
|
|
146
|
+
export const eqPlain = typia.compare.createEquals<{
|
|
147
|
+
kind: string;
|
|
148
|
+
common: string;
|
|
149
|
+
b?: string;
|
|
150
|
+
}>();
|
|
151
|
+
`
|
|
152
|
+
|
|
153
|
+
const compareTemplateLiteralUnionRuntimeRunner = `const mod = require("./main.cjs");
|
|
154
|
+
|
|
155
|
+
let failures = 0;
|
|
156
|
+
const expect = (label, actual, expected) => {
|
|
157
|
+
if (actual !== expected) {
|
|
158
|
+
console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
|
|
159
|
+
failures++;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const expectJson = (label, actual, expected) =>
|
|
163
|
+
expect(label, JSON.stringify(actual), JSON.stringify(expected));
|
|
164
|
+
|
|
165
|
+
const left = { kind: "b_x", common: "same", b: "left" };
|
|
166
|
+
const right = { kind: "b_x", common: "same", b: "right" };
|
|
167
|
+
expect("is left b member", mod.isTemplate(left), true);
|
|
168
|
+
expect("is right b member", mod.isTemplate(right), true);
|
|
169
|
+
expectJson("clone left preserves b", mod.cloneTemplate(left), left);
|
|
170
|
+
expectJson("clone right preserves b", mod.cloneTemplate(right), right);
|
|
171
|
+
expect("factory different b", mod.eqTemplateFactory(left, right), false);
|
|
172
|
+
expect("direct different b", mod.eqTemplateDirect(left, right), false);
|
|
173
|
+
|
|
174
|
+
expect("factory equal b", mod.eqTemplateFactory(
|
|
175
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
176
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
177
|
+
), true);
|
|
178
|
+
expect("direct equal b", mod.eqTemplateDirect(
|
|
179
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
180
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
181
|
+
), true);
|
|
182
|
+
expect("a member different common", mod.eqTemplateFactory(
|
|
183
|
+
{ kind: "a_x", common: "left" },
|
|
184
|
+
{ kind: "a_x", common: "right" },
|
|
185
|
+
), false);
|
|
186
|
+
expect("a member equal", mod.eqTemplateFactory(
|
|
187
|
+
{ kind: "a_x", common: "same" },
|
|
188
|
+
{ kind: "a_x", common: "same" },
|
|
189
|
+
), true);
|
|
190
|
+
expect("a versus b", mod.eqTemplateFactory(
|
|
191
|
+
{ kind: "a_x", common: "same" },
|
|
192
|
+
{ kind: "b_x", common: "same" },
|
|
193
|
+
), false);
|
|
194
|
+
|
|
195
|
+
const invalidLeft = { kind: "c_x", common: "same" };
|
|
196
|
+
const invalidRight = { kind: "c_x", common: "same" };
|
|
197
|
+
expect("is rejects invalid discriminator", mod.isTemplate(invalidLeft), false);
|
|
198
|
+
expect("factory rejects invalid discriminator", mod.eqTemplateFactory(invalidLeft, invalidRight), false);
|
|
199
|
+
expect("direct rejects invalid discriminator", mod.eqTemplateDirect(invalidLeft, invalidRight), false);
|
|
200
|
+
|
|
201
|
+
const nestedLeft = { value: left };
|
|
202
|
+
const nestedRight = { value: right };
|
|
203
|
+
expect("nested is left", mod.isNested(nestedLeft), true);
|
|
204
|
+
expect("nested is right", mod.isNested(nestedRight), true);
|
|
205
|
+
expectJson("nested clone left preserves b", mod.cloneNested(nestedLeft), nestedLeft);
|
|
206
|
+
expectJson("nested clone right preserves b", mod.cloneNested(nestedRight), nestedRight);
|
|
207
|
+
expect("nested factory different b", mod.eqNestedFactory(nestedLeft, nestedRight), false);
|
|
208
|
+
expect("nested direct different b", mod.eqNestedDirect(nestedLeft, nestedRight), false);
|
|
209
|
+
expect("nested factory equal b", mod.eqNestedFactory(
|
|
210
|
+
{ value: { kind: "b_x", common: "same", b: "same" } },
|
|
211
|
+
{ value: { kind: "b_x", common: "same", b: "same" } },
|
|
212
|
+
), true);
|
|
213
|
+
expect("nested invalid discriminator", mod.eqNestedFactory(
|
|
214
|
+
{ value: invalidLeft },
|
|
215
|
+
{ value: invalidRight },
|
|
216
|
+
), false);
|
|
217
|
+
|
|
218
|
+
expect("literal member different", mod.eqLiteral(
|
|
219
|
+
{ kind: "a", value: 1 },
|
|
220
|
+
{ kind: "a", value: 2 },
|
|
221
|
+
), false);
|
|
222
|
+
expect("literal cross member", mod.eqLiteral(
|
|
223
|
+
{ kind: "a", value: 1 },
|
|
224
|
+
{ kind: "b", value: "1" },
|
|
225
|
+
), false);
|
|
226
|
+
expect("optional member different", mod.eqOptional({ a: 1 }, { a: 2 }), false);
|
|
227
|
+
expect("optional second payload follows first match", mod.eqOptional({ b: "left" }, { b: "right" }), true);
|
|
228
|
+
expect("plain different", mod.eqPlain(
|
|
229
|
+
{ kind: "b_x", common: "same", b: "left" },
|
|
230
|
+
{ kind: "b_x", common: "same", b: "right" },
|
|
231
|
+
), false);
|
|
232
|
+
expect("plain equal", mod.eqPlain(
|
|
233
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
234
|
+
{ kind: "b_x", common: "same", b: "same" },
|
|
235
|
+
), true);
|
|
236
|
+
|
|
237
|
+
if (failures > 0) {
|
|
238
|
+
throw new Error(failures + " assertion(s) failed");
|
|
239
|
+
}
|
|
240
|
+
console.log("all compare template-literal union cases passed");
|
|
241
|
+
`
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestCompareUnionDiscriminationTransform pins compare.equals over a union of
|
|
11
|
+
// object types (issue #2214).
|
|
12
|
+
//
|
|
13
|
+
// CompareEqualProgrammer.schema assembled an object union as a flat OR of member
|
|
14
|
+
// comparators (`_eo0(x,y) || _eo1(x,y) || ...`) with no discrimination. A wrong
|
|
15
|
+
// member's comparator matched spuriously: its constant discriminant passed via
|
|
16
|
+
// the always-prepended `x.type === y.type` branch (both agree, even when neither
|
|
17
|
+
// is that member) and its absent payload keys compared `undefined === undefined`.
|
|
18
|
+
// So `equals({type:"a",x:1}, {type:"a",x:2})` was `true` for two distinct
|
|
19
|
+
// references. Every other object-union programmer (is/clone/classify/prune/json/
|
|
20
|
+
// notations/protobuf) discriminates so a member comparator only runs for the
|
|
21
|
+
// member both values actually are. `equals` must do the same: decide which member
|
|
22
|
+
// each operand is, return false if they differ, and compare within the one shared
|
|
23
|
+
// member — and must agree with `is` on membership.
|
|
24
|
+
//
|
|
25
|
+
// All fixtures compare DISTINCT references (fresh object literals) so the
|
|
26
|
+
// `x === y` identity fast path never hides the flaw.
|
|
27
|
+
//
|
|
28
|
+
// 1. Transform is + compare.createEquals over discriminated, non-discriminated
|
|
29
|
+
// disjoint, narrower-masks-wider, 3-member, array/union-member, and nested
|
|
30
|
+
// object unions, plus primitive/array-union and non-union controls.
|
|
31
|
+
// 2. Require distinct-but-different pairs to compare not-equal, distinct-but-
|
|
32
|
+
// identical pairs to compare equal, and equals to imply is on both operands.
|
|
33
|
+
// 3. Require primitive/array unions and non-union objects to be unchanged.
|
|
34
|
+
func TestCompareUnionDiscriminationTransform(t *testing.T) {
|
|
35
|
+
project := compareUnionDiscriminationProject(t)
|
|
36
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
37
|
+
return runTransform([]string{
|
|
38
|
+
"--cwd", project,
|
|
39
|
+
"--tsconfig", "tsconfig.json",
|
|
40
|
+
"--file", "src/main.ts",
|
|
41
|
+
"--output", "js",
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
if code != 0 {
|
|
45
|
+
t.Fatalf("compare union discrimination transform failed: code=%d stderr=\n%s", code, errText)
|
|
46
|
+
}
|
|
47
|
+
compareUnionDiscriminationRunRuntimeCases(t, project, out)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func compareUnionDiscriminationProject(t *testing.T) string {
|
|
51
|
+
t.Helper()
|
|
52
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
53
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
54
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
55
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
56
|
+
}
|
|
57
|
+
dir, err := os.MkdirTemp(base, "compare-union-disc-")
|
|
58
|
+
if err != nil {
|
|
59
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
60
|
+
}
|
|
61
|
+
t.Cleanup(func() {
|
|
62
|
+
_ = os.RemoveAll(dir)
|
|
63
|
+
})
|
|
64
|
+
src := filepath.Join(dir, "src")
|
|
65
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
66
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
67
|
+
}
|
|
68
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareUnionDiscriminationTSConfig), 0o644); err != nil {
|
|
69
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
70
|
+
}
|
|
71
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareUnionDiscriminationSource), 0o644); err != nil {
|
|
72
|
+
t.Fatalf("write source: %v", err)
|
|
73
|
+
}
|
|
74
|
+
return dir
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func compareUnionDiscriminationRunRuntimeCases(t *testing.T, project string, js string) {
|
|
78
|
+
t.Helper()
|
|
79
|
+
node, err := exec.LookPath("node")
|
|
80
|
+
if err != nil {
|
|
81
|
+
t.Skip("node executable not found")
|
|
82
|
+
}
|
|
83
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
84
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
85
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
86
|
+
}
|
|
87
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
88
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
89
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
90
|
+
t.Fatalf("write runtime module: %v", err)
|
|
91
|
+
}
|
|
92
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
93
|
+
if err := os.WriteFile(runner, []byte(compareUnionDiscriminationRuntimeRunner), 0o644); err != nil {
|
|
94
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
95
|
+
}
|
|
96
|
+
cmd := exec.Command(node, runner)
|
|
97
|
+
cmd.Dir = runtimeDir
|
|
98
|
+
output, err := cmd.CombinedOutput()
|
|
99
|
+
if err != nil {
|
|
100
|
+
t.Fatalf("compare union discrimination runtime cases failed: %v\n%s", err, output)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const compareUnionDiscriminationTSConfig = `{
|
|
105
|
+
"compilerOptions": {
|
|
106
|
+
"target": "ES2022",
|
|
107
|
+
"module": "commonjs",
|
|
108
|
+
"moduleResolution": "bundler",
|
|
109
|
+
"ignoreDeprecations": "6.0",
|
|
110
|
+
"types": ["*"],
|
|
111
|
+
"esModuleInterop": true,
|
|
112
|
+
"strict": true,
|
|
113
|
+
"skipLibCheck": true
|
|
114
|
+
},
|
|
115
|
+
"include": ["src"]
|
|
116
|
+
}
|
|
117
|
+
`
|
|
118
|
+
|
|
119
|
+
const compareUnionDiscriminationSource = `import typia from "typia";
|
|
120
|
+
|
|
121
|
+
// 1. discriminated union
|
|
122
|
+
type Disc = { type: "a"; x: number } | { type: "b"; y: string };
|
|
123
|
+
export const isDisc = typia.createIs<Disc>();
|
|
124
|
+
export const eqDisc = typia.compare.createEquals<Disc>();
|
|
125
|
+
|
|
126
|
+
// 2. non-discriminated union with disjoint keys
|
|
127
|
+
type Disjoint = { x: number } | { y: string };
|
|
128
|
+
export const isDisjoint = typia.createIs<Disjoint>();
|
|
129
|
+
export const eqDisjoint = typia.compare.createEquals<Disjoint>();
|
|
130
|
+
|
|
131
|
+
// 3. narrower-masks-wider
|
|
132
|
+
type Mask = { a: number } | { a: number; b: string };
|
|
133
|
+
export const isMask = typia.createIs<Mask>();
|
|
134
|
+
export const eqMask = typia.compare.createEquals<Mask>();
|
|
135
|
+
|
|
136
|
+
// 4. three-member discriminated union
|
|
137
|
+
type Three =
|
|
138
|
+
| { type: "a"; x: number }
|
|
139
|
+
| { type: "b"; y: string }
|
|
140
|
+
| { type: "c"; z: boolean };
|
|
141
|
+
export const isThree = typia.createIs<Three>();
|
|
142
|
+
export const eqThree = typia.compare.createEquals<Three>();
|
|
143
|
+
|
|
144
|
+
// 5. a member whose payload is itself an array / element union
|
|
145
|
+
type ArrMember =
|
|
146
|
+
| { kind: "multi"; values: (number | string)[] }
|
|
147
|
+
| { kind: "single"; value: number };
|
|
148
|
+
export const isArrMember = typia.createIs<ArrMember>();
|
|
149
|
+
export const eqArrMember = typia.compare.createEquals<ArrMember>();
|
|
150
|
+
|
|
151
|
+
// 6. nested object-union property
|
|
152
|
+
type Nested = { wrap: { type: "a"; x: number } | { type: "b"; y: string } };
|
|
153
|
+
export const isNested = typia.createIs<Nested>();
|
|
154
|
+
export const eqNested = typia.compare.createEquals<Nested>();
|
|
155
|
+
|
|
156
|
+
// 7. recursive discriminated union (exercises _vctx capture through the IIFE)
|
|
157
|
+
type Tree =
|
|
158
|
+
| { type: "leaf"; value: number }
|
|
159
|
+
| { type: "node"; left: Tree; right: Tree };
|
|
160
|
+
export const isTree = typia.createIs<Tree>();
|
|
161
|
+
export const eqTree = typia.compare.createEquals<Tree>();
|
|
162
|
+
|
|
163
|
+
// 8. native alongside a discriminated object union (notNatives guard + ladder)
|
|
164
|
+
type WithNative = Date | { kind: "a"; x: number } | { kind: "b"; y: string };
|
|
165
|
+
export const eqWithNative = typia.compare.createEquals<WithNative>();
|
|
166
|
+
|
|
167
|
+
// control: a native unioned with a SINGLE object keeps the flat guarded branch
|
|
168
|
+
type DateOrStamp = Date | { timestamp: number };
|
|
169
|
+
export const eqDateStamp = typia.compare.createEquals<DateOrStamp>();
|
|
170
|
+
|
|
171
|
+
// controls: primitive union, array union, non-union object
|
|
172
|
+
export const eqPrim = typia.compare.createEquals<string | number>();
|
|
173
|
+
export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
|
|
174
|
+
export const eqObj = typia.compare.createEquals<{ a: number; b: string }>();
|
|
175
|
+
`
|
|
176
|
+
|
|
177
|
+
const compareUnionDiscriminationRuntimeRunner = `const mod = require("./main.cjs");
|
|
178
|
+
|
|
179
|
+
let failures = 0;
|
|
180
|
+
const expect = (label, actual, expected) => {
|
|
181
|
+
if (actual !== expected) {
|
|
182
|
+
console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
|
|
183
|
+
failures++;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// --- 1. discriminated union: {type:"a";x} | {type:"b";y} ---
|
|
188
|
+
expect("disc a distinct-different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
189
|
+
expect("disc b distinct-different", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
|
|
190
|
+
expect("disc a distinct-identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
|
|
191
|
+
expect("disc b distinct-identical", mod.eqDisc({ type: "b", y: "p" }, { type: "b", y: "p" }), true);
|
|
192
|
+
expect("disc cross-arm a vs b", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
|
|
193
|
+
|
|
194
|
+
// --- 2. non-discriminated disjoint keys: {x} | {y} ---
|
|
195
|
+
expect("disjoint x distinct-different", mod.eqDisjoint({ x: 1 }, { x: 2 }), false);
|
|
196
|
+
expect("disjoint y distinct-different", mod.eqDisjoint({ y: "p" }, { y: "q" }), false);
|
|
197
|
+
expect("disjoint x distinct-identical", mod.eqDisjoint({ x: 1 }, { x: 1 }), true);
|
|
198
|
+
expect("disjoint cross-arm x vs y", mod.eqDisjoint({ x: 1 }, { y: "p" }), false);
|
|
199
|
+
|
|
200
|
+
// --- 3. narrower-masks-wider: {a} | {a,b} ---
|
|
201
|
+
expect("mask wider distinct-different", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
|
|
202
|
+
expect("mask narrower distinct-identical", mod.eqMask({ a: 1 }, { a: 1 }), true);
|
|
203
|
+
expect("mask wider distinct-identical", mod.eqMask({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
|
|
204
|
+
expect("mask narrower vs wider", mod.eqMask({ a: 1 }, { a: 1, b: "x" }), false);
|
|
205
|
+
|
|
206
|
+
// --- 4. three-member ---
|
|
207
|
+
expect("three a-different", mod.eqThree({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
208
|
+
expect("three b-different", mod.eqThree({ type: "b", y: "p" }, { type: "b", y: "q" }), false);
|
|
209
|
+
expect("three c-different", mod.eqThree({ type: "c", z: true }, { type: "c", z: false }), false);
|
|
210
|
+
expect("three c-identical", mod.eqThree({ type: "c", z: true }, { type: "c", z: true }), true);
|
|
211
|
+
expect("three cross a vs c", mod.eqThree({ type: "a", x: 1 }, { type: "c", z: true }), false);
|
|
212
|
+
|
|
213
|
+
// --- 5. array/element-union member ---
|
|
214
|
+
expect("arrmember multi different length", mod.eqArrMember({ kind: "multi", values: [1, 2] }, { kind: "multi", values: [1] }), false);
|
|
215
|
+
expect("arrmember multi different elem", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "b"] }), false);
|
|
216
|
+
expect("arrmember multi identical", mod.eqArrMember({ kind: "multi", values: [1, "a"] }, { kind: "multi", values: [1, "a"] }), true);
|
|
217
|
+
expect("arrmember single different", mod.eqArrMember({ kind: "single", value: 1 }, { kind: "single", value: 2 }), false);
|
|
218
|
+
expect("arrmember cross multi vs single", mod.eqArrMember({ kind: "multi", values: [1] }, { kind: "single", value: 1 }), false);
|
|
219
|
+
|
|
220
|
+
// --- 6. nested object-union property ---
|
|
221
|
+
expect("nested inner different", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 2 } }), false);
|
|
222
|
+
expect("nested inner identical", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "a", x: 1 } }), true);
|
|
223
|
+
expect("nested cross arm", mod.eqNested({ wrap: { type: "a", x: 1 } }, { wrap: { type: "b", y: "p" } }), false);
|
|
224
|
+
|
|
225
|
+
// --- controls: primitive / array unions, non-union object ---
|
|
226
|
+
expect("prim number-different", mod.eqPrim(1, 2), false);
|
|
227
|
+
expect("prim string-identical", mod.eqPrim("x", "x"), true);
|
|
228
|
+
expect("prim cross string vs number", mod.eqPrim("1", 1), false);
|
|
229
|
+
expect("arrunion number-different", mod.eqArrUnion([1, 2], [1, 3]), false);
|
|
230
|
+
expect("arrunion number-identical", mod.eqArrUnion([1, 2], [1, 2]), true);
|
|
231
|
+
expect("arrunion string-identical", mod.eqArrUnion(["a"], ["a"]), true);
|
|
232
|
+
expect("obj different", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "y" }), false);
|
|
233
|
+
expect("obj identical", mod.eqObj({ a: 1, b: "x" }, { a: 1, b: "x" }), true);
|
|
234
|
+
|
|
235
|
+
// --- recursive discriminated union (distinct references throughout) ---
|
|
236
|
+
const mkTree = () => ({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } });
|
|
237
|
+
expect("tree identical", mod.eqTree(mkTree(), mkTree()), true);
|
|
238
|
+
expect("tree leaf value differs", mod.eqTree({ type: "leaf", value: 1 }, { type: "leaf", value: 2 }), false);
|
|
239
|
+
expect("tree deep differs", mod.eqTree(mkTree(), { type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 9 } }), false);
|
|
240
|
+
expect("tree leaf vs node", mod.eqTree({ type: "leaf", value: 1 }, mkTree()), false);
|
|
241
|
+
expect("tree shape differs", mod.eqTree({ type: "node", left: { type: "leaf", value: 1 }, right: { type: "leaf", value: 2 } }, { type: "node", left: { type: "leaf", value: 1 }, right: { type: "node", left: { type: "leaf", value: 2 }, right: { type: "leaf", value: 3 } } }), false);
|
|
242
|
+
|
|
243
|
+
// --- native alongside a discriminated object union ---
|
|
244
|
+
expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
|
|
245
|
+
expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
|
|
246
|
+
expect("withnative obj a different", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 2 }), false);
|
|
247
|
+
expect("withnative obj a identical", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "a", x: 1 }), true);
|
|
248
|
+
expect("withnative date vs obj", mod.eqWithNative(new Date(0), { kind: "a", x: 1 }), false);
|
|
249
|
+
expect("withnative cross arm", mod.eqWithNative({ kind: "a", x: 1 }, { kind: "b", y: "p" }), false);
|
|
250
|
+
|
|
251
|
+
// --- native unioned with a single object (control) ---
|
|
252
|
+
expect("datestamp same date", mod.eqDateStamp(new Date(0), new Date(0)), true);
|
|
253
|
+
expect("datestamp diff date", mod.eqDateStamp(new Date(0), new Date(5000)), false);
|
|
254
|
+
expect("datestamp stamp identical", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 5 }), true);
|
|
255
|
+
expect("datestamp stamp different", mod.eqDateStamp({ timestamp: 5 }, { timestamp: 9 }), false);
|
|
256
|
+
expect("datestamp date vs stamp", mod.eqDateStamp(new Date(0), { timestamp: 0 }), false);
|
|
257
|
+
|
|
258
|
+
// --- equals must imply is on both operands (agree with is) ---
|
|
259
|
+
const discSamples = [
|
|
260
|
+
{ type: "a", x: 1 }, { type: "a", x: 2 }, { type: "b", y: "p" }, { type: "b", y: "q" },
|
|
261
|
+
];
|
|
262
|
+
for (const a of discSamples)
|
|
263
|
+
for (const b of discSamples) {
|
|
264
|
+
// fresh distinct references
|
|
265
|
+
const x = JSON.parse(JSON.stringify(a));
|
|
266
|
+
const y = JSON.parse(JSON.stringify(b));
|
|
267
|
+
if (mod.eqDisc(x, y)) {
|
|
268
|
+
expect("agree-is disc lhs " + JSON.stringify(a), mod.isDisc(x), true);
|
|
269
|
+
expect("agree-is disc rhs " + JSON.stringify(b), mod.isDisc(y), true);
|
|
270
|
+
// equal implies structurally same JSON
|
|
271
|
+
expect("equal implies same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const maskSamples = [{ a: 1 }, { a: 1, b: "x" }, { a: 1, b: "y" }, { a: 2 }];
|
|
276
|
+
for (const a of maskSamples)
|
|
277
|
+
for (const b of maskSamples) {
|
|
278
|
+
const x = JSON.parse(JSON.stringify(a));
|
|
279
|
+
const y = JSON.parse(JSON.stringify(b));
|
|
280
|
+
if (mod.eqMask(x, y)) {
|
|
281
|
+
expect("agree-is mask same json " + JSON.stringify(a) + "|" + JSON.stringify(b), JSON.stringify(x) === JSON.stringify(y), true);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (failures > 0) {
|
|
286
|
+
throw new Error(failures + " assertion(s) failed");
|
|
287
|
+
}
|
|
288
|
+
console.log("all compare-union-discrimination cases passed");
|
|
289
|
+
`
|