chore: initial commit

This commit is contained in:
Ade Attwood 2022-10-24 19:48:49 +01:00
commit a03f915338
21 changed files with 8839 additions and 0 deletions

20
.eslintrc.js Normal file
View file

@ -0,0 +1,20 @@
module.exports = {
env: { node: true, es6: true },
parser: "@typescript-eslint/parser",
extends: ["eslint:recommended", "plugin:prettier/recommended", "plugin:@typescript-eslint/recommended"],
settings: {
jsdoc: { mode: "typescript" },
},
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-types": [
"error",
{
extendDefaults: true,
types: {
"{}": false,
},
},
],
},
};

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
node_modules
lib
coverage

7
.prettierrc.js Normal file
View file

@ -0,0 +1,7 @@
module.exports = {
tabWidth: 2,
printWidth: 120,
singleQuote: false,
trailingComma: "es5",
semi: true,
};

7
README.md Normal file
View file

@ -0,0 +1,7 @@
<div align="center">
# Diff Cov
Simple CLI to print diffs highlighted with test coverage status
</div>

BIN
assets/example-output.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

3
bin/diff-cov.js Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env node
require("..").run();

41
data/1.diff Normal file
View file

@ -0,0 +1,41 @@
diff --git a/src/index.ts b/src/index.ts
index d70a331..9515bb8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,8 @@
+export * from "./attribute-context";
+export * from "./check-group";
+export * from "./form-context";
export * from "./form";
export * from "./input-group";
+export * from "./list-group";
+export * from "./radio-group";
export * from "./select-group";
diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx
new file mode 100644
index 0000000..778e42f
--- /dev/null
+++ b/tests/index.spec.tsx
@@ -0,0 +1,22 @@
+import * as ReactForm from "../src";
+
+test.each([
+ // Components
+ "CheckGroup",
+ "Form",
+ "InputGroup",
+ "ListGroup",
+ "ListOption",
+ "RadioGroup",
+ "RadioOption",
+ "SelectGroup",
+
+ // Hooks
+ "useAttributeContext",
+ "useCheckboxAttribute",
+ "useFormContext",
+ "useSelectAttribute",
+ "useTextAttribute",
+])("'%s' is exported from the index file", (variable: string) => {
+ expect(ReactForm[variable as keyof typeof ReactForm]).not.toBeUndefined();
+});

980
data/1.lcov.info Normal file
View file

