Skip to content

Commit f0aae88

Browse files
authored
implement test specifier configuration (#64)
* implement test specifier configuration * implement a cheap check finding tests in files * parsing: refactor `parseSource` to not rely on any vscode.* code This allows unit test to be written and run without VS code. * implement logic for `require` with custom test specifiers * self code review * clarify documentation for configuration value * Check tests have valid names when using 'namespaced' imports
1 parent 7ad1de5 commit f0aae88

File tree

12 files changed

+920
-61
lines changed

12 files changed

+920
-61
lines changed

package.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,52 @@
147147
}
148148
}
149149
},
150+
"nodejs-testing.testSpecifiers": {
151+
"type": "array",
152+
"markdownDescription": "_Advanced_: A list of specifiers that indicate test function to search for:\nIt defaults to:\n\n```json\n[\n {\n \"import\": \"node:test\",\n \"name\": [\"default\", \"it\", \"test\", \"describe\", \"suite\"]\n }\n]\n```\n\nBut in case your test function is wrapped, you can specify it with a relative import:\nNOTE: relative imports must be prefixed with ./\nNOTE: A `name` of \"default\" is special and means the default export of that module is a test function\n\n```json\n[\n {\n \"import\": \"./test/utils.js\",\n \"name\": \"test\"\n }\n]\n```\n",
153+
"default": [
154+
{
155+
"import": "node:test",
156+
"name": [
157+
"default",
158+
"it",
159+
"test",
160+
"describe",
161+
"suite"
162+
]
163+
}
164+
],
165+
"items": {
166+
"type": "object",
167+
"default": {
168+
"import": "node:test",
169+
"name": [
170+
"default",
171+
"it",
172+
"test",
173+
"describe",
174+
"suite"
175+
]
176+
},
177+
"required": [
178+
"import",
179+
"name"
180+
],
181+
"properties": {
182+
"import": {
183+
"type": "string",
184+
"markdownDescription": "A package specifier (i.e. node:test) or workspace-relative path beginning with ./ (like ./test/utils.js) that indicates where the 'test' function can be imported from in your codebase"
185+
},
186+
"name": {
187+
"type": "array",
188+
"markdownDescription": "A list of functions that are imported from `import` that should be treated as test functions, the special name 'default' refers to the default export of a module",
189+
"items": {
190+
"type": "string"
191+
}
192+
}
193+
}
194+
}
195+
},
150196
"nodejs-testing.envFile": {
151197
"type": "string",
152198
"markdownDescription": "Absolute path to a file containing environment variable definitions.\n\nNote: template parameters like ${workspaceFolder} will be resolved.",

src/__snapshots__/parsing.test.ts.snap

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,3 +669,309 @@ exports[`extract > works with string literals 1`] = `
669669
},
670670
]
671671
`;
672+
673+
exports[`extract tests with custom specifiers > extracts default import tests 1`] = `
674+
[
675+
{
676+
"children": [
677+
{
678+
"children": [],
679+
"fn": "test",
680+
"location": SourceLocation {
681+
"end": Position {
682+
"column": 4,
683+
"line": 8,
684+
},
685+
"start": Position {
686+
"column": 2,
687+
"line": 6,
688+
},
689+
},
690+
"name": "nested test",
691+
},
692+
],
693+
"fn": "test",
694+
"location": SourceLocation {
695+
"end": Position {
696+
"column": 2,
697+
"line": 9,
698+
},
699+
"start": Position {
700+
"column": 0,
701+
"line": 4,
702+
},
703+
},
704+
"name": "default import test",
705+
},
706+
]
707+
`;
708+
709+
exports[`extract tests with custom specifiers > extracts named import tests 1`] = `
710+
[
711+
{
712+
"children": [],
713+
"fn": "wrappedTest",
714+
"location": SourceLocation {
715+
"end": Position {
716+
"column": 6,
717+
"line": 4,
718+
},
719+
"start": Position {
720+
"column": 4,
721+
"line": 2,
722+
},
723+
},
724+
"name": "addition",
725+
},
726+
]
727+
`;
728+
729+
exports[`extract tests with custom specifiers > extracts renamed named import test 1`] = `
730+
[
731+
{
732+
"children": [],
733+
"fn": "wrappedTest",
734+
"location": SourceLocation {
735+
"end": Position {
736+
"column": 6,
737+
"line": 4,
738+
},
739+
"start": Position {
740+
"column": 4,
741+
"line": 2,
742+
},
743+
},
744+
"name": "addition",
745+
},
746+
]
747+
`;
748+
749+
exports[`extract tests with custom specifiers > extracts renamed named import tests 1`] = `
750+
[
751+
{
752+
"children": [],
753+
"fn": "wrappedTest",
754+
"location": SourceLocation {
755+
"end": Position {
756+
"column": 6,
757+
"line": 4,
758+
},
759+
"start": Position {
760+
"column": 4,
761+
"line": 2,
762+
},
763+
},
764+
"name": "addition",
765+
},
766+
]
767+
`;
768+
769+
exports[`extract tests with custom specifiers > extracts star import tests 1`] = `
770+
[
771+
{
772+
"children": [
773+
{
774+
"children": [],
775+
"fn": "specialTest",
776+
"location": SourceLocation {
777+
"end": Position {
778+
"column": 8,
779+
"line": 10,
780+
},
781+
"start": Position {
782+
"column": 6,
783+
"line": 8,
784+
},
785+
},
786+
"name": "subtest",
787+
},
788+
],
789+
"fn": "specialTest",
790+
"location": SourceLocation {
791+
"end": Position {
792+
"column": 6,
793+
"line": 11,
794+
},
795+
"start": Position {
796+
"column": 4,
797+
"line": 2,
798+
},
799+
},
800+
"name": "addition",
801+
},
802+
]
803+
`;
804+
805+
exports[`extract with custom test specifiers in commonjs code > extracts aliased require 1`] = `
806+
[
807+
{
808+
"children": [
809+
{
810+
"children": [],
811+
"fn": "it",
812+
"location": SourceLocation {
813+
"end": Position {
814+
"column": 4,
815+
"line": 7,
816+
},
817+
"start": Position {
818+
"column": 2,
819+
"line": 5,
820+
},
821+
},
822+
"name": "nested test",
823+
},
824+
],
825+
"fn": "describe",
826+
"location": SourceLocation {
827+
"end": Position {
828+
"column": 2,
829+
"line": 8,
830+
},
831+
"start": Position {
832+
"column": 0,
833+
"line": 3,
834+
},
835+
},
836+
"name": "destructured test",
837+
},
838+
]
839+
`;
840+
841+
exports[`extract with custom test specifiers in commonjs code > extracts default require tests 1`] = `
842+
[
843+
{
844+
"children": [
845+
{
846+
"children": [],
847+
"fn": "test",
848+
"location": SourceLocation {
849+
"end": Position {
850+
"column": 4,
851+
"line": 7,
852+
},
853+
"start": Position {
854+
"column": 2,
855+
"line": 5,
856+
},
857+
},
858+
"name": "nested test",
859+
},
860+
],
861+
"fn": "test",
862+
"location": SourceLocation {
863+
"end": Position {
864+
"column": 2,
865+
"line": 8,
866+
},
867+
"start": Position {
868+
"column": 0,
869+
"line": 3,
870+
},
871+
},
872+
"name": "default import test",
873+
},
874+
]
875+
`;
876+
877+
exports[`extract with custom test specifiers in commonjs code > extracts destructed require 1`] = `
878+
[
879+
{
880+
"children": [
881+
{
882+
"children": [],
883+
"fn": "it",
884+
"location": SourceLocation {
885+
"end": Position {
886+
"column": 4,
887+
"line": 7,
888+
},
889+
"start": Position {
890+
"column": 2,
891+
"line": 5,
892+
},
893+
},
894+
"name": "nested test",
895+
},
896+
],
897+
"fn": "describe",
898+
"location": SourceLocation {
899+
"end": Position {
900+
"column": 2,
901+
"line": 8,
902+
},
903+
"start": Position {
904+
"column": 0,
905+
"line": 3,
906+
},
907+
},
908+
"name": "destructured test",
909+
},
910+
]
911+
`;
912+
913+
exports[`extract with custom test specifiers in commonjs code > extracts ts import mangled 1`] = `
914+
[
915+
{
916+
"children": [
917+
{
918+
"children": [],
919+
"fn": "it",
920+
"location": SourceLocation {
921+
"end": Position {
922+
"column": 6,
923+
"line": 8,
924+
},
925+
"start": Position {
926+
"column": 4,
927+
"line": 6,
928+
},
929+
},
930+
"name": "addition",
931+
},
932+
{
933+
"children": [],
934+
"fn": "it",
935+
"location": SourceLocation {
936+
"end": Position {
937+
"column": 6,
938+
"line": 11,
939+
},
940+
"start": Position {
941+
"column": 4,
942+
"line": 9,
943+
},
944+
},
945+
"name": "addition",
946+
},
947+
{
948+
"children": [],
949+
"fn": "it",
950+
"location": SourceLocation {
951+
"end": Position {
952+
"column": 6,
953+
"line": 14,
954+
},
955+
"start": Position {
956+
"column": 4,
957+
"line": 12,
958+
},
959+
},
960+
"name": "subtraction",
961+
},
962+
],
963+
"fn": "describe",
964+
"location": SourceLocation {
965+
"end": Position {
966+
"column": 2,
967+
"line": 15,
968+
},
969+
"start": Position {
970+
"column": 0,
971+
"line": 5,
972+
},
973+
},
974+
"name": "math",
975+
},
976+
]
977+
`;

0 commit comments

Comments
 (0)