Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce tsc for some whitelisted jsdoc checks in src/utils. #510

Merged
merged 6 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
440 changes: 440 additions & 0 deletions .dependency-cruiser.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
# no longer check-in docs for builds. This is handled by Netlify
/docs

# tsc checks build here
oo-bldrs marked this conversation as resolved.
Show resolved Hide resolved
built

# misc
.DS_Store
.vscode
Expand Down
Binary file added deps.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
"build-storybook": "shx mkdir -p docs && build-storybook -o docs/sb",
"build-share": "yarn write-new-version && node config/build.js && yarn build-share-copy-web-asm",
"build-share-copy-web-asm": "shx cp node_modules/web-ifc/*.wasm docs/static/js",
"deps-graph": "npx dependency-cruiser src --include-only 'jsx?' --config --output-type dot | dot -T png > deps.png ; open deps.png",
"husky-init": "husky install",
"lint": "yarn eslint src",
"lint": "yarn eslint src && tsc",
"precommit": "yarn lint && yarn test",
"serve": "yarn serve-share",
"serve-share": "yarn build-share && node config/serve.js",
Expand Down Expand Up @@ -70,6 +71,10 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0",
"@testing-library/react-hooks": "^8.0.1",
"@tsconfig/recommended": "^1.0.1",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@types/three": "^0.146.0",
"babel-jest": "^28.1.3",
"babel-loader": "^8.2.5",
"cypress": "^10.7.0",
Expand Down
6 changes: 3 additions & 3 deletions src/utils/assert.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* If cond is true, do nothing. Otherwise, throw error with msg.
*
* @param {string} cond path to the button icon.
* @param {boolean} cond Test condition.
* @param {string} msg path to the button icon.
* @throws If the condition is false.
*/
Expand All @@ -16,8 +16,8 @@ export function assert(cond, msg) {
/**
* Equivalent to calling assertDefined on each parameter.
*
* @param {Array} args Variable length arguments to assert are defined.
* @return {Array} args That was passed in
* @param {any} args Variable length arguments to assert are defined.
* @return {any} args That was passed in
* @throws If any argument is not defined.
*/
export function assertDefined(...args) {
Expand Down
8 changes: 4 additions & 4 deletions src/utils/assert.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ test('assert', () => {
const a = undefined
const b = 1
expectFailure(() => {
new TestArgsCtor({a, b})
new TestArgsCtor(a, b)
})
expectFailure(() => {
new TestVarargs({a, b})
new TestVarargs(a, b)
})
})

Expand All @@ -57,7 +57,7 @@ class TestArgsCtor {
* @param {any} a test arg, possibly undefined
* @param {any} b test arg, possibly undefined
*/
constructor({a, b}) {
constructor(a, b) {
assertDefined(a, b)
}
}
Expand All @@ -69,7 +69,7 @@ class TestVarargs {
* @param {any} a test arg, possibly undefined
* @param {any} b test arg, possibly undefined
*/
constructor({a, b}) {
constructor(a, b) {
assertDefined(...arguments)
}
}
4 changes: 1 addition & 3 deletions src/utils/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export default function debug(level = INFO) {
}


/**
* @param {number} level One of OFF, INFO, DEBUG, ALL.
*/
/** @param {number} level One of OFF, INFO, DEBUG, ALL. */
export function setDebugLevel(level) {
if (!Number.isFinite(level) || level < DEBUG || level > OFF) {
throw new Error(`Debug level must be a number from ${DEBUG}-${OFF}`)
Expand Down
19 changes: 9 additions & 10 deletions src/utils/location.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/** @type {Object<string, Function>} */
const hashListeners = {}
window.onhashchange = () => {
for (const name in hashListeners) {
if (Object.prototype.hasOwnProperty.call(hashListeners, name)) {
const listener = hashListeners[name]
listener()
}
}
Object.values(hashListeners).forEach((listener) => {
listener()
})
}


Expand All @@ -26,9 +24,9 @@ export function addHashListener(name, onHashCb) {
* Serialize the given paramObj and add it to the current
* location.hash
*
* @param {object} location The window.location object
* @param {Location} location The window.location object
* @param {string} name A unique name for the params
* @param {object} params The parameters to encode
* @param {Object<string, any>} params The parameters to encode
* @param {boolean} includeNames Whether or not to include the
* parameter names in the encoding, default is false.
*/
Expand All @@ -44,6 +42,7 @@ export function addHashParams(location, name, params, includeNames = false) {
encodedParams += `${separator}${encodedParam}`
}
const sets = location.hash.substring(1).split('::')
/** @type {Object<string, string>} */
const setMap = {}
for (let i = 0; i < sets.length; i++) {
const set = sets[i]
Expand All @@ -68,7 +67,7 @@ export function addHashParams(location, name, params, includeNames = false) {


/**
* @param {object} location
* @param {Location} location
* @param {string} name prefix of the params to fetch
* @return {string|undefined} The encoded params
*/
Expand Down Expand Up @@ -98,7 +97,7 @@ export function getHashParamsFromHashStr(hashStr, name) {
/**
* Removes the given named hash param.
*
* @param {object} location
* @param {Location} location
* @param {string} name prefix of the params to fetch
*/
export function removeHashParams(location, name) {
Expand Down
5 changes: 4 additions & 1 deletion src/utils/location.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// TODO(pablo): The type for loc is really verbose below. Gotta be a
oo-bldrs marked this conversation as resolved.
Show resolved Hide resolved
// simpler way.
// @ts-nocheck
import {
addHashParams,
getHashParams,
Expand All @@ -6,8 +9,8 @@ import {


test('addHashParams', () => {
/** @type {Location} */
let loc

loc = {hash: ''}
addHashParams(loc, 'test', {a: 1})
expect(loc.hash).toBe('test:1')
Expand Down
22 changes: 10 additions & 12 deletions src/utils/math.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
/**
* @param {number} num Number to convert to float
* @return {number} The number as a float
*/
export function numToFloat(num) {
return parseFloat(num)
}


/**
* @param {number} num Number to round
* @param {number|string} num Number to round
* @param {number} numDigits Number of digits to round to, default = 0
* @return {number} The rounded number
*/
export function round(num, numDigits = 0) {
return numToFloat(numToFloat(num).toFixed(numDigits))
/** @type {number} */
let n
if (typeof num === 'string') {
n = parseFloat(num)
} else {
n = num
}
return parseFloat(n.toFixed(numDigits))
}


Expand All @@ -22,7 +20,7 @@ export function round(num, numDigits = 0) {
* @param {number} y y coordinate
* @param {number} z Z coordinate
* @param {number} numDigits Number of digits to round to, default = 0
* @return {Array} Array of [x, y, z]
* @return {Array<number>} Array of [x, y, z]
*/
export function roundCoord(x, y, z, numDigits = 0) {
return [x, y, z].map((n) => round(n, numDigits))
Expand Down
13 changes: 2 additions & 11 deletions src/utils/math.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable no-magic-numbers */
import {
numToFloat,
round,
roundCoord,
} from './math'
Expand All @@ -10,19 +9,11 @@ import {
const τ = 6.283185306


test('numToFloat', () => {
expect(numToFloat(0)).toBe(0.0)
expect(numToFloat(6)).toBe(6.0)
expect(numToFloat('6')).toBe(6.0)
expect(numToFloat(`${τ }`)).toBe(τ)
})


test('round', () => {
expect(round(τ)).toBe(6)
expect(round(`${τ }`)).toBe(6)
expect(round(`${τ}`)).toBe(6)
expect(round(τ, 2)).toBe(6.28)
expect(round(`${τ }`, 2)).toBe(6.28)
expect(round(`${τ}`, 2)).toBe(6.28)
expect(round(τ, 3)).toBe(6.283)
})

Expand Down
8 changes: 2 additions & 6 deletions src/utils/objects.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
/**
* Delete all properties defined in the given object.
*
* @param {object} obj The object whose properties to delete.
* @param {Object<any, any>} obj The object whose properties to delete.
*/
export function deleteProperties(obj) {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
delete obj[key]
}
}
Object.keys(obj).forEach((key) => delete obj[key])
}


Expand Down
5 changes: 2 additions & 3 deletions src/utils/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ export function isNumeric(str) {
if (typeof str !== 'string') {
return false
}
return !isNaN(str) && // use type coercion to parse the _entirety_ of the string
!isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
return !isNaN(parseFloat(str))
}


/**
* @param {string} str
* @return {Array} url matches
* @return {Array<string>} url matches
*/
export function findUrls(str) {
// TODO(pablo): maybe support example.com/asdf
Expand Down
18 changes: 17 additions & 1 deletion src/utils/strings.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {findUrls} from './strings'
import {findUrls, isNumeric} from './strings'


describe('strings', () => {
Expand Down Expand Up @@ -34,4 +34,20 @@ describe('strings', () => {
'http://localhost:8080/share/v/p/index.ifc#c:-26.91,28.84,112.47,0,16.21,-3.48',
])
})


it('isNumeric recognizes common cases', () => {
oo-bldrs marked this conversation as resolved.
Show resolved Hide resolved
// @ts-expect-error TS2345
expect(isNumeric(-1)).toBeFalsy()
// @ts-expect-error TS2345
expect(isNumeric(0)).toBeFalsy()
// @ts-expect-error TS2345
expect(isNumeric(1)).toBeFalsy()
// @ts-expect-error TS2345
expect(isNumeric(NaN)).toBeFalsy()
expect(isNumeric('-1')).toBeTruthy()
expect(isNumeric('0')).toBeTruthy()
expect(isNumeric('1')).toBeTruthy()
expect(isNumeric('NaN')).toBeFalsy()
})
})
22 changes: 22 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "@tsconfig/recommended/tsconfig.json",
"include": [
"./src/utils/assert.js",
"./src/utils/assert.test.js",
"./src/utils/location.js",
"./src/utils/location.test.js",
"./src/utils/math.js",
"./src/utils/math.test.js",
"./src/utils/objects.js",
"./src/utils/strings.js",
"./src/utils/strings.test.js",
],
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"module": "es6",
"jsx": "react-jsx",
"pretty": false,
"noEmit": true,
},
}
33 changes: 33 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3335,6 +3335,11 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==

"@tsconfig/recommended@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@tsconfig/recommended/-/recommended-1.0.1.tgz#7619bad397e06ead1c5182926c944e0ca6177f52"
integrity sha512-2xN+iGTbPBEzGSnVp/Hd64vKJCJWxsi9gfs88x4PPMyEjHJoA3o5BY9r5OLPHIZU2pAQxkSAsJFqn6itClP8mQ==

"@types/aria-query@^4.2.0":
version "4.2.2"
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
Expand Down Expand Up @@ -3596,6 +3601,13 @@
dependencies:
"@types/react" "*"

"@types/react-dom@^18.0.9":
version "18.0.9"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504"
integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==
dependencies:
"@types/react" "*"

"@types/react-is@^16.7.1 || ^17.0.0":
version "17.0.3"
resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.3.tgz#2d855ba575f2fc8d17ef9861f084acc4b90a137a"
Expand All @@ -3619,6 +3631,15 @@
"@types/scheduler" "*"
csstype "^3.0.2"

"@types/react@^18.0.26":
version "18.0.26"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917"
integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"

"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
Expand Down Expand Up @@ -3663,6 +3684,13 @@
dependencies:
"@types/jest" "*"

"@types/three@^0.146.0":
version "0.146.0"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.146.0.tgz#83813ba0d2fff6bdc6d7fda3a77993a932bba45f"
integrity sha512-75AgysUrIvTCB054eQa2pDVFurfeFW8CrMQjpzjt3yHBfuuknoSvvsESd/3EhQxPrz9si3+P0wiDUVsWUlljfA==
dependencies:
"@types/webxr" "*"

"@types/tough-cookie@*":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397"
Expand Down Expand Up @@ -3706,6 +3734,11 @@
anymatch "^3.0.0"
source-map "^0.6.0"

"@types/webxr@*":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.0.tgz#aae1cef3210d88fd4204f8c33385a0bbc4da07c9"
integrity sha512-IUMDPSXnYIbEO2IereEFcgcqfDREOgmbGqtrMpVPpACTU6pltYLwHgVkrnYv0XhWEcjio9sYEfIEzgn3c7nDqA==

"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
Expand Down