Skip to content

Commit

Permalink
Improve type testing for older versions of TypeScript (#254)
Browse files Browse the repository at this point in the history
* Run types tests with multiple versions of TypeScript

* Test older versions of TypeScript by separate @ts-expect-error tests

* Remove old versions test from GitHub actions workflow

* Add comment
  • Loading branch information
christopher-stripe authored Nov 1, 2021
1 parent a03f141 commit 4f2d0af
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 187 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ jobs:
- run: yarn run lint
- run: yarn run typecheck
- run: yarn run test:unit
- run: yarn run test:versions
- run: yarn run test:types
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
"scripts": {
"test": "yarn lint && yarn test:unit && yarn test:versions && yarn test:types && yarn typecheck",
"test:unit": "jest",
"test:versions": "./tests/versions/scripts/test.sh",
"test:types": "tsc -p ./tests/types",
"test:types": "zx --quiet ./tests/types/scripts/test.mjs",
"lint": "eslint '{src,types}/**/*.{ts,js}' && yarn prettier-check",
"typecheck": "tsc",
"build": "yarn clean && yarn rollup -c",
Expand Down Expand Up @@ -57,6 +56,7 @@
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-typescript2": "^0.25.3",
"ts-jest": "^24.3.0",
"typescript": "^4.1.2"
"typescript": "^4.1.2",
"zx": "^4.2.0"
}
}
1 change: 1 addition & 0 deletions tests/types/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src
File renamed without changes.
48 changes: 48 additions & 0 deletions tests/types/scripts/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env zx

import fs from 'fs';
import 'zx/globals';

const VERSIONS = [
'next',
'beta',
'latest',
'3.9.7',
'3.8.3',
'3.7.4',
'3.6.3',
'3.5.1',
'3.4.4',
'3.3.3',
'3.2.1',

// Attempting to test on 3.1.1 currently fails. I believe it is not a
// fundamental incompability with the types, just some tsconfig.json changes
// that are needed. Skipping for now
// '3.1.1',
];

const TYPE_TESTS_DIR = `${__dirname}/..`;

// Ensure working directory is test directory
cd(TYPE_TESTS_DIR);

if (fs.existsSync(`${TYPE_TESTS_DIR}/package.json`)) {
await $`rm package.json`;
}

await $`yarn init -sy`;

for (const version of VERSIONS) {
console.log(`--- Testing with TypeScript version ${version}`);
await $`yarn add -s --no-progress typescript@${version}`;
await $`yarn run tsc --strict --noEmit src/valid.ts`;

// TypeScript versions >= 3.9.0 support [@ts-expect-error][0], which lets us
// write tests for types that we expect to cause errors
//
// [0]: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#-ts-expect-error-comments
if (version >= '3.9.0') {
await $`yarn run tsc --strict --noEmit src/invalid.ts`;
}
}
91 changes: 91 additions & 0 deletions tests/types/src/invalid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
///<reference path='../../../types/index.d.ts' />

import {
Stripe,
StripeElements,
StripeCardElement,
StripeIbanElement,
StripePaymentElement,
} from '@stripe/stripe-js';

declare const stripe: Stripe;
declare const elements: StripeElements;
declare const cardElement: StripeCardElement;
declare const ibanElement: StripeIbanElement;
declare const paymentElement: StripePaymentElement;

elements.update({
// @ts-expect-error: `clientSecret` is not updatable
clientSecret: 'pk_foo_secret_bar',
});

elements.update({
// @ts-expect-error: `fonts` is not updatable
fonts: [],
});

paymentElement.on('change', (e) => {
// @ts-expect-error: `error` is not present on PaymentElement "change" event.
if (e.error) {
}
});

