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,161 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestCompareNativeObjectOvermatchTransform pins equals/cover over native|object.
|
|
11
|
+
//
|
|
12
|
+
// CompareEqualProgrammer.schema ORs a branch per union member and the object
|
|
13
|
+
// branch (`_eo`) guards only with `typeof === "object" && !Array.isArray`,
|
|
14
|
+
// which a native instance also passes. For `Date | { timestamp: number }` the
|
|
15
|
+
// object branch compares two Dates by the absent `timestamp` key — both
|
|
16
|
+
// `undefined`, so it reports them equal, and the OR accepts even though the
|
|
17
|
+
// Date branch (comparing getTime) correctly said not-equal. The object branch
|
|
18
|
+
// must never claim a value a sibling native branch owns. This test drives Date,
|
|
19
|
+
// Uint8Array, and RegExp unioned with an object, in both orders, and requires
|
|
20
|
+
// two different natives to compare not-equal while every legitimate pair and
|
|
21
|
+
// the native-alone / object-alone controls are unchanged.
|
|
22
|
+
//
|
|
23
|
+
// 1. Transform equals/cover factories over native|object and object|native.
|
|
24
|
+
// 2. Require two different natives to compare not-equal (equals and cover).
|
|
25
|
+
// 3. Require same natives, plain-object pairs, and the native-alone control
|
|
26
|
+
// to keep their correct equal / not-equal results.
|
|
27
|
+
func TestCompareNativeObjectOvermatchTransform(t *testing.T) {
|
|
28
|
+
project := compareNativeObjectOvermatchProject(t)
|
|
29
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
30
|
+
return runTransform([]string{
|
|
31
|
+
"--cwd", project,
|
|
32
|
+
"--tsconfig", "tsconfig.json",
|
|
33
|
+
"--file", "src/main.ts",
|
|
34
|
+
"--output", "js",
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
if code != 0 {
|
|
38
|
+
t.Fatalf("compare native/object over-match transform failed: code=%d stderr=\n%s", code, errText)
|
|
39
|
+
}
|
|
40
|
+
compareNativeObjectOvermatchRunRuntimeCases(t, project, out)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func compareNativeObjectOvermatchProject(t *testing.T) string {
|
|
44
|
+
t.Helper()
|
|
45
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
46
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
47
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
48
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
49
|
+
}
|
|
50
|
+
dir, err := os.MkdirTemp(base, "compare-native-object-")
|
|
51
|
+
if err != nil {
|
|
52
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
53
|
+
}
|
|
54
|
+
t.Cleanup(func() {
|
|
55
|
+
_ = os.RemoveAll(dir)
|
|
56
|
+
})
|
|
57
|
+
src := filepath.Join(dir, "src")
|
|
58
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
59
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
60
|
+
}
|
|
61
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareNativeObjectOvermatchTSConfig), 0o644); err != nil {
|
|
62
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
63
|
+
}
|
|
64
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareNativeObjectOvermatchSource), 0o644); err != nil {
|
|
65
|
+
t.Fatalf("write source: %v", err)
|
|
66
|
+
}
|
|
67
|
+
return dir
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func compareNativeObjectOvermatchRunRuntimeCases(t *testing.T, project string, js string) {
|
|
71
|
+
t.Helper()
|
|
72
|
+
node, err := exec.LookPath("node")
|
|
73
|
+
if err != nil {
|
|
74
|
+
t.Skip("node executable not found")
|
|
75
|
+
}
|
|
76
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
77
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
78
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
79
|
+
}
|
|
80
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
81
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
82
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
83
|
+
t.Fatalf("write runtime module: %v", err)
|
|
84
|
+
}
|
|
85
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
86
|
+
if err := os.WriteFile(runner, []byte(compareNativeObjectOvermatchRuntimeRunner), 0o644); err != nil {
|
|
87
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
88
|
+
}
|
|
89
|
+
cmd := exec.Command(node, runner)
|
|
90
|
+
cmd.Dir = runtimeDir
|
|
91
|
+
output, err := cmd.CombinedOutput()
|
|
92
|
+
if err != nil {
|
|
93
|
+
t.Fatalf("compare native/object over-match runtime cases failed: %v\n%s", err, output)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const compareNativeObjectOvermatchTSConfig = `{
|
|
98
|
+
"compilerOptions": {
|
|
99
|
+
"target": "ES2022",
|
|
100
|
+
"module": "commonjs",
|
|
101
|
+
"moduleResolution": "bundler",
|
|
102
|
+
"ignoreDeprecations": "6.0",
|
|
103
|
+
"types": ["*"],
|
|
104
|
+
"esModuleInterop": true,
|
|
105
|
+
"strict": true,
|
|
106
|
+
"skipLibCheck": true
|
|
107
|
+
},
|
|
108
|
+
"include": ["src"]
|
|
109
|
+
}
|
|
110
|
+
`
|
|
111
|
+
|
|
112
|
+
const compareNativeObjectOvermatchSource = `import typia, { compare } from "typia";
|
|
113
|
+
|
|
114
|
+
interface IStamp {
|
|
115
|
+
timestamp: number;
|
|
116
|
+
}
|
|
117
|
+
interface ISource {
|
|
118
|
+
source: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const equalDateObj = typia.compare.createEquals<Date | IStamp>();
|
|
122
|
+
export const coverDateObj = typia.compare.createCover<Date | IStamp>();
|
|
123
|
+
export const equalObjDate = typia.compare.createEquals<IStamp | Date>();
|
|
124
|
+
export const equalBytesObj = typia.compare.createEquals<Uint8Array | IStamp>();
|
|
125
|
+
export const equalRegExpObj = typia.compare.createEquals<RegExp | ISource>();
|
|
126
|
+
|
|
127
|
+
// controls: the native alone and the object alone must be unchanged.
|
|
128
|
+
export const equalDate = typia.compare.createEquals<Date>();
|
|
129
|
+
export const equalStamp = typia.compare.createEquals<IStamp>();
|
|
130
|
+
`
|
|
131
|
+
|
|
132
|
+
const compareNativeObjectOvermatchRuntimeRunner = `const mod = require("./main.cjs");
|
|
133
|
+
|
|
134
|
+
const expect = (label, actual, expected) => {
|
|
135
|
+
if (actual !== expected) {
|
|
136
|
+
throw new Error(label + ": expected " + expected + ", got " + actual);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Two different natives must NOT be reported equal by the object branch.
|
|
141
|
+
expect("Date|obj: two different Dates equal", mod.equalDateObj(new Date(0), new Date(5000)), false);
|
|
142
|
+
expect("Date|obj: cover two different Dates", mod.coverDateObj(new Date(0), new Date(5000)), false);
|
|
143
|
+
expect("obj|Date: two different Dates equal", mod.equalObjDate(new Date(0), new Date(5000)), false);
|
|
144
|
+
expect("Bytes|obj: different bytes equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([9, 9, 9])), false);
|
|
145
|
+
expect("Bytes|obj: one-byte diff equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4])), false);
|
|
146
|
+
expect("RegExp|obj: same source diff flags equal", mod.equalRegExpObj(/a/g, /a/i), false);
|
|
147
|
+
|
|
148
|
+
// Legitimate equal cases must be preserved.
|
|
149
|
+
expect("Date|obj: same Date equal", mod.equalDateObj(new Date(0), new Date(0)), true);
|
|
150
|
+
expect("Date|obj: cover same Date", mod.coverDateObj(new Date(0), new Date(0)), true);
|
|
151
|
+
expect("Date|obj: stamp object equal", mod.equalDateObj({ timestamp: 5 }, { timestamp: 5 }), true);
|
|
152
|
+
expect("Date|obj: stamp object not equal", mod.equalDateObj({ timestamp: 5 }, { timestamp: 9 }), false);
|
|
153
|
+
expect("Bytes|obj: same bytes equal", mod.equalBytesObj(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])), true);
|
|
154
|
+
expect("RegExp|obj: identical regexp equal", mod.equalRegExpObj(/a/g, /a/g), true);
|
|
155
|
+
|
|
156
|
+
// Controls: native alone and object alone are unchanged.
|
|
157
|
+
expect("control Date: equal", mod.equalDate(new Date(0), new Date(0)), true);
|
|
158
|
+
expect("control Date: not equal", mod.equalDate(new Date(0), new Date(5000)), false);
|
|
159
|
+
expect("control Stamp: equal", mod.equalStamp({ timestamp: 5 }, { timestamp: 5 }), true);
|
|
160
|
+
expect("control Stamp: not equal", mod.equalStamp({ timestamp: 5 }, { timestamp: 9 }), false);
|
|
161
|
+
`
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"os/exec"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestCompareNonDiscriminableUnionTransform pins compare.equals over an object
|
|
12
|
+
// union no discriminant can split (issue #2225).
|
|
13
|
+
//
|
|
14
|
+
// #2214 discriminated the object unions UnionPredicator can specialize, but left
|
|
15
|
+
// every other object union on the pre-#2214 flat OR of member comparators.
|
|
16
|
+
// UnionPredicator.Object skips a key that is not required, so a union whose
|
|
17
|
+
// distinguishing keys are all optional (`{ a?: number } | { b?: string }`)
|
|
18
|
+
// produced no specialization and always took that fallback — which is the very
|
|
19
|
+
// defect #2214 removed: the wrong member's comparator matches because the keys
|
|
20
|
+
// it declares are absent from both operands and compare `undefined ===
|
|
21
|
+
// undefined`, while the keys that actually differ are not declared by that
|
|
22
|
+
// member at all. So `equals({ a: 1 }, { a: 2 })` and even `equals({ a: 1 }, {})`
|
|
23
|
+
// were `true` for distinct references.
|
|
24
|
+
//
|
|
25
|
+
// The fix routes such a union through the first-is-match ladder that
|
|
26
|
+
// clone/classify/prune reach via Decode_union_object: each operand resolves to
|
|
27
|
+
// the first member it structurally matches, distinct members compare false, and
|
|
28
|
+
// a shared member's comparator decides the rest. `equals` therefore agrees with
|
|
29
|
+
// what `clone` produces for the same value.
|
|
30
|
+
//
|
|
31
|
+
// All fixtures compare DISTINCT references (fresh object literals) so the
|
|
32
|
+
// `x === y` identity fast path never hides the flaw.
|
|
33
|
+
//
|
|
34
|
+
// 1. Transform is + compare.createEquals + plain.createClone over
|
|
35
|
+
// all-optional, shared-optional-key, three-member, empty-member,
|
|
36
|
+
// discriminable/non-discriminable mixed, nested, recursive, container-valued
|
|
37
|
+
// and native-bearing non-discriminable unions.
|
|
38
|
+
// 2. Require distinct-but-different values to compare not-equal (a populated
|
|
39
|
+
// object never equals `{}`), distinct-but-identical values to compare equal.
|
|
40
|
+
// 3. Require `equals` to agree with `clone` over every ordered sample pair of
|
|
41
|
+
// `is`-valid values, and to be false whenever either operand fails `is`.
|
|
42
|
+
func TestCompareNonDiscriminableUnionTransform(t *testing.T) {
|
|
43
|
+
project := compareNonDiscriminableUnionProject(t)
|
|
44
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
45
|
+
return runTransform([]string{
|
|
46
|
+
"--cwd", project,
|
|
47
|
+
"--tsconfig", "tsconfig.json",
|
|
48
|
+
"--file", "src/main.ts",
|
|
49
|
+
"--output", "js",
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
if code != 0 {
|
|
53
|
+
t.Fatalf("compare non-discriminable union transform failed: code=%d stderr=\n%s", code, errText)
|
|
54
|
+
}
|
|
55
|
+
if strings.Contains(out, "_ui0") == false {
|
|
56
|
+
t.Fatalf("expected the is-match member matchers in the emit, got:\n%s", out)
|
|
57
|
+
}
|
|
58
|
+
compareNonDiscriminableUnionRunRuntimeCases(t, project, out)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func compareNonDiscriminableUnionProject(t *testing.T) string {
|
|
62
|
+
t.Helper()
|
|
63
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
64
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
65
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
66
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
67
|
+
}
|
|
68
|
+
dir, err := os.MkdirTemp(base, "compare-union-nondisc-")
|
|
69
|
+
if err != nil {
|
|
70
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
71
|
+
}
|
|
72
|
+
t.Cleanup(func() {
|
|
73
|
+
_ = os.RemoveAll(dir)
|
|
74
|
+
})
|
|
75
|
+
src := filepath.Join(dir, "src")
|
|
76
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
77
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
78
|
+
}
|
|
79
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(compareNonDiscriminableUnionTSConfig), 0o644); err != nil {
|
|
80
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
81
|
+
}
|
|
82
|
+
if err := os.WriteFile(filepath.Join(src, "main.ts"), []byte(compareNonDiscriminableUnionSource), 0o644); err != nil {
|
|
83
|
+
t.Fatalf("write source: %v", err)
|
|
84
|
+
}
|
|
85
|
+
return dir
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func compareNonDiscriminableUnionRunRuntimeCases(t *testing.T, project string, js string) {
|
|
89
|
+
t.Helper()
|
|
90
|
+
node, err := exec.LookPath("node")
|
|
91
|
+
if err != nil {
|
|
92
|
+
t.Skip("node executable not found")
|
|
93
|
+
}
|
|
94
|
+
runtimeDir := filepath.Join(project, "runtime")
|
|
95
|
+
if err := os.MkdirAll(runtimeDir, 0o755); err != nil {
|
|
96
|
+
t.Fatalf("mkdir runtime dir: %v", err)
|
|
97
|
+
}
|
|
98
|
+
ttscTypiaTestWriteCommonRuntimeStubs(t, runtimeDir)
|
|
99
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "throw-type-guard-error-stub.cjs"), []byte(compareNonDiscriminableUnionThrowStub), 0o644); err != nil {
|
|
100
|
+
t.Fatalf("write throw stub: %v", err)
|
|
101
|
+
}
|
|
102
|
+
js = strings.ReplaceAll(js, `require("typia/lib/internal/_throwTypeGuardError")`, `require("./throw-type-guard-error-stub.cjs")`)
|
|
103
|
+
runtimeJS := ttscTypiaTestRewriteCommonJS(t, js)
|
|
104
|
+
if err := os.WriteFile(filepath.Join(runtimeDir, "main.cjs"), []byte(runtimeJS), 0o644); err != nil {
|
|
105
|
+
t.Fatalf("write runtime module: %v", err)
|
|
106
|
+
}
|
|
107
|
+
runner := filepath.Join(runtimeDir, "run.cjs")
|
|
108
|
+
if err := os.WriteFile(runner, []byte(compareNonDiscriminableUnionRuntimeRunner), 0o644); err != nil {
|
|
109
|
+
t.Fatalf("write runtime runner: %v", err)
|
|
110
|
+
}
|
|
111
|
+
cmd := exec.Command(node, runner)
|
|
112
|
+
cmd.Dir = runtimeDir
|
|
113
|
+
output, err := cmd.CombinedOutput()
|
|
114
|
+
if err != nil {
|
|
115
|
+
t.Fatalf("compare non-discriminable union runtime cases failed: %v\n%s", err, output)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const compareNonDiscriminableUnionTSConfig = `{
|
|
120
|
+
"compilerOptions": {
|
|
121
|
+
"target": "ES2022",
|
|
122
|
+
"module": "commonjs",
|
|
123
|
+
"moduleResolution": "bundler",
|
|
124
|
+
"ignoreDeprecations": "6.0",
|
|
125
|
+
"types": ["*"],
|
|
126
|
+
"esModuleInterop": true,
|
|
127
|
+
"strict": true,
|
|
128
|
+
"skipLibCheck": true
|
|
129
|
+
},
|
|
130
|
+
"include": ["src"]
|
|
131
|
+
}
|
|
132
|
+
`
|
|
133
|
+
|
|
134
|
+
const compareNonDiscriminableUnionThrowStub = `module.exports._throwTypeGuardError = (props) => {
|
|
135
|
+
const error = new Error("guard: " + props.expected);
|
|
136
|
+
error.name = "TypeGuardError";
|
|
137
|
+
throw error;
|
|
138
|
+
};
|
|
139
|
+
`
|
|
140
|
+
|
|
141
|
+
const compareNonDiscriminableUnionSource = `import typia from "typia";
|
|
142
|
+
|
|
143
|
+
// 1. the canonical all-optional union: no member has a unique required key
|
|
144
|
+
type Opt = { a?: number } | { b?: string };
|
|
145
|
+
export const isOpt = typia.createIs<Opt>();
|
|
146
|
+
export const eqOpt = typia.compare.createEquals<Opt>();
|
|
147
|
+
export const cloneOpt = typia.plain.createClone<Opt>();
|
|
148
|
+
|
|
149
|
+
// 2. a key shared by both members, still no required discriminant
|
|
150
|
+
type Shared = { a?: number; c?: boolean } | { b?: string; c?: boolean };
|
|
151
|
+
export const isShared = typia.createIs<Shared>();
|
|
152
|
+
export const eqShared = typia.compare.createEquals<Shared>();
|
|
153
|
+
export const cloneShared = typia.plain.createClone<Shared>();
|
|
154
|
+
|
|
155
|
+
// 3. three all-optional members
|
|
156
|
+
type Three = { a?: number } | { b?: string } | { c?: boolean };
|
|
157
|
+
export const isThree = typia.createIs<Three>();
|
|
158
|
+
export const eqThree = typia.compare.createEquals<Three>();
|
|
159
|
+
export const cloneThree = typia.plain.createClone<Three>();
|
|
160
|
+
|
|
161
|
+
// 4. a member that declares nothing, so it matches every object
|
|
162
|
+
type WithEmpty = { a?: number } | { [key: string]: never };
|
|
163
|
+
export const isWithEmpty = typia.createIs<WithEmpty>();
|
|
164
|
+
export const eqWithEmpty = typia.compare.createEquals<WithEmpty>();
|
|
165
|
+
|
|
166
|
+
// 5. a discriminable member alongside a non-discriminable pair
|
|
167
|
+
type Mixed = { type: "a"; x: number } | { p?: number } | { q?: string };
|
|
168
|
+
export const isMixed = typia.createIs<Mixed>();
|
|
169
|
+
export const eqMixed = typia.compare.createEquals<Mixed>();
|
|
170
|
+
export const cloneMixed = typia.plain.createClone<Mixed>();
|
|
171
|
+
|
|
172
|
+
// 6. a nested non-discriminable union property
|
|
173
|
+
type Nested = { wrap: { a?: number } | { b?: string } };
|
|
174
|
+
export const isNested = typia.createIs<Nested>();
|
|
175
|
+
export const eqNested = typia.compare.createEquals<Nested>();
|
|
176
|
+
export const cloneNested = typia.plain.createClone<Nested>();
|
|
177
|
+
|
|
178
|
+
// 7. container-valued members: the array and tuple checks in the matcher are
|
|
179
|
+
// what routes a value, since the two members share their only key
|
|
180
|
+
type Container = { value?: number[] } | { value?: [number, string] };
|
|
181
|
+
export const isContainer = typia.createIs<Container>();
|
|
182
|
+
export const eqContainer = typia.compare.createEquals<Container>();
|
|
183
|
+
export const cloneContainer = typia.plain.createClone<Container>();
|
|
184
|
+
|
|
185
|
+
// 8. a recursive non-discriminable union (matcher must not recurse forever at
|
|
186
|
+
// generation time, and the comparator still receives its _vctx)
|
|
187
|
+
type Rec = { child?: Rec; a?: number } | { b?: string };
|
|
188
|
+
export const isRec = typia.createIs<Rec>();
|
|
189
|
+
export const eqRec = typia.compare.createEquals<Rec>();
|
|
190
|
+
|
|
191
|
+
// 9. a native alongside a non-discriminable object union (notNatives guard)
|
|
192
|
+
type WithNative = Date | { a?: number } | { b?: string };
|
|
193
|
+
export const eqWithNative = typia.compare.createEquals<WithNative>();
|
|
194
|
+
|
|
195
|
+
// controls that must keep the discriminated / flat forms
|
|
196
|
+
export const eqDisc = typia.compare.createEquals<
|
|
197
|
+
{ type: "a"; x: number } | { type: "b"; y: string }
|
|
198
|
+
>();
|
|
199
|
+
export const eqPrim = typia.compare.createEquals<string | number>();
|
|
200
|
+
export const eqArrUnion = typia.compare.createEquals<number[] | string[]>();
|
|
201
|
+
export const eqObj = typia.compare.createEquals<{ a?: number; b?: string }>();
|
|
202
|
+
`
|
|
203
|
+
|
|
204
|
+
const compareNonDiscriminableUnionRuntimeRunner = `const mod = require("./main.cjs");
|
|
205
|
+
|
|
206
|
+
let failures = 0;
|
|
207
|
+
const expect = (label, actual, expected) => {
|
|
208
|
+
if (actual !== expected) {
|
|
209
|
+
console.log("FAIL " + label + ": expected " + expected + ", got " + actual);
|
|
210
|
+
failures++;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const copy = (v) => JSON.parse(JSON.stringify(v));
|
|
214
|
+
// Serialize a clone so that a key the resolved member declares but the value
|
|
215
|
+
// omits stays visible: JSON.stringify drops an undefined-valued key, which would
|
|
216
|
+
// make two members that declare different keys look alike.
|
|
217
|
+
const shape = (v) => JSON.stringify(v, (_key, value) => (value === undefined ? null : value));
|
|
218
|
+
|
|
219
|
+
// --- 1. the reported defect: {a?:number} | {b?:string} ---
|
|
220
|
+
expect("opt a different", mod.eqOpt({ a: 1 }, { a: 2 }), false);
|
|
221
|
+
expect("opt populated vs empty", mod.eqOpt({ a: 1 }, {}), false);
|
|
222
|
+
expect("opt empty vs populated", mod.eqOpt({}, { a: 1 }), false);
|
|
223
|
+
expect("opt cross member", mod.eqOpt({ a: 1 }, { b: "p" }), false);
|
|
224
|
+
expect("opt identical", mod.eqOpt({ a: 1 }, { a: 1 }), true);
|
|
225
|
+
expect("opt both empty", mod.eqOpt({}, {}), true);
|
|
226
|
+
// both values resolve to the first member, under which "b" is not declared:
|
|
227
|
+
// exactly what clone keeps, so equals must agree with clone rather than with
|
|
228
|
+
// the raw literals.
|
|
229
|
+
expect("opt second-member payload follows clone", mod.eqOpt({ b: "p" }, { b: "q" }), JSON.stringify(mod.cloneOpt({ b: "p" })) === JSON.stringify(mod.cloneOpt({ b: "q" })));
|
|
230
|
+
expect("opt member resolution follows clone", mod.eqOpt({}, { a: "x" }), false);
|
|
231
|
+
expect("opt invalid operand", mod.eqOpt({ a: "x", b: 1 }, { a: "x", b: 1 }), false);
|
|
232
|
+
|
|
233
|
+
// --- 2. shared optional key ---
|
|
234
|
+
expect("shared c different", mod.eqShared({ c: true }, { c: false }), false);
|
|
235
|
+
expect("shared c identical", mod.eqShared({ a: 1, c: true }, { a: 1, c: true }), true);
|
|
236
|
+
expect("shared a different", mod.eqShared({ a: 1, c: true }, { a: 2, c: true }), false);
|
|
237
|
+
expect("shared populated vs empty", mod.eqShared({ a: 1 }, {}), false);
|
|
238
|
+
expect("shared c only vs empty", mod.eqShared({ c: true }, {}), false);
|
|
239
|
+
|
|
240
|
+
// --- 3. three all-optional members ---
|
|
241
|
+
expect("three a different", mod.eqThree({ a: 1 }, { a: 2 }), false);
|
|
242
|
+
expect("three populated vs empty", mod.eqThree({ a: 1 }, {}), false);
|
|
243
|
+
expect("three identical", mod.eqThree({ a: 1 }, { a: 1 }), true);
|
|
244
|
+
expect("three cross member", mod.eqThree({ a: 1 }, { c: true }), false);
|
|
245
|
+
|
|
246
|
+
// --- 4. member matching everything ---
|
|
247
|
+
expect("withempty a different", mod.eqWithEmpty({ a: 1 }, { a: 2 }), false);
|
|
248
|
+
expect("withempty populated vs empty", mod.eqWithEmpty({ a: 1 }, {}), false);
|
|
249
|
+
expect("withempty identical", mod.eqWithEmpty({ a: 1 }, { a: 1 }), true);
|
|
250
|
+
|
|
251
|
+
// --- 5. discriminable member beside a non-discriminable pair ---
|
|
252
|
+
expect("mixed disc different", mod.eqMixed({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
253
|
+
expect("mixed disc identical", mod.eqMixed({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
|
|
254
|
+
expect("mixed disc vs optional", mod.eqMixed({ type: "a", x: 1 }, { p: 1 }), false);
|
|
255
|
+
expect("mixed optional different", mod.eqMixed({ p: 1 }, { p: 2 }), false);
|
|
256
|
+
expect("mixed optional vs empty", mod.eqMixed({ p: 1 }, {}), false);
|
|
257
|
+
expect("mixed optional identical", mod.eqMixed({ p: 1 }, { p: 1 }), true);
|
|
258
|
+
|
|
259
|
+
// --- 6. nested non-discriminable union property ---
|
|
260
|
+
expect("nested inner different", mod.eqNested({ wrap: { a: 1 } }, { wrap: { a: 2 } }), false);
|
|
261
|
+
expect("nested inner populated vs empty", mod.eqNested({ wrap: { a: 1 } }, { wrap: {} }), false);
|
|
262
|
+
expect("nested inner identical", mod.eqNested({ wrap: { a: 1 } }, { wrap: { a: 1 } }), true);
|
|
263
|
+
expect("nested cross member", mod.eqNested({ wrap: { a: 1 } }, { wrap: { b: "p" } }), false);
|
|
264
|
+
|
|
265
|
+
// --- 7. container-valued members ---
|
|
266
|
+
expect("container array different", mod.eqContainer({ value: [1, 2] }, { value: [1, 3] }), false);
|
|
267
|
+
expect("container array identical", mod.eqContainer({ value: [1, 2] }, { value: [1, 2] }), true);
|
|
268
|
+
expect("container array vs empty", mod.eqContainer({ value: [1] }, {}), false);
|
|
269
|
+
expect("container tuple different", mod.eqContainer({ value: [1, "p"] }, { value: [1, "q"] }), false);
|
|
270
|
+
expect("container tuple identical", mod.eqContainer({ value: [1, "p"] }, { value: [1, "p"] }), true);
|
|
271
|
+
expect("container cross member", mod.eqContainer({ value: [1] }, { value: [1, "p"] }), false);
|
|
272
|
+
|
|
273
|
+
// --- 8. recursive non-discriminable union ---
|
|
274
|
+
const mkRec = () => ({ a: 1, child: { a: 2, child: { a: 3 } } });
|
|
275
|
+
expect("rec identical", mod.eqRec(mkRec(), mkRec()), true);
|
|
276
|
+
expect("rec deep different", mod.eqRec(mkRec(), { a: 1, child: { a: 2, child: { a: 9 } } }), false);
|
|
277
|
+
expect("rec depth different", mod.eqRec(mkRec(), { a: 1, child: { a: 2 } }), false);
|
|
278
|
+
expect("rec populated vs empty", mod.eqRec(mkRec(), {}), false);
|
|
279
|
+
|
|
280
|
+
// --- 9. native beside the non-discriminable union ---
|
|
281
|
+
expect("withnative same date", mod.eqWithNative(new Date(0), new Date(0)), true);
|
|
282
|
+
expect("withnative diff date", mod.eqWithNative(new Date(0), new Date(5000)), false);
|
|
283
|
+
expect("withnative date vs object", mod.eqWithNative(new Date(0), { a: 1 }), false);
|
|
284
|
+
expect("withnative object different", mod.eqWithNative({ a: 1 }, { a: 2 }), false);
|
|
285
|
+
expect("withnative object identical", mod.eqWithNative({ a: 1 }, { a: 1 }), true);
|
|
286
|
+
expect("withnative populated vs empty", mod.eqWithNative({ a: 1 }, {}), false);
|
|
287
|
+
|
|
288
|
+
// --- controls: the discriminated path and the non-union paths are untouched ---
|
|
289
|
+
expect("disc different", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 2 }), false);
|
|
290
|
+
expect("disc identical", mod.eqDisc({ type: "a", x: 1 }, { type: "a", x: 1 }), true);
|
|
291
|
+
expect("disc cross arm", mod.eqDisc({ type: "a", x: 1 }, { type: "b", y: "p" }), false);
|
|
292
|
+
expect("prim different", mod.eqPrim(1, 2), false);
|
|
293
|
+
expect("prim identical", mod.eqPrim("x", "x"), true);
|
|
294
|
+
expect("arrunion different", mod.eqArrUnion([1, 2], [1, 3]), false);
|
|
295
|
+
expect("arrunion identical", mod.eqArrUnion([1, 2], [1, 2]), true);
|
|
296
|
+
expect("obj optional different", mod.eqObj({ a: 1 }, { a: 2 }), false);
|
|
297
|
+
expect("obj optional vs empty", mod.eqObj({ a: 1 }, {}), false);
|
|
298
|
+
expect("obj optional identical", mod.eqObj({ a: 1 }, { a: 1 }), true);
|
|
299
|
+
|
|
300
|
+
// --- equals agrees with is and with the member clone resolves to ---
|
|
301
|
+
// For every ordered pair of samples (distinct references throughout):
|
|
302
|
+
// * an operand is rejects is never equal to anything, and
|
|
303
|
+
// * two is-valid operands are equal exactly when their clones are, which is
|
|
304
|
+
// the statement "both resolved to the same member and agree on everything
|
|
305
|
+
// that member declares".
|
|
306
|
+
const agree = (label, eq, is, clone, samples) => {
|
|
307
|
+
for (const a of samples)
|
|
308
|
+
for (const b of samples) {
|
|
309
|
+
const x = copy(a);
|
|
310
|
+
const y = copy(b);
|
|
311
|
+
const suffix = " " + JSON.stringify(a) + " | " + JSON.stringify(b);
|
|
312
|
+
if (is(x) === false || is(y) === false) {
|
|
313
|
+
expect(label + " invalid operand not equal" + suffix, eq(x, y), false);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
expect(label + " equals agrees with clone" + suffix, eq(x, y), shape(clone(x)) === shape(clone(y)));
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
agree("opt", mod.eqOpt, mod.isOpt, mod.cloneOpt, [
|
|
321
|
+
{}, { a: 1 }, { a: 2 }, { b: "p" }, { b: "q" }, { a: 1, b: "p" }, { a: "x", b: 1 }, { a: "x" },
|
|
322
|
+
]);
|
|
323
|
+
agree("shared", mod.eqShared, mod.isShared, mod.cloneShared, [
|
|
324
|
+
{}, { a: 1 }, { c: true }, { c: false }, { a: 1, c: true }, { b: "p" }, { b: "p", c: true }, { a: "x", b: 1 },
|
|
325
|
+
]);
|
|
326
|
+
agree("three", mod.eqThree, mod.isThree, mod.cloneThree, [
|
|
327
|
+
{}, { a: 1 }, { b: "p" }, { c: true }, { c: false }, { a: 1, c: true }, { a: "x", b: 1, c: 2 },
|
|
328
|
+
]);
|
|
329
|
+
agree("mixed", mod.eqMixed, mod.isMixed, mod.cloneMixed, [
|
|
330
|
+
{}, { type: "a", x: 1 }, { type: "a", x: 2 }, { p: 1 }, { p: 2 }, { q: "z" },
|
|
331
|
+
]);
|
|
332
|
+
agree("nested", mod.eqNested, mod.isNested, mod.cloneNested, [
|
|
333
|
+
{ wrap: {} }, { wrap: { a: 1 } }, { wrap: { a: 2 } }, { wrap: { b: "p" } },
|
|
334
|
+
]);
|
|
335
|
+
agree("container", mod.eqContainer, mod.isContainer, mod.cloneContainer, [
|
|
336
|
+
{}, { value: [] }, { value: [1] }, { value: [1, 2] }, { value: [1, "p"] }, { value: [2, "p"] },
|
|
337
|
+
]);
|
|
338
|
+
|
|
339
|
+
if (failures > 0) {
|
|
340
|
+
throw new Error(failures + " assertion(s) failed");
|
|
341
|
+
}
|
|
342
|
+
console.log("all compare-non-discriminable-union cases passed");
|
|
343
|
+
`
|