typia 13.3.0 → 14.0.1
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/lib/internal/_createStandardSchema.d.ts +1 -2
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_randomPattern.js +20 -3
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +5 -1
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.js +9 -2
- package/lib/internal/_randomStringLength.js.map +1 -1
- package/lib/internal/_randomStringLength.mjs +3 -1
- package/lib/internal/_randomStringLength.mjs.map +1 -1
- package/lib/module.d.ts +1 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/re-exports.d.ts +1 -1
- package/lib/re-exports.js.map +1 -1
- package/lib/transform.mjs +1 -1
- package/native/cmd/ttsc-typia/create_assert_error_factory_arity_test.go +5 -2
- package/native/cmd/ttsc-typia/dependency_collector_virtual_scheme_test.go +52 -0
- package/native/cmd/ttsc-typia/dynamic_key_tags_transform_test.go +206 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +2 -2
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +84 -85
- package/native/cmd/ttsc-typia/project_dependencies_callee_argument_transform_test.go +177 -0
- package/native/cmd/ttsc-typia/project_dependencies_callee_barrel_transform_test.go +115 -0
- package/native/cmd/ttsc-typia/project_dependencies_callee_inference_transform_test.go +285 -0
- package/native/cmd/ttsc-typia/project_dependencies_callee_shape_transform_test.go +117 -0
- package/native/cmd/ttsc-typia/project_dependencies_callee_untransformed_barrel_transform_test.go +121 -0
- package/native/cmd/ttsc-typia/project_dependencies_complete_diagnostic_transform_test.go +116 -0
- package/native/cmd/ttsc-typia/project_dependencies_complete_envelope_transform_test.go +115 -0
- package/native/cmd/ttsc-typia/project_dependencies_complete_inferred_type_transform_test.go +127 -0
- package/native/cmd/ttsc-typia/project_dependencies_complete_replaced_library_transform_test.go +153 -0
- package/native/cmd/ttsc-typia/project_dependencies_complete_untouched_reprint_transform_test.go +155 -0
- package/native/cmd/ttsc-typia/project_dependencies_computed_key_transform_test.go +218 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +6 -5
- package/native/cmd/ttsc-typia/project_dependencies_enum_member_value_transform_test.go +131 -0
- package/native/cmd/ttsc-typia/project_dependencies_inferred_declaration_transform_test.go +159 -0
- package/native/cmd/ttsc-typia/project_dependencies_jsdoc_typedef_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_named_tuple_member_transform_test.go +123 -0
- package/native/cmd/ttsc-typia/project_dependencies_qualified_barrel_transform_test.go +141 -0
- package/native/cmd/ttsc-typia/project_dependencies_type_parameter_default_transform_test.go +127 -0
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +195 -21
- package/native/cmd/ttsc-typia/transform_helpers_test.go +12 -0
- package/native/core/factories/MetadataCommentTagFactory.go +96 -27
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +2 -2
- package/native/core/factories/metadata_comment_tag_factory_rejects_out_of_range_integer_test.go +124 -0
- package/native/core/programmers/AssertProgrammer.go +20 -6
- package/native/core/programmers/RandomProgrammer.go +78 -6
- package/native/core/programmers/ValidateProgrammer.go +21 -6
- package/native/core/programmers/helpers/RandomJoiner.go +8 -1
- package/native/core/programmers/iterate/check_dynamic_properties.go +177 -3
- package/native/core/programmers/iterate/check_object.go +12 -1
- package/native/core/schemas/metadata/MetadataDependency.go +613 -30
- package/native/transform/CallExpressionTransformer.go +16 -1
- package/package.json +4 -14
- package/src/internal/_createStandardSchema.ts +1 -2
- package/src/internal/_randomPattern.ts +18 -3
- package/src/internal/_randomStringLength.ts +9 -2
- package/src/module.ts +6 -2
- package/src/re-exports.ts +13 -0
- package/lib/executable/FileSystemIdentity.d.ts +0 -44
- package/lib/executable/FileSystemIdentity.js +0 -213
- package/lib/executable/FileSystemIdentity.js.map +0 -1
- package/lib/executable/FileSystemIdentity.mjs +0 -133
- package/lib/executable/FileSystemIdentity.mjs.map +0 -1
- package/lib/executable/TypiaGenerateWizard.d.ts +0 -9
- package/lib/executable/TypiaGenerateWizard.js +0 -852
- package/lib/executable/TypiaGenerateWizard.js.map +0 -1
- package/lib/executable/TypiaGenerateWizard.mjs +0 -618
- package/lib/executable/TypiaGenerateWizard.mjs.map +0 -1
- package/lib/executable/generate/ttsc.d.ts +0 -1
- package/lib/executable/generate/ttsc.js +0 -53
- package/lib/executable/generate/ttsc.js.map +0 -1
- package/lib/executable/generate/ttsc.mjs +0 -37
- package/lib/executable/generate/ttsc.mjs.map +0 -1
- package/lib/executable/typia.d.ts +0 -2
- package/lib/executable/typia.js +0 -84
- package/lib/executable/typia.js.map +0 -1
- package/lib/executable/typia.mjs +0 -60
- package/lib/executable/typia.mjs.map +0 -1
- package/src/executable/FileSystemIdentity.ts +0 -222
- package/src/executable/TypiaGenerateWizard.ts +0 -1133
- package/src/executable/generate/ttsc.ts +0 -70
- package/src/executable/typia.ts +0 -80
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestProjectDependenciesNamedTupleMemberTransform verifies a named tuple
|
|
11
|
+
// member's written type reaches the reported dependencies, and that the file
|
|
12
|
+
// consulting it is still declared complete.
|
|
13
|
+
//
|
|
14
|
+
// `[id: Id]` writes its type as plainly as a property annotation does, and the
|
|
15
|
+
// checker interns `type Id = string` as the bare intrinsic, so the written
|
|
16
|
+
// surface is the only thing that can register `id.ts` (samchon/typia#2126). The
|
|
17
|
+
// member is a declaration kind of its own, so it needs its own place in both the
|
|
18
|
+
// surface that walks a written type and the predicate that decides whether a
|
|
19
|
+
// file may be declared on the strength of one — a kind in the second without the
|
|
20
|
+
// first is exactly an over-declaration (samchon/typia#2357).
|
|
21
|
+
//
|
|
22
|
+
// 1. Build a project where `a.ts` validates a tuple alias whose first member is
|
|
23
|
+
// named and typed `Id`, beside an alias the tuple never uses.
|
|
24
|
+
// 2. Run project transform mode and decode the JSON envelope.
|
|
25
|
+
// 3. Assert `dependencies["src/a.ts"]` contains `src/id.ts` and that `a.ts` is
|
|
26
|
+
// declared complete, so the narrowed bound is the one carrying it.
|
|
27
|
+
// 4. Assert it omits `src/unused.ts`, which no consulted member names.
|
|
28
|
+
func TestProjectDependenciesNamedTupleMemberTransform(t *testing.T) {
|
|
29
|
+
project := projectDependenciesNamedTupleMemberProject(t)
|
|
30
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
31
|
+
return runTransform([]string{
|
|
32
|
+
"--cwd", project,
|
|
33
|
+
"--tsconfig", "tsconfig.json",
|
|
34
|
+
"--output", "ts",
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
if code != 0 {
|
|
38
|
+
t.Fatalf("project transform failed: code=%d stderr=\n%s", code, errText)
|
|
39
|
+
}
|
|
40
|
+
var envelope struct {
|
|
41
|
+
Dependencies map[string][]string `json:"dependencies"`
|
|
42
|
+
DependenciesComplete []string `json:"dependenciesComplete"`
|
|
43
|
+
}
|
|
44
|
+
if err := json.Unmarshal([]byte(out), &envelope); err != nil {
|
|
45
|
+
t.Fatalf("decode envelope: %v\n%s", err, out)
|
|
46
|
+
}
|
|
47
|
+
entries := envelope.Dependencies["src/a.ts"]
|
|
48
|
+
found := map[string]bool{}
|
|
49
|
+
for _, entry := range entries {
|
|
50
|
+
found[entry] = true
|
|
51
|
+
}
|
|
52
|
+
if !found["src/pair.ts"] {
|
|
53
|
+
t.Fatalf("dependencies of src/a.ts must contain the declaring file src/pair.ts: %v", entries)
|
|
54
|
+
}
|
|
55
|
+
if !found["src/id.ts"] {
|
|
56
|
+
t.Fatalf("dependencies of src/a.ts must contain src/id.ts, which the named tuple member's type names: %v", entries)
|
|
57
|
+
}
|
|
58
|
+
if found["src/unused.ts"] {
|
|
59
|
+
t.Fatalf("dependencies of src/a.ts must not contain src/unused.ts, which no consulted member names: %v", entries)
|
|
60
|
+
}
|
|
61
|
+
declared := false
|
|
62
|
+
for _, key := range envelope.DependenciesComplete {
|
|
63
|
+
if key == "src/a.ts" {
|
|
64
|
+
declared = true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if !declared {
|
|
68
|
+
t.Fatalf("src/a.ts must be declared complete, so the reported entry is the whole bound: %v", envelope.DependenciesComplete)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func projectDependenciesNamedTupleMemberProject(t *testing.T) string {
|
|
73
|
+
t.Helper()
|
|
74
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
75
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
76
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
77
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
78
|
+
}
|
|
79
|
+
dir, err := os.MkdirTemp(base, "project-dependencies-named-tuple-member-")
|
|
80
|
+
if err != nil {
|
|
81
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
82
|
+
}
|
|
83
|
+
t.Cleanup(func() { _ = os.RemoveAll(dir) })
|
|
84
|
+
src := filepath.Join(dir, "src")
|
|
85
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
86
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
87
|
+
}
|
|
88
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(projectDependenciesEnvelopeTSConfig), 0o644); err != nil {
|
|
89
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
90
|
+
}
|
|
91
|
+
for name, body := range map[string]string{
|
|
92
|
+
"a.ts": projectDependenciesNamedTupleMemberSourceA,
|
|
93
|
+
"pair.ts": projectDependenciesNamedTupleMemberSourcePair,
|
|
94
|
+
"id.ts": projectDependenciesNamedTupleMemberSourceId,
|
|
95
|
+
"unused.ts": projectDependenciesNamedTupleMemberSourceUnused,
|
|
96
|
+
} {
|
|
97
|
+
if err := os.WriteFile(filepath.Join(src, name), []byte(body), 0o644); err != nil {
|
|
98
|
+
t.Fatalf("write %s: %v", name, err)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return dir
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const projectDependenciesNamedTupleMemberSourceA = `import typia from "typia";
|
|
105
|
+
|
|
106
|
+
import { Pair } from "./pair";
|
|
107
|
+
|
|
108
|
+
export const check = (input: unknown) => typia.is<Pair>(input);
|
|
109
|
+
`
|
|
110
|
+
|
|
111
|
+
const projectDependenciesNamedTupleMemberSourcePair = `import { Id } from "./id";
|
|
112
|
+
import { Unused } from "./unused";
|
|
113
|
+
|
|
114
|
+
export type Pair = [id: Id, count: number];
|
|
115
|
+
|
|
116
|
+
export type Spare = [label: Unused];
|
|
117
|
+
`
|
|
118
|
+
|
|
119
|
+
const projectDependenciesNamedTupleMemberSourceId = `export type Id = string;
|
|
120
|
+
`
|
|
121
|
+
|
|
122
|
+
const projectDependenciesNamedTupleMemberSourceUnused = `export type Unused = string;
|
|
123
|
+
`
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestProjectDependenciesQualifiedBarrelTransform verifies a QUALIFIED type
|
|
12
|
+
// reference reports the barrel that selected its namespace half, not only the
|
|
13
|
+
// module declaring its terminus.
|
|
14
|
+
//
|
|
15
|
+
// `TestProjectDependenciesBarrelReexportTransform` pins the bare spelling, and
|
|
16
|
+
// it works because the checker answers `Alpha` with the local import alias, whose
|
|
17
|
+
// path metadataDependency_touchPath walks. `Kind.A` is answered with the enum
|
|
18
|
+
// member instead -- not an alias, no path to walk -- so the barrel between the
|
|
19
|
+
// caller and the enum went unreported while its value went straight into the
|
|
20
|
+
// validator as `"alpha" === input.kind`. Re-pointing that barrel at another enum
|
|
21
|
+
// changed the emitted constant with nothing left to invalidate the file
|
|
22
|
+
// (samchon/typia#2126, samchon/typia#2357).
|
|
23
|
+
//
|
|
24
|
+
// 1. Build a project where `main.ts` validates `Doc`, whose member type is
|
|
25
|
+
// `Kind.A` for a `Kind` imported from `barrel.ts`, which re-exports it from
|
|
26
|
+
// `kind.ts` and also re-exports an unconsumed `Unused` from `unused.ts`.
|
|
27
|
+
// 2. Run project transform mode and decode the JSON envelope.
|
|
28
|
+
// 3. Assert the emitted validator compares against the enum member's value, so
|
|
29
|
+
// the fixture really does read `kind.ts` into its output.
|
|
30
|
+
// 4. Assert `dependencies["src/main.ts"]` contains `src/barrel.ts` and
|
|
31
|
+
// `src/kind.ts`, and that `src/main.ts` is declared complete.
|
|
32
|
+
// 5. Assert it omits `src/unused.ts`, the sibling the reference never traverses.
|
|
33
|
+
func TestProjectDependenciesQualifiedBarrelTransform(t *testing.T) {
|
|
34
|
+
project := projectDependenciesQualifiedBarrelProject(t)
|
|
35
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
36
|
+
return runTransform([]string{
|
|
37
|
+
"--cwd", project,
|
|
38
|
+
"--tsconfig", "tsconfig.json",
|
|
39
|
+
"--output", "ts",
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
if code != 0 {
|
|
43
|
+
t.Fatalf("project transform failed: code=%d stderr=\n%s", code, errText)
|
|
44
|
+
}
|
|
45
|
+
var envelope struct {
|
|
46
|
+
TypeScript map[string]string `json:"typescript"`
|
|
47
|
+
Dependencies map[string][]string `json:"dependencies"`
|
|
48
|
+
DependenciesComplete []string `json:"dependenciesComplete"`
|
|
49
|
+
}
|
|
50
|
+
if err := json.Unmarshal([]byte(out), &envelope); err != nil {
|
|
51
|
+
t.Fatalf("decode envelope: %v\n%s", err, out)
|
|
52
|
+
}
|
|
53
|
+
if text := envelope.TypeScript["src/main.ts"]; !strings.Contains(text, `"alpha"`) {
|
|
54
|
+
t.Fatalf("the validator must compare against the enum member's value, so the fixture reads kind.ts into its output, got:\n%s", text)
|
|
55
|
+
}
|
|
56
|
+
entries := envelope.Dependencies["src/main.ts"]
|
|
57
|
+
found := map[string]bool{}
|
|
58
|
+
for _, entry := range entries {
|
|
59
|
+
found[entry] = true
|
|
60
|
+
}
|
|
61
|
+
if !found["src/kind.ts"] {
|
|
62
|
+
t.Fatalf("dependencies of src/main.ts must contain src/kind.ts, which declares the member the type names: %v", entries)
|
|
63
|
+
}
|
|
64
|
+
if !found["src/barrel.ts"] {
|
|
65
|
+
t.Fatalf("dependencies of src/main.ts must contain src/barrel.ts, which selects the enum the qualified name reads: %v", entries)
|
|
66
|
+
}
|
|
67
|
+
if found["src/unused.ts"] {
|
|
68
|
+
t.Fatalf("dependencies of src/main.ts must not contain src/unused.ts, a sibling the reference never traverses: %v", entries)
|
|
69
|
+
}
|
|
70
|
+
declared := false
|
|
71
|
+
for _, key := range envelope.DependenciesComplete {
|
|
72
|
+
if key == "src/main.ts" {
|
|
73
|
+
declared = true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if !declared {
|
|
77
|
+
t.Fatalf("src/main.ts must be declared complete, so the reported entry is the whole bound: %v", envelope.DependenciesComplete)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func projectDependenciesQualifiedBarrelProject(t *testing.T) string {
|
|
82
|
+
t.Helper()
|
|
83
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
84
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
85
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
86
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
87
|
+
}
|
|
88
|
+
dir, err := os.MkdirTemp(base, "project-dependencies-qualified-barrel-")
|
|
89
|
+
if err != nil {
|
|
90
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
91
|
+
}
|
|
92
|
+
t.Cleanup(func() { _ = os.RemoveAll(dir) })
|
|
93
|
+
src := filepath.Join(dir, "src")
|
|
94
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
95
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
96
|
+
}
|
|
97
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(projectDependenciesEnvelopeTSConfig), 0o644); err != nil {
|
|
98
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
99
|
+
}
|
|
100
|
+
for name, body := range map[string]string{
|
|
101
|
+
"main.ts": projectDependenciesQualifiedBarrelSourceMain,
|
|
102
|
+
"doc.ts": projectDependenciesQualifiedBarrelSourceDoc,
|
|
103
|
+
"barrel.ts": projectDependenciesQualifiedBarrelSourceBarrel,
|
|
104
|
+
"kind.ts": projectDependenciesQualifiedBarrelSourceKind,
|
|
105
|
+
"unused.ts": projectDependenciesQualifiedBarrelSourceUnused,
|
|
106
|
+
} {
|
|
107
|
+
if err := os.WriteFile(filepath.Join(src, name), []byte(body), 0o644); err != nil {
|
|
108
|
+
t.Fatalf("write %s: %v", name, err)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return dir
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const projectDependenciesQualifiedBarrelSourceMain = `import typia from "typia";
|
|
115
|
+
|
|
116
|
+
import { Doc } from "./doc";
|
|
117
|
+
|
|
118
|
+
export const check = (input: unknown) => typia.is<Doc>(input);
|
|
119
|
+
`
|
|
120
|
+
|
|
121
|
+
const projectDependenciesQualifiedBarrelSourceDoc = `import { Kind } from "./barrel";
|
|
122
|
+
|
|
123
|
+
export interface Doc {
|
|
124
|
+
kind: Kind.A;
|
|
125
|
+
}
|
|
126
|
+
`
|
|
127
|
+
|
|
128
|
+
const projectDependenciesQualifiedBarrelSourceBarrel = `export { Kind } from "./kind";
|
|
129
|
+
export { Unused } from "./unused";
|
|
130
|
+
`
|
|
131
|
+
|
|
132
|
+
const projectDependenciesQualifiedBarrelSourceKind = `export enum Kind {
|
|
133
|
+
A = "alpha",
|
|
134
|
+
B = "beta",
|
|
135
|
+
}
|
|
136
|
+
`
|
|
137
|
+
|
|
138
|
+
const projectDependenciesQualifiedBarrelSourceUnused = `export enum Unused {
|
|
139
|
+
C = "gamma",
|
|
140
|
+
}
|
|
141
|
+
`
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestProjectDependenciesTypeParameterDefaultTransform verifies an interface's
|
|
11
|
+
// type-parameter default reports the file its alias comes from.
|
|
12
|
+
//
|
|
13
|
+
// `typia.is<Wrapper>()` over `interface Wrapper<T = Id>` validates whatever `Id`
|
|
14
|
+
// is, and the checker interns `type Id = string` as the bare intrinsic, so the
|
|
15
|
+
// resolved type carries no symbol the type graph can follow to `id.ts`
|
|
16
|
+
// (samchon/typia#2126). The equivalent `type AliasWrapper<T = Id> = { v: T }`
|
|
17
|
+
// always reported it, because a `type` alias surfaces its whole node; an
|
|
18
|
+
// interface surfaced only its index signatures, one declaration kind away from
|
|
19
|
+
// the same defect (samchon/typia#2357).
|
|
20
|
+
//
|
|
21
|
+
// 1. Build a project where `a.ts` validates `Wrapper` from `wrapper.ts`, whose
|
|
22
|
+
// type parameter defaults to `Id` from `id.ts`, and where the same file
|
|
23
|
+
// declares a second interface defaulting to `Unused` from `unused.ts`.
|
|
24
|
+
// 2. Run project transform mode and decode the JSON envelope.
|
|
25
|
+
// 3. Assert `dependencies["src/a.ts"]` contains `src/id.ts`, and that `a.ts`
|
|
26
|
+
// is declared complete so the narrowed bound is the one that carries it.
|
|
27
|
+
// 4. Assert it omits `src/unused.ts`, whose interface the call never reaches.
|
|
28
|
+
func TestProjectDependenciesTypeParameterDefaultTransform(t *testing.T) {
|
|
29
|
+
project := projectDependenciesTypeParameterDefaultProject(t)
|
|
30
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
31
|
+
return runTransform([]string{
|
|
32
|
+
"--cwd", project,
|
|
33
|
+
"--tsconfig", "tsconfig.json",
|
|
34
|
+
"--output", "ts",
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
if code != 0 {
|
|
38
|
+
t.Fatalf("project transform failed: code=%d stderr=\n%s", code, errText)
|
|
39
|
+
}
|
|
40
|
+
var envelope struct {
|
|
41
|
+
Dependencies map[string][]string `json:"dependencies"`
|
|
42
|
+
DependenciesComplete []string `json:"dependenciesComplete"`
|
|
43
|
+
}
|
|
44
|
+
if err := json.Unmarshal([]byte(out), &envelope); err != nil {
|
|
45
|
+
t.Fatalf("decode envelope: %v\n%s", err, out)
|
|
46
|
+
}
|
|
47
|
+
entries := envelope.Dependencies["src/a.ts"]
|
|
48
|
+
found := map[string]bool{}
|
|
49
|
+
for _, entry := range entries {
|
|
50
|
+
found[entry] = true
|
|
51
|
+
}
|
|
52
|
+
if !found["src/wrapper.ts"] {
|
|
53
|
+
t.Fatalf("dependencies of src/a.ts must contain the declaring file src/wrapper.ts: %v", entries)
|
|
54
|
+
}
|
|
55
|
+
if !found["src/id.ts"] {
|
|
56
|
+
t.Fatalf("dependencies of src/a.ts must contain src/id.ts, which the type-parameter default names: %v", entries)
|
|
57
|
+
}
|
|
58
|
+
if found["src/unused.ts"] {
|
|
59
|
+
t.Fatalf("dependencies of src/a.ts must not contain src/unused.ts, which no consulted type reaches: %v", entries)
|
|
60
|
+
}
|
|
61
|
+
declared := false
|
|
62
|
+
for _, key := range envelope.DependenciesComplete {
|
|
63
|
+
if key == "src/a.ts" {
|
|
64
|
+
declared = true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if !declared {
|
|
68
|
+
t.Fatalf("src/a.ts must be declared complete, so the reported entry is the whole bound: %v", envelope.DependenciesComplete)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func projectDependenciesTypeParameterDefaultProject(t *testing.T) string {
|
|
73
|
+
t.Helper()
|
|
74
|
+
root := ttscTypiaTestRepoRoot(t)
|
|
75
|
+
base := filepath.Join(root, "packages", "typia", "native", ".tmp-ttsc-typia-tests")
|
|
76
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
77
|
+
t.Fatalf("mkdir temp base: %v", err)
|
|
78
|
+
}
|
|
79
|
+
dir, err := os.MkdirTemp(base, "project-dependencies-type-parameter-default-")
|
|
80
|
+
if err != nil {
|
|
81
|
+
t.Fatalf("create temp fixture: %v", err)
|
|
82
|
+
}
|
|
83
|
+
t.Cleanup(func() { _ = os.RemoveAll(dir) })
|
|
84
|
+
src := filepath.Join(dir, "src")
|
|
85
|
+
if err := os.MkdirAll(src, 0o755); err != nil {
|
|
86
|
+
t.Fatalf("mkdir fixture src: %v", err)
|
|
87
|
+
}
|
|
88
|
+
if err := os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte(projectDependenciesEnvelopeTSConfig), 0o644); err != nil {
|
|
89
|
+
t.Fatalf("write tsconfig: %v", err)
|
|
90
|
+
}
|
|
91
|
+
for name, body := range map[string]string{
|
|
92
|
+
"a.ts": projectDependenciesTypeParameterDefaultSourceA,
|
|
93
|
+
"wrapper.ts": projectDependenciesTypeParameterDefaultSourceWrapper,
|
|
94
|
+
"id.ts": projectDependenciesTypeParameterDefaultSourceId,
|
|
95
|
+
"unused.ts": projectDependenciesTypeParameterDefaultSourceUnused,
|
|
96
|
+
} {
|
|
97
|
+
if err := os.WriteFile(filepath.Join(src, name), []byte(body), 0o644); err != nil {
|
|
98
|
+
t.Fatalf("write %s: %v", name, err)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return dir
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const projectDependenciesTypeParameterDefaultSourceA = `import typia from "typia";
|
|
105
|
+
|
|
106
|
+
import { Wrapper } from "./wrapper";
|
|
107
|
+
|
|
108
|
+
export const check = (input: unknown) => typia.is<Wrapper>(input);
|
|
109
|
+
`
|
|
110
|
+
|
|
111
|
+
const projectDependenciesTypeParameterDefaultSourceWrapper = `import { Id } from "./id";
|
|
112
|
+
import { Unused } from "./unused";
|
|
113
|
+
|
|
114
|
+
export interface Wrapper<T = Id> {
|
|
115
|
+
value: T;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface Spare<T = Unused> {
|
|
119
|
+
value: T;
|
|
120
|
+
}
|
|
121
|
+
`
|
|
122
|
+
|
|
123
|
+
const projectDependenciesTypeParameterDefaultSourceId = `export type Id = string;
|
|
124
|
+
`
|
|
125
|
+
|
|
126
|
+
const projectDependenciesTypeParameterDefaultSourceUnused = `export type Unused = number;
|
|
127
|
+
`
|
|
@@ -34,7 +34,9 @@ func TestTemplateLiteralTypeTagsTransform(t *testing.T) {
|
|
|
34
34
|
if code != 0 {
|
|
35
35
|
t.Fatalf("template literal tags transform failed: code=%d stderr=\n%s", code, errText)
|
|
36
36
|
}
|
|
37
|
-
if !strings.Contains(out, "
|
|
37
|
+
if !strings.Contains(out, `require("typia/lib/internal/_stringLength")`) ||
|
|
38
|
+
!strings.Contains(out, "._stringLength(input) <= 30") ||
|
|
39
|
+
!strings.Contains(out, "RegExp(/^prefix(.*)postfix$/)") {
|
|
38
40
|
t.Fatalf("emitted checker should combine the template pattern with its tags:\n%s", out)
|
|
39
41
|
}
|
|
40
42
|
templateLiteralTypeTagsRunRuntimeCases(t, project, out)
|