stripe
.confirmPayment({elements, confirmParams: {return_url: ''}})
.then((res) => {
if (res.error) {
}

// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmPayment({
elements,
confirmParams: {return_url: ''},
redirect: 'always',
})
.then((res) => {
if (res.error) {
}

// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe.confirmSetup({elements, confirmParams: {return_url: ''}}).then((res) => {
if (res.error) {
}

// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmSetup({elements, confirmParams: {return_url: ''}, redirect: 'always'})
.then((res) => {
if (res.error) {
}

// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe.createToken(cardElement, {
currency: '',
name: '',
// @ts-expect-error: `extra_property` is not valid
extra_property: '',
});

// @ts-expect-error: `extra_property` is not valid
stripe.createToken(ibanElement, {
currency: '',
account_holder_name: '',
extra_property: '',
});
96 changes: 3 additions & 93 deletions tests/types/index.ts → tests/types/src/valid.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
///<reference path='../../types/index.d.ts' />
///<reference path='../../../types/index.d.ts' />

import {assert, Has} from 'conditional-type-checks';

Expand Down Expand Up @@ -51,12 +51,12 @@ const stripePromise: Promise<Stripe | null> = loadStripe('');
const stripeConnectPromise = loadStripe('', {stripeAccount: '', locale: 'en'});

type TypeModule = typeof import('@stripe/stripe-js');
type SrcModule = typeof import('../../src/index');
type SrcModule = typeof import('../../../src/index');

// Makes sure that the implementation matches the type definitions
// Checking for compatibility both ways ensures that the exports
// are equivalent with nothing missing on either side.
import('../../src/index').then((srcModule: TypeModule) => {});
import('../../../src/index').then((srcModule: TypeModule) => {});
import('@stripe/stripe-js').then((typeModule: SrcModule) => {});

const stripe: Stripe = window.Stripe!('pk_123');
Expand Down Expand Up @@ -134,14 +134,6 @@ elements.update({
},
},
});
elements.update({
// @ts-expect-error: `clientSecret` is not updatable
clientSecret: 'pk_foo_secret_bar',
});
elements.update({
// @ts-expect-error: `fonts` is not updatable
fonts: [],
});

const auBankAccountElement = elements.create('auBankAccount', {});

Expand Down Expand Up @@ -198,13 +190,6 @@ const retrievedCardCvcElement: StripeCardCvcElement | null = elements.getElement
'cardCvc'
);

stripe.createToken(cardElement, {
currency: '',
name: '',
// @ts-expect-error: `extra_property` is not valid
extra_property: '',
});

const fpxBankElement = elements.create('fpxBank', {
style: MY_STYLE,
value: '',
Expand All @@ -227,13 +212,6 @@ const retrievedIbanElement: StripeIbanElement | null = elements.getElement(
'iban'
);

// @ts-expect-error: `extra_property` is not valid
stripe.createToken(ibanElement, {
currency: '',
account_holder_name: '',
extra_property: '',
});

const idealBankElement = elements.create('idealBank', {
style: MY_STYLE,
value: '',
Expand Down Expand Up @@ -330,12 +308,6 @@ paymentElement
}) => {}
);

paymentElement.on('change', (e) => {
// @ts-expect-error: `error` is not present on PaymentElement "change" event.
if (e.error) {
}
});

paymentElement.collapse();

affirmMessageElement.on('ready', (e: {elementType: 'affirmMessage'}) => {});
Expand Down Expand Up @@ -1908,37 +1880,6 @@ stripe
}) => null
);

stripe
.confirmPayment({
elements,
confirmParams: {
return_url: '',
},
})
.then((res) => {
if (res.error) {
}
// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmPayment({
elements,
confirmParams: {
return_url: '',
},
redirect: 'always',
})
.then((res) => {
if (res.error) {
}
// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmPayment({
elements,
Expand All @@ -1963,37 +1904,6 @@ stripe
}
});

stripe
.confirmSetup({
elements,
confirmParams: {
return_url: '',
},
})
.then((res) => {
if (res.error) {
}
// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmSetup({
elements,
confirmParams: {
return_url: '',
},
redirect: 'always',
})
.then((res) => {
if (res.error) {
}
// @ts-expect-error redirect only, no paymentIntent expected
if (res.paymentIntent) {
}
});

stripe
.confirmSetup({
elements,
Expand Down
10 changes: 0 additions & 10 deletions tests/types/tsconfig.json

This file was deleted.

2 changes: 0 additions & 2 deletions tests/versions/.eslintrc.yml

This file was deleted.

30 changes: 0 additions & 30 deletions tests/versions/scripts/test.sh

This file was deleted.

33 changes: 0 additions & 33 deletions tests/versions/src/index.ts

This file was deleted.

Loading

0 comments on commit 4f2d0af

Please sign in to comment.