@ -0,0 +1,980 @@
TN:
SF:src/attribute-context.tsx
FN:22,AttributeContextProvider
FN:30,useAttributeContext
FNF:2
FNH:2
FNDA:20,AttributeContextProvider
FNDA:20,useAttributeContext
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,1
DA:16,1
DA:17,1
DA:18,1
DA:19,1
DA:20,1
DA:21,1
DA:22,20
DA:23,20
DA:24,20
DA:25,20
DA:26,1
DA:27,1
DA:28,1
DA:29,1
DA:30,20
DA:31,20
DA:32,20
LF:32
LH:32
BRDA:22,0,0,20
BRDA:30,1,0,20
BRF:2
BRH:2
end_of_record
TN:
SF:src/attribute-hook.ts
FN:1,(empty-report)
FNF:1
FNH:0
FNDA:0,(empty-report)
DA:1,0
DA:2,0
DA:3,0
DA:4,0
DA:5,0
DA:6,0
DA:7,0
DA:8,0
DA:9,0
DA:10,0
DA:11,0
DA:12,0
DA:13,0
DA:14,0
DA:15,0
DA:16,0
DA:17,0
DA:18,0
DA:19,0
DA:20,0
DA:21,0
DA:22,0
DA:23,0
DA:24,0
DA:25,0
DA:26,0
DA:27,0
DA:28,0
DA:29,0
DA:30,0
DA:31,0
DA:32,0
DA:33,0
DA:34,0
DA:35,0
DA:36,0
DA:37,0
DA:38,0
DA:39,0
DA:40,0
DA:41,0
DA:42,0
DA:43,0
DA:44,0
DA:45,0
DA:46,0
DA:47,0
LF:47
LH:0
BRDA:1,0,0,0
BRF:1
BRH:0
end_of_record
TN:
SF:src/base-group-props.ts
FN:1,(empty-report)
FNF:1
FNH:0
FNDA:0,(empty-report)
DA:1,0
DA:2,0
DA:3,0
DA:4,0
DA:5,0
DA:6,0
DA:7,0
DA:8,0
DA:9,0
DA:10,0
DA:11,0
DA:12,0
DA:13,0
LF:13
LH:0
BRDA:1,0,0,0
BRF:1
BRH:0
end_of_record
TN:
SF:src/check-group.tsx
FN:8,useCheckboxAttribute
FN:18,onChange
FN:37,CheckGroup
FNF:3
FNH:3
FNDA:3,useCheckboxAttribute
FNDA:2,onChange
FNDA:3,CheckGroup
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,3
DA:10,3
DA:11,3
DA:12,3
DA:13,3
DA:14,3
DA:15,3
DA:16,3
DA:17,3
DA:18,3
DA:19,2
DA:20,3
DA:21,3
DA:22,3
DA:23,3
DA:24,1
DA:25,1
DA:26,1
DA:27,1
DA:28,1
DA:29,1
DA:30,1
DA:31,1
DA:32,1
DA:33,1
DA:34,1
DA:35,1
DA:36,1
DA:37,1
DA:38,3
DA:39,3
DA:40,1
DA:41,1
LF:41
LH:41
BRDA:8,0,0,3
BRDA:18,1,0,2
BRDA:37,2,0,3
BRF:3
BRH:3
end_of_record
TN:
SF:src/dot-notation.ts
FN:15,get
FN:37,set
FNF:2
FNH:2
FNDA:104,get
FNDA:25,set
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,104
DA:16,104
DA:17,1
DA:18,1
DA:19,103
DA:20,104
DA:21,60
DA:22,60
DA:23,103
DA:24,104
DA:25,131
DA:26,131
DA:27,49
DA:28,49
DA:29,131
DA:30,54
DA:31,54
DA:32,54
DA:33,1
DA:34,1
DA:35,1
DA:36,1
DA:37,25
DA:38,25
DA:39,0
DA:40,0
DA:41,25
DA:42,25
DA:43,25
DA:44,25
DA:45,25
DA:46,25
DA:47,16
DA:48,16
DA:49,0
DA:50,0
DA:51,16
DA:52,16
DA:53,1
DA:54,1
DA:55,16
DA:56,16
DA:57,16
DA:58,25
DA:59,25
DA:60,25
DA:61,0
DA:62,0
DA:63,25
DA:64,25
DA:65,25
LF:65
LH:59
BRDA:15,0,0,104
BRDA:16,1,0,1
BRDA:19,2,0,103
BRDA:20,3,0,60
BRDA:23,4,0,103
BRDA:24,5,0,131
BRDA:26,6,0,49
BRDA:30,7,0,54
BRDA:37,8,0,25
BRDA:38,9,0,0
BRDA:46,10,0,16
BRDA:48,11,0,0
BRDA:52,12,0,1
BRDA:60,13,0,0
BRF:14
BRH:11
end_of_record
TN:
SF:src/form-context.tsx
FN:14,useFormContext
FNF:1
FNH:1
FNDA:59,useFormContext
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,59
DA:15,59
DA:16,59
LF:16
LH:16
BRDA:14,0,0,59
BRF:1
BRH:1
end_of_record
TN:
SF:src/form.tsx
FN:66,Form
FN:113,Form.submit
FN:128,Form.getAttribute
FN:135,Form.setAttribute
FN:157,Form.firstError
FN:166,Form.queueValidation
FN:185,Form.validateTimeout
FN:204,Form.validate
FN:237,Form.validateAttribute
FN:260,Form.getContextValue
FN:212,validateInternal
FN:271,render
FNF:12
FNH:11
FNDA:8,Form
FNDA:12,Form.submit
FNDA:58,Form.getAttribute
FNDA:23,Form.setAttribute
FNDA:42,Form.firstError
FNDA:23,Form.queueValidation
FNDA:0,Form.validateTimeout
FNDA:12,Form.validate
FNDA:15,Form.validateAttribute
FNDA:32,Form.getContextValue
FNDA:16,validateInternal
FNDA:32,render
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,1
DA:16,1
DA:17,1
DA:18,1
DA:19,1
DA:20,1
DA:21,1
DA:22,1
DA:23,1
DA:24,1
DA:25,1
DA:26,1
DA:27,1
DA:28,1
DA:29,1
DA:30,1
DA:31,1
DA:32,1
DA:33,1
DA:34,1
DA:35,1
DA:36,1
DA:37,1
DA:38,1
DA:39,1
DA:40,1
DA:41,1
DA:42,1
DA:43,1
DA:44,1
DA:45,1
DA:46,1
DA:47,1
DA:48,1
DA:49,1
DA:50,1
DA:51,1
DA:52,1
DA:53,1
DA:54,1
DA:55,1
DA:56,1
DA:57,1
DA:58,1
DA:59,1
DA:60,1
DA:61,1
DA:62,1
DA:63,1
DA:64,1
DA:65,1
DA:66,8
DA:67,8
DA:68,8
DA:69,8
DA:70,8
DA:71,8
DA:72,8
DA:73,8
DA:74,8
DA:75,8
DA:76,8
DA:77,8
DA:78,8
DA:79,8
DA:80,8
DA:81,8
DA:82,8
DA:83,8
DA:84,8
DA:85,8
DA:86,8
DA:87,8
DA:88,8
DA:89,8
DA:90,8
DA:91,8
DA:92,8
DA:93,8
DA:94,8
DA:95,8
DA:96,8
DA:97,8
DA:98,8
DA:99,8
DA:100,8
DA:101,8
DA:102,8
DA:103,8
DA:104,8
DA:105,8
DA:106,8
DA:107,8
DA:108,8
DA:109,8
DA:110,8
DA:111,8
DA:112,8
DA:113,8
DA:114,12
DA:115,12
DA:116,12
DA:117,1
DA:118,1
DA:119,11
DA:120,11
DA:121,11
DA:122,11
DA:123,8
DA:124,8
DA:125,8
DA:126,8
DA:127,8
DA:128,8
DA:129,58
DA:130,8
DA:131,8
DA:132,8
DA:133,8
DA:134,8
DA:135,8
DA:136,23
DA:137,23
DA:138,23
DA:139,23
DA:140,23
DA:141,23
DA:142,23
DA:143,23
DA:144,0
DA:145,0
DA:146,0
DA:147,0
DA:148,0
DA:149,23
DA:150,23
DA:151,8
DA:152,8
DA:153,8
DA:154,8
DA:155,8
DA:156,8
DA:157,8
DA:158,42
DA:159,8
DA:160,8
DA:161,8
DA:162,8
DA:163,8
DA:164,8
DA:165,8
DA:166,8
DA:167,23
DA:168,8
DA:169,8
DA:170,23
DA:171,23
DA:172,17
DA:173,17
DA:174,23
DA:175,23
DA:176,8
DA:177,8
DA:178,8
DA:179,8
DA:180,8
DA:181,8
DA:182,8
DA:183,8
DA:184,8
DA:185,8
DA:186,0
DA:187,0
DA:188,0
DA:189,0
DA:190,0
DA:191,0
DA:192,0
DA:193,0
DA:194,0
DA:195,0
DA:196,0
DA:197,8
DA:198,8
DA:199,8
DA:200,8
DA:201,8
DA:202,8
DA:203,8
DA:204,8
DA:205,12
DA:206,12
DA:207,12
DA:208,12
DA:209,12
DA:210,8
DA:211,8
DA:212,8
DA:213,16
DA:214,16
DA:215,16
DA:216,16
DA:217,16
DA:218,16
DA:219,19
DA:220,19
DA:221,4
DA:222,4
DA:223,4
DA:224,15
DA:225,15
DA:226,19
DA:227,1
DA:228,1
DA:229,1
DA:230,19
DA:231,16
DA:232,8
DA:233,8
DA:234,8
DA:235,8
DA:236,8
DA:237,8
DA:238,15
DA:239,15
DA:240,2
DA:241,2
DA:242,1
DA:243,1
DA:244,2
DA:245,15
DA:246,15
DA:247,15
DA:248,1
DA:249,1
DA:250,1
DA:251,1
DA:252,1
DA:253,15
DA:254,15
DA:255,8
DA:256,8
DA:257,8
DA:258,8
DA:259,8
DA:260,8
DA:261,32
DA:262,32
DA:263,32
DA:264,32
DA:265,32
DA:266,32
DA:267,32
DA:268,32
DA:269,8
DA:270,8
DA:271,8
DA:272,32
DA:273,32
DA:274,32
DA:275,32
DA:276,32
DA:277,32
DA:278,8
DA:279,1
DA:280,1
LF:280
LH:264
BRDA:66,0,0,8
BRDA:113,1,0,12
BRDA:116,2,0,1
BRDA:119,3,0,11
BRDA:128,4,0,58
BRDA:129,5,0,12
BRDA:135,6,0,23
BRDA:143,7,0,0
BRDA:157,8,0,42
BRDA:166,9,0,23
BRDA:167,10,0,8
BRDA:171,11,0,17
BRDA:204,12,0,12
BRDA:237,13,0,15
BRDA:239,14,0,2
BRDA:241,15,0,1
BRDA:242,16,0,0
BRDA:247,17,0,1
BRDA:242,18,0,1
BRDA:260,19,0,32
BRDA:212,20,0,16
BRDA:218,21,0,19
BRDA:219,22,0,5
BRDA:219,23,0,14
BRDA:220,24,0,4
BRDA:224,25,0,15
BRDA:226,26,0,1
BRDA:271,27,0,32
BRF:28
BRH:26
end_of_record
TN:
SF:src/index.ts
FNF:0
FNH:0
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
LF:8
LH:8
BRF:0
BRH:0
end_of_record
TN:
SF:src/input-group.tsx
FN:12,useTextAttribute
FN:21,onChange
FN:43,InputGroup
FNF:3
FNH:3
FNDA:29,useTextAttribute
FNDA:15,onChange
FNDA:29,InputGroup
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,29
DA:14,29
DA:15,29
DA:16,29
DA:17,29
DA:18,29
DA:19,29
DA:20,29
DA:21,29
DA:22,15
DA:23,29
DA:24,29
DA:25,29
DA:26,29
DA:27,1
DA:28,1
DA:29,1
DA:30,1
DA:31,1
DA:32,1
DA:33,1
DA:34,1
DA:35,1
DA:36,1
DA:37,1
DA:38,1
DA:39,1
DA:40,1
DA:41,1
DA:42,1
DA:43,1
DA:44,29
DA:45,29
DA:46,1
DA:47,1
LF:47
LH:47
BRDA:12,0,0,29
BRDA:21,1,0,15
BRDA:43,2,0,29
BRF:3
BRH:3
end_of_record
TN:
SF:src/list-group.tsx
FN:22,ListGroup
FN:30,add
FN:38,newItem
FN:55,ListOption
FNF:4
FNH:3
FNDA:17,ListGroup
FNDA:2,add
FNDA:0,newItem
FNDA:17,ListOption
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,1
DA:16,1
DA:17,1
DA:18,1
DA:19,1
DA:20,1
DA:21,1
DA:22,1
DA:23,17
DA:24,17
DA:25,17
DA:26,17
DA:27,0
DA:28,0
DA:29,17
DA:30,17
DA:31,2
DA:32,17
DA:33,17
DA:34,17
DA:35,17
DA:36,1
DA:37,1
DA:38,1
DA:39,1
DA:40,1
DA:41,1
DA:42,1
DA:43,1
DA:44,1
DA:45,1
DA:46,1
DA:47,1
DA:48,1
DA:49,1
DA:50,1
DA:51,1
DA:52,1
DA:53,1
DA:54,1
DA:55,1
DA:56,17
DA:57,17
DA:58,17
DA:59,17
DA:60,17
DA:61,24
DA:62,24
DA:63,24
DA:64,17
DA:65,17
DA:66,17
DA:67,17
DA:68,1
DA:69,1
LF:69
LH:67
BRDA:22,0,0,17
BRDA:26,1,0,0
BRDA:30,2,0,2
BRDA:55,3,0,17
BRDA:60,4,0,24
BRF:5
BRH:4
end_of_record
TN:
SF:src/radio-group.tsx
FN:29,RadioGroup
FN:40,RadioOption
FN:58,onChange
FNF:3
FNH:3
FNDA:3,RadioGroup
FNDA:3,RadioOption
FNDA:2,onChange
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,1
DA:16,1
DA:17,1
DA:18,1
DA:19,1
DA:20,1
DA:21,1
DA:22,1
DA:23,1
DA:24,1
DA:25,1
DA:26,1
DA:27,1
DA:28,1
DA:29,1
DA:30,3
DA:31,3
DA:32,3
DA:33,3
DA:34,3
DA:35,1
DA:36,1
DA:37,1
DA:38,1
DA:39,1
DA:40,1
DA:41,3
DA:42,3
DA:43,3
DA:44,3
DA:45,3
DA:46,3
DA:47,3
DA:48,3
DA:49,3
DA:50,6
DA:51,6
DA:52,6
DA:53,6
DA:54,6
DA:55,6
DA:56,6
DA:57,6
DA:58,6
DA:59,6
DA:60,6
DA:61,3
DA:62,3
DA:63,3
DA:64,3
DA:65,1
DA:66,1
LF:66
LH:66
BRDA:29,0,0,3
BRDA:40,1,0,3
BRDA:49,2,0,6
BRDA:58,3,0,2
BRF:4
BRH:4
end_of_record
TN:
SF:src/select-group.tsx
FN:8,filterOptions
FN:14,useSelectAttribute
FN:24,onChange
FN:40,SelectGroup
FNF:4
FNH:4
FNDA:1,filterOptions
FNDA:4,useSelectAttribute
FNDA:2,onChange
FNDA:4,SelectGroup
DA:1,1
DA:2,1
DA:3,1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
DA:9,1
DA:10,1
DA:11,1
DA:12,1
DA:13,1
DA:14,1
DA:15,4
DA:16,4
DA:17,4
DA:18,4
DA:19,4
DA:20,4
DA:21,4
DA:22,4
DA:23,4
DA:24,4
DA:25,2
DA:26,4
DA:27,4
DA:28,4
DA:29,4
DA:30,1
DA:31,1
DA:32,1
DA:33,1
DA:34,1
DA:35,1
DA:36,1
DA:37,1
DA:38,1
DA:39,1
DA:40,1
DA:41,4
DA:42,4
DA:43,1
DA:44,1
LF:44
LH:44
BRDA:8,0,0,1
BRDA:10,1,0,1
BRDA:11,2,0,1
BRDA:14,3,0,4
BRDA:22,4,0,2
BRDA:22,5,0,2
BRDA:24,6,0,2
BRDA:25,7,0,1
BRDA:25,8,0,1
BRDA:40,9,0,4
BRF:10
BRH:10
end_of_record

197
jest.config.ts Normal file
View file

@ -0,0 +1,197 @@
/*
* For a detailed explanation regarding each configuration property and type check, visit:
* https://jestjs.io/docs/configuration
*/
export default {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
collectCoverageFrom: ["src/**/**"],
// The directory where Jest should output its coverage files
// coverageDirectory: undefined,
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// The default configuration for fake timers
// fakeTimers: {
// "enableGlobally": false
// },
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "mjs",
// "cjs",
// "jsx",
// "ts",
// "tsx",
// "json",
// "node"
// ],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
preset: "ts-jest",
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state before every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state and implementation before every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
// testEnvironment: "jsdom",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
// testRunner: "jest-circus/runner",
// A map from regular expressions to paths to transformers
transform: {
"^.+\\.[jt]s$": "ts-jest",
},
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/",
// "\\.pnp\\.[^\\/]+$"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};

47
package.json Normal file
View file

@ -0,0 +1,47 @@
{
"name": "@adeattwood/diff-cov",
"version": "0.0.1",
"description": "Simple CLI to get test coverage on a diff",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"author": {
"name": "Ade Attwood",
"email": "code@adeattwood.co.uk",
"url": "https://adeattwood.co.uk"
},
"bin": {
"diff-cov": "./bin/diff-cov.js"
},
"files": [
"lib/**/*",
"bin/**/*",
"README.md"
],
"keywords": [
"diff",
"coverage",
"lcov"
],
"scripts": {
"test": "jest",
"lint": "eslint src tests",
"build": "tsc"
},
"dependencies": {
"@types/node": "^18.11.4",
"yargs": "^17.3.1"
},
"devDependencies": {
"@types/jest": "^29.1.1",
"@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1",
"eslint": "^8.25.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.1.2",
"prettier": "^2.7.1",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typescript": "^4.8.4"
}
}

231
src/diff-parser.js Normal file
View file

@ -0,0 +1,231 @@
export const parseDiff = (input) => {
if (!input) return [];
if (typeof input !== "string" || input.match(/^\s+$/)) return [];
const lines = input.split("\n");
if (lines.length === 0) return [];
const files = [];
let currentFile = null;
let currentChunk = null;
let deletedLineCounter = 0;
let addedLineCounter = 0;
let currentFileChanges = null;
const normal = (line) => {
currentChunk?.changes.push({
type: "normal",
normal: true,
ln1: deletedLineCounter++,
ln2: addedLineCounter++,
content: line,
});
currentFileChanges.oldLines--;
currentFileChanges.newLines--;
};
const start = (line) => {
const [fromFileName, toFileName] = parseFiles(line) ?? [];
currentFile = {
chunks: [],
deletions: 0,
additions: 0,
from: fromFileName,
to: toFileName,
};
files.push(currentFile);
};
const restart = () => {
if (!currentFile || currentFile.chunks.length) start();
};
const newFile = () => {
restart();
currentFile.new = true;
currentFile.from = "/dev/null";
};
const deletedFile = () => {
restart();
currentFile.deleted = true;
currentFile.to = "/dev/null";
};
const index = (line) => {
restart();
currentFile.index = line.split(" ").slice(1);
};
const fromFile = (line) => {
restart();
currentFile.from = parseOldOrNewFile(line);
};
const toFile = (line) => {
restart();
currentFile.to = parseOldOrNewFile(line);
};
const toNumOfLines = (number) => +(number || 1);
const chunk = (line, match) => {
if (!currentFile) return;
const [oldStart, oldNumLines, newStart, newNumLines] = match.slice(1);
deletedLineCounter = +oldStart;
addedLineCounter = +newStart;
currentChunk = {
content: line,
changes: [],
oldStart: +oldStart,
oldLines: toNumOfLines(oldNumLines),
newStart: +newStart,
newLines: toNumOfLines(newNumLines),
};
currentFileChanges = {
oldLines: toNumOfLines(oldNumLines),
newLines: toNumOfLines(newNumLines),
};
currentFile.chunks.push(currentChunk);
};
const del = (line) => {
if (!currentChunk) return;
currentChunk.changes.push({
type: "del",
del: true,
ln: deletedLineCounter++,
content: line,
});
currentFile.deletions++;
currentFileChanges.oldLines--;
};
const add = (line) => {
if (!currentChunk) return;
currentChunk.changes.push({
type: "add",
add: true,
ln: addedLineCounter++,
content: line,
});
currentFile.additions++;
currentFileChanges.newLines--;
};
const eof = (line) => {
if (!currentChunk) return;
const [mostRecentChange] = currentChunk.changes.slice(-1);
currentChunk.changes.push({
type: mostRecentChange.type,
[mostRecentChange.type]: true,
ln1: mostRecentChange.ln1,
ln2: mostRecentChange.ln2,
ln: mostRecentChange.ln,
content: line,
});
};
const schemaHeaders = [
[/^diff\s/, start],
[/^new file mode \d+$/, newFile],
[/^deleted file mode \d+$/, deletedFile],
[/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
[/^---\s/, fromFile],
[/^\+\+\+\s/, toFile],
[/^@@\s+-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
[/^\\ No newline at end of file$/, eof],
];
const schemaContent = [
[/^-/, del],
[/^\+/, add],
[/^\s+/, normal],
];
const parseContentLine = (line) => {
for (const [pattern, handler] of schemaContent) {
const match = line.match(pattern);
if (match) {
handler(line, match);
break;
}
}
if (currentFileChanges.oldLines === 0 && currentFileChanges.newLines === 0) {
currentFileChanges = null;
}
};
const parseHeaderLine = (line) => {
for (const [pattern, handler] of schemaHeaders) {
const match = line.match(pattern);
if (match) {
handler(line, match);
break;
}
}
};
const parseLine = (line) => {
if (currentFileChanges) {
parseContentLine(line);
} else {
parseHeaderLine(line);
}
return;
};
for (const line of lines) parseLine(line);
return files;
};
const fileNameDiffRegex = /a\/.*(?=["']? ["']?b\/)|b\/.*$/g;
const gitFileHeaderRegex = /^(a|b)\//;
const parseFiles = (line) => {
let fileNames = line?.match(fileNameDiffRegex);
return fileNames?.map((fileName) => fileName.replace(gitFileHeaderRegex, "").replace(/("|')$/, ""));
};
const qoutedFileNameRegex = /^\\?['"]|\\?['"]$/g;
const parseOldOrNewFile = (line) => {
let fileName = leftTrimChars(line, "-+").trim();
fileName = removeTimeStamp(fileName);
return fileName.replace(qoutedFileNameRegex, "").replace(gitFileHeaderRegex, "");
};
const leftTrimChars = (string, trimmingChars) => {
string = makeString(string);
if (!trimmingChars && String.prototype.trimLeft) return string.trimLeft();
let trimmingString = formTrimmingString(trimmingChars);
return string.replace(new RegExp(`^${trimmingString}+`), "");
};
const timeStampRegex = /\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d/;
const removeTimeStamp = (string) => {
const timeStamp = timeStampRegex.exec(string);
if (timeStamp) {
string = string.substring(0, timeStamp.index).trim();
}
return string;
};
const formTrimmingString = (trimmingChars) => {
if (trimmingChars === null || trimmingChars === undefined) return "\\s";
else if (trimmingChars instanceof RegExp) return trimmingChars.source;
return `[${makeString(trimmingChars).replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1")}]`;
};
const makeString = (itemToConvert) => (itemToConvert ?? "") + "";
export default parseDiff;

28
src/exec.ts Normal file
View file

@ -0,0 +1,28 @@
import { exec, ExecException } from "child_process";
interface ExecResult {
code: number;
stderr: string;
stdout: string;
}
const getCode = (error: ExecException | null) => {
if (!error) {
return 0;
}
return error.code || 127;
};
export const run = (command: string) =>
new Promise<ExecResult>((resolve) => {
exec(command, (error, stdout, stderr) => {
resolve({
code: getCode(error),
stderr,
stdout,
});
});
});
export default run;

37
src/index.ts Normal file
View file

@ -0,0 +1,37 @@
import yargs from "yargs";
import type { Options } from "yargs";
import { hideBin } from "yargs/helpers";
import exec from "./exec";
import report from "./report";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const parseDiff = require("./diff-parser");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const parseLcov = require("./lcov-parser");
export const error = (message: string) => {
console.error(message);
};
const options: { [key: string]: Options } = {
coverageFile: {
default: "./lcov.info",
description: "The path to the lcov report file",
type: "string",
},
};
export const run = async (argv = process.argv) => {
const parsed: any = yargs(hideBin(argv)).options(options).argv;
const diffText = await exec(`git diff origin/HEAD...HEAD`);
if (diffText.code > 0) {
return error("Error loading the diff\n\n" + diffText.stderr);
}
const diff = parseDiff.default(diffText.stdout);
const coverage = await parseLcov.default(parsed.coverageFile);
report(diff, coverage);
};

130
src/lcov-parser.js Normal file
View file

@ -0,0 +1,130 @@
/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/
import fs from "fs";
const exists = fs.exists;
var walkFile = function (str, cb) {
var data = [],
item;
["end_of_record"].concat(str.split("\n")).forEach(function (line) {
line = line.trim();
var allparts = line.split(":"),
parts = [allparts.shift(), allparts.join(":")],
lines,
fn;
switch (parts[0].toUpperCase()) {
case "TN":
item.title = parts[1].trim();
break;
case "SF":
item.file = parts.slice(1).join(":").trim();
break;
case "FNF":
item.functions.found = Number(parts[1].trim());
break;
case "FNH":
item.functions.hit = Number(parts[1].trim());
break;
case "LF":
item.lines.found = Number(parts[1].trim());
break;
case "LH":
item.lines.hit = Number(parts[1].trim());
break;
case "DA":
lines = parts[1].split(",");
item.lines.details.push({
line: Number(lines[0]),
hit: Number(lines[1]),
});
break;
case "FN":
fn = parts[1].split(",");
item.functions.details.push({
name: fn[1],
line: Number(fn[0]),
});
break;
case "FNDA":
fn = parts[1].split(",");
item.functions.details.some(function (i, k) {
if (i.name === fn[1] && i.hit === undefined) {
item.functions.details[k].hit = Number(fn[0]);
return true;
}
});
break;
case "BRDA":
fn = parts[1].split(",");
item.branches.details.push({
line: Number(fn[0]),
block: Number(fn[1]),
branch: Number(fn[2]),
taken: fn[3] === "-" ? 0 : Number(fn[3]),
});
break;
case "BRF":
item.branches.found = Number(parts[1]);
break;
case "BRH":
item.branches.hit = Number(parts[1]);
break;
}
if (line.indexOf("end_of_record") > -1) {
data.push(item);
item = {
lines: {
found: 0,
hit: 0,
details: [],
},
functions: {
hit: 0,
found: 0,
details: [],
},
branches: {
hit: 0,
found: 0,
details: [],
},
};
}
});
data.shift();
if (data.length) {
cb(null, data);
} else {
cb("Failed to parse string");
}
};
const parseInternal = function (file, cb) {
exists(file, function (x) {
if (!x) {
return walkFile(file, cb);
}
fs.readFile(file, "utf8", function (err, str) {
walkFile(str, cb);
});
});
};
export const parse = (file) =>
new Promise((resolve, reject) => {
parseInternal(file, (error, coverage) => {
error ? reject(error) : resolve(coverage);
});
});
export default parse;

84
src/report.ts Normal file
View file

@ -0,0 +1,84 @@
const getCoverageForFile = (file: any, coverage: any) => {
for (const cov of coverage) {
const report: { [k: number]: number } = {};
if (cov.file === file.to) {
for (const detail of cov.lines.details) {
report[detail.line] = detail.hit;
}
for (const detail of cov.functions.details) {
if (!report[detail.line]) {
report[detail.line] = detail.hit;
}
}
return report;
}
}
};
interface Change {
type: string;
ln: number;
ln2: number;
content: string;
}
interface Chunk {
content: string;
changes: Change[];
}
interface Diff {
to: string;
chunks: Chunk[];
}
export const printReport = (diff: Diff[], coverage: any) => {
const report = { total: 0, covered: 0 };
for (const file of diff) {
const fileCoverage = getCoverageForFile(file, coverage);
if (typeof fileCoverage === "undefined") {
continue;
}
console.log();
console.log(file.to);
for (const chunk of file.chunks) {
console.log();
console.log(chunk.content);
console.log();
for (const change of chunk.changes) {
if (change.type === "del") {
continue;
}
const line = change.ln || change.ln2;
let color = "\x1b[0m";
if (typeof fileCoverage[line] !== "undefined") {
color = fileCoverage[line] > 0 ? "\x1b[32m" : "\x1b[31m";
report.total++;
if (fileCoverage[line] > 0) {
report.covered++;
}
}
console.log(line.toString().padStart(4, " "), color, change.content.substring(1), "\x1b[0m");
}
}
}
const percentage = (report.covered / report.total) * 100;
const color = percentage > 90 ? "\x1b[32m" : "\x1b[31m";
console.log("");
console.log("Total Lines: ", report.total.toString());
console.log("Lines Covered: ", report.covered.toString());
console.log("Coverage Percentage", color, percentage.toString() + "%", "\x1b[0m");
return report;
};
export default printReport;

View file

@ -0,0 +1,231 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`parse 1.diff 1`] = `
[
{
"additions": 5,
"chunks": [
{
"changes": [
{
"add": true,
"content": "+export * from "./attribute-context";",
"ln": 1,
"type": "add",
},
{
"add": true,
"content": "+export * from "./check-group";",
"ln": 2,
"type": "add",
},
{
"add": true,
"content": "+export * from "./form-context";",
"ln": 3,
"type": "add",
},
{
"content": " export * from "./form";",
"ln1": 1,
"ln2": 4,
"normal": true,
"type": "normal",
},
{
"content": " export * from "./input-group";",
"ln1": 2,
"ln2": 5,
"normal": true,
"type": "normal",
},
{
"add": true,
"content": "+export * from "./list-group";",
"ln": 6,
"type": "add",
},
{
"add": true,
"content": "+export * from "./radio-group";",
"ln": 7,
"type": "add",
},
{
"content": " export * from "./select-group";",
"ln1": 3,
"ln2": 8,
"normal": true,
"type": "normal",
},
],
"content": "@@ -1,3 +1,8 @@",
"newLines": 8,
"newStart": 1,
"oldLines": 3,
"oldStart": 1,
},
],
"deletions": 0,
"from": "src/index.ts",
"index": [
"d70a331..9515bb8",
"100644",
],
"to": "src/index.ts",
},
{
"additions": 22,
"chunks": [
{
"changes": [
{
"add": true,
"content": "+import * as ReactForm from "../src";",
"ln": 1,
"type": "add",
},
{
"add": true,
"content": "+",
"ln": 2,
"type": "add",
},
{
"add": true,
"content": "+test.each([",
"ln": 3,
"type": "add",
},
{
"add": true,
"content": "+ // Components",
"ln": 4,
"type": "add",
},
{
"add": true,
"content": "+ "CheckGroup",",
"ln": 5,
"type": "add",
},
{
"add": true,
"content": "+ "Form",",
"ln": 6,
"type": "add",
},
{
"add": true,
"content": "+ "InputGroup",",
"ln": 7,
"type": "add",
},
{
"add": true,
"content": "+ "ListGroup",",
"ln": 8,
"type": "add",
},
{
"add": true,
"content": "+ "ListOption",",
"ln": 9,
"type": "add",
},
{
"add": true,
"content": "+ "RadioGroup",",
"ln": 10,
"type": "add",
},
{
"add": true,
"content": "+ "RadioOption",",
"ln": 11,
"type": "add",
},
{
"add": true,
"content": "+ "SelectGroup",",
"ln": 12,
"type": "add",
},
{
"add": true,
"content": "+",
"ln": 13,
"type": "add",
},
{
"add": true,
"content": "+ // Hooks",
"ln": 14,
"type": "add",
},
{
"add": true,
"content": "+ "useAttributeContext",",
"ln": 15,
"type": "add",
},
{
"add": true,
"content": "+ "useCheckboxAttribute",",
"ln": 16,
"type": "add",
},
{
"add": true,
"content": "+ "useFormContext",",
"ln": 17,
"type": "add",
},
{
"add": true,
"content": "+ "useSelectAttribute",",
"ln": 18,
"type": "add",
},
{
"add": true,
"content": "+ "useTextAttribute",",
"ln": 19,
"type": "add",
},
{
"add": true,
"content": "+])("'%s' is exported from the index file", (variable: string) => {",
"ln": 20,
"type": "add",
},
{
"add": true,
"content": "+ expect(ReactForm[variable as keyof typeof ReactForm]).not.toBeUndefined();",
"ln": 21,
"type": "add",
},
{
"add": true,
"content": "+});",
"ln": 22,
"type": "add",
},
],
"content": "@@ -0,0 +1,22 @@",
"newLines": 22,
"newStart": 1,
"oldLines": 0,
"oldStart": 0,
},
],
"deletions": 0,
"from": "/dev/null",
"index": [
"0000000..778e42f",
],
"new": true,
"to": "tests/index.spec.tsx",
},
]
`;

File diff suppressed because it is too large Load diff

11
tests/parse-diff.spec.ts Normal file
View file

@ -0,0 +1,11 @@
import fs from "fs";
import path from "path";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const parseDiff = require("../src/diff-parser");
test.each(["1.diff"])("parse %s", async (diffFile) => {
const diffFilePath = path.resolve(__dirname, "..", "data", diffFile);
const diffContent = fs.readFileSync(diffFilePath).toString();
expect(parseDiff.default(diffContent)).toMatchSnapshot();
});

11
tests/parse-lcov.spec.ts Normal file
View file

@ -0,0 +1,11 @@
import fs from "fs";
import path from "path";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const parseLcov = require("../src/lcov-parser");
test.each(["1.lcov.info"])("parse %s", async (lcovFile) => {
const lcovFilePath = path.resolve(__dirname, "..", "data", lcovFile);
const lcovContent = fs.readFileSync(lcovFilePath).toString();
expect(await parseLcov.default(lcovContent)).toMatchSnapshot();
});

104
tsconfig.json Normal file
View file

@ -0,0 +1,104 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "react" /* Specify what JSX code is generated. */,
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "CommonJS" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./lib" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["src"]
}

2875
yarn.lock Normal file

File diff suppressed because it is too large Load diff