Skip to content

Commit 530f110

Browse files
antfupikax
andauthored
feat(test): add dts testing (#347)
* feat(test): add dts testing * update test script * update github actions * chore: update to align with vue-next * clean up * fix test * fix * Update .github/workflows/nodejs.yml Co-authored-by: Carlos Rodrigues <[email protected]> Co-authored-by: Carlos Rodrigues <[email protected]>
1 parent bc78428 commit 530f110

File tree

8 files changed

+446
-1117
lines changed

8 files changed

+446
-1117
lines changed

.github/workflows/nodejs.yml

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
1-
name: Node CI
1+
name: Build & Test
22

33
on:
44
pull_request:
55
branches:
6-
- master
6+
- master
77

88
jobs:
99
build:
10-
1110
runs-on: ubuntu-latest
1211

1312
strategy:
1413
matrix:
1514
node-version: [10.x, 12.x]
1615

1716
steps:
18-
- uses: actions/checkout@v1
19-
- name: Use Node.js ${{ matrix.node-version }}
20-
uses: actions/setup-node@v1
21-
with:
22-
node-version: ${{ matrix.node-version }}
23-
- name: npm install, build, and test
24-
run: |
25-
npm install
26-
npm run build --if-present
27-
npm test
28-
env:
29-
CI: true
17+
- uses: actions/checkout@v2
18+
- uses: actions/setup-node@v1
19+
with:
20+
node-version: ${{ matrix.node-version }}
21+
- name: Install
22+
run: yarn install --frozen-lockfile
23+
- name: Build
24+
run: yarn build
25+
env:
26+
CI: true
27+
- name: Typing Declartion Tests
28+
run: yarn test-dts
29+
env:
30+
CI: true
31+
- name: Unit Tests
32+
run: yarn test
33+
env:
34+
CI: true
35+

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
"license": "MIT",
2323
"sideEffects": false,
2424
"files": [
25-
"dist/"
25+
"dist"
2626
],
2727
"scripts": {
2828
"start": "cross-env TARGET=es rollup -c -w",
2929
"build": "rollup -c",
3030
"test": "cross-env NODE_ENV=test jest",
31+
"test-dts": "tsc -p ./test-dts/tsconfig.json && npm run build && tsc -p ./test-dts/tsconfig.build.json",
3132
"release": "bash scripts/release.sh"
3233
},
3334
"bugs": {

test-dts/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from '@vue/composition-api';
2+
3+
export function expectType<T>(value: T): void;
4+
export function expectError<T>(value: T): void;
5+
export function expectAssignable<T, T2 extends T = T>(value: T2): void;

test-dts/ref.test-d.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Ref, ref, isRef, unref, reactive, expectType } from './index';
2+
3+
function plainType(arg: number | Ref<number>) {
4+
// ref coercing
5+
const coerced = ref(arg);
6+
expectType<Ref<number>>(coerced);
7+
8+
// isRef as type guard
9+
if (isRef(arg)) {
10+
expectType<Ref<number>>(arg);
11+
}
12+
13+
// ref unwrapping
14+
expectType<number>(unref(arg));
15+
16+
// ref inner type should be unwrapped
17+
const nestedRef = ref({
18+
foo: ref(1),
19+
});
20+
expectType<Ref<{ foo: number }>>(nestedRef);
21+
expectType<{ foo: number }>(nestedRef.value);
22+
23+
// ref boolean
24+
const falseRef = ref(false);
25+
expectType<Ref<boolean>>(falseRef);
26+
expectType<boolean>(falseRef.value);
27+
28+
// ref true
29+
const trueRef = ref<true>(true);
30+
expectType<Ref<true>>(trueRef);
31+
expectType<true>(trueRef.value);
32+
33+
// tuple
34+
expectType<[number, string]>(unref(ref([1, '1'])));
35+
36+
interface IteratorFoo {
37+
[Symbol.iterator]: any;
38+
}
39+
40+
// with symbol
41+
expectType<Ref<IteratorFoo | null | undefined>>(ref<IteratorFoo | null | undefined>());
42+
}
43+
44+
plainType(1);
45+
46+
function bailType(arg: HTMLElement | Ref<HTMLElement>) {
47+
// ref coercing
48+
const coerced = ref(arg);
49+
expectType<Ref<HTMLElement>>(coerced);
50+
51+
// isRef as type guard
52+
if (isRef(arg)) {
53+
expectType<Ref<HTMLElement>>(arg);
54+
}
55+
56+
// ref unwrapping
57+
expectType<HTMLElement>(unref(arg));
58+
59+
// ref inner type should be unwrapped
60+
const nestedRef = ref({ foo: ref(document.createElement('DIV')) });
61+
62+
expectType<Ref<{ foo: HTMLElement }>>(nestedRef);
63+
expectType<{ foo: HTMLElement }>(nestedRef.value);
64+
}
65+
const el = document.createElement('DIV');
66+
bailType(el);
67+
68+
function withSymbol() {
69+
const customSymbol = Symbol();
70+
const obj = {
71+
[Symbol.asyncIterator]: { a: 1 },
72+
[Symbol.unscopables]: { b: '1' },
73+
[customSymbol]: { c: [1, 2, 3] },
74+
};
75+
76+
const objRef = ref(obj);
77+
78+
expectType<{ a: number }>(objRef.value[Symbol.asyncIterator]);
79+
expectType<{ b: string }>(objRef.value[Symbol.unscopables]);
80+
expectType<{ c: Array<number> }>(objRef.value[customSymbol]);
81+
}
82+
83+
withSymbol();
84+
85+
const state = reactive({
86+
foo: {
87+
value: 1,
88+
label: 'bar',
89+
},
90+
});
91+
92+
expectType<string>(state.foo.label);

test-dts/tsconfig.build.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"paths": {
5+
"@vue/composition-api": ["../dist"]
6+
}
7+
}
8+
}

test-dts/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"noEmit": true,
5+
"declaration": true,
6+
"baseUrl": ".",
7+
"paths": {
8+
"@vue/composition-api": ["../src"]
9+
}
10+
},
11+
"exclude": ["../test"],
12+
"include": ["../src", "./*.ts"]
13+
}

test-dts/watch.test-d.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { ref, computed, watch, expectType } from './index';
2+
3+
const source = ref('foo');
4+
const source2 = computed(() => source.value);
5+
const source3 = () => 1;
6+
7+
// lazy watcher will have consistent types for oldValue.
8+
watch(source, (value, oldValue) => {
9+
expectType<string>(value);
10+
expectType<string>(oldValue);
11+
});
12+
13+
watch([source, source2, source3], (values, oldValues) => {
14+
expectType<(string | number)[]>(values);
15+
expectType<(string | number)[]>(oldValues);
16+
});
17+
18+
// const array
19+
watch([source, source2, source3] as const, (values, oldValues) => {
20+
expectType<Readonly<[string, string, number]>>(values);
21+
expectType<Readonly<[string, string, number]>>(oldValues);
22+
});
23+
24+
// immediate watcher's oldValue will be undefined on first run.
25+
watch(
26+
source,
27+
(value, oldValue) => {
28+
expectType<string>(value);
29+
expectType<string | undefined>(oldValue);
30+
},
31+
{ immediate: true }
32+
);
33+
34+
watch(
35+
[source, source2, source3],
36+
(values, oldValues) => {
37+
expectType<(string | number)[]>(values);
38+
expectType<(string | number | undefined)[]>(oldValues);
39+
},
40+
{ immediate: true }
41+
);
42+
43+
// const array
44+
watch(
45+
[source, source2, source3] as const,
46+
(values, oldValues) => {
47+
expectType<Readonly<[string, string, number]>>(values);
48+
expectType<Readonly<[string | undefined, string | undefined, number | undefined]>>(oldValues);
49+
},
50+
{ immediate: true }
51+
);
52+
53+
// should provide correct ref.value inner type to callbacks
54+
const nestedRefSource = ref({
55+
foo: ref(1),
56+
});
57+
58+
watch(nestedRefSource, (v, ov) => {
59+
expectType<{ foo: number }>(v);
60+
expectType<{ foo: number }>(ov);
61+
});

0 commit comments

Comments
 (0)