| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d3fea00 commit 8ea1fc5
20 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -931,11 +931,19 @@ in the `$schema` must be replaced with the version of Node.js you are using. | |||
| 931 | 931 | ], | |
| 932 | 932 | "watch-path": "src", | |
| 933 | 933 | "watch-preserve-output": true | |
| 934 | + }, | ||
| 935 | + "testRunner": { | ||
| 936 | + "test-isolation": "process" | ||
| 934 | 937 | } | |
| 935 | 938 | } | |
| 936 | 939 | ``` | |
| 937 | 940 | ||
| 938 | - In the `nodeOptions` field, only flags that are allowed in [`NODE_OPTIONS`][] are supported. | ||
| 941 | + The configuration file supports namespace-specific options: | ||
| 942 | + | ||
| 943 | + * The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][]. | ||
| 944 | + | ||
| 945 | + * Namespace fields like `testRunner` contain configuration specific to that subsystem. | ||
| 946 | + | ||
| 939 | 947 | No-op flags are not supported. | |
| 940 | 948 | Not all V8 flags are currently supported. | |
| 941 | 949 | ||
@@ -949,7 +957,7 @@ For example, the configuration file above is equivalent to | |||
| 949 | 957 | the following command-line arguments: | |
| 950 | 958 | ||
| 951 | 959 | ```bash | |
| 952 | - node --import amaro/strip --watch-path=src --watch-preserve-output | ||
| 960 | + node --import amaro/strip --watch-path=src --watch-preserve-output --test-isolation=process | ||
| 953 | 961 | ``` | |
| 954 | 962 | ||
| 955 | 963 | The priority in configuration is as follows: | |
@@ -962,11 +970,10 @@ Values in the configuration file will not override the values in the environment | |||
| 962 | 970 | variables and command-line options, but will override the values in the `NODE_OPTIONS` | |
| 963 | 971 | env file parsed by the `--env-file` flag. | |
| 964 | 972 | ||
| 965 | - If duplicate keys are present in the configuration file, only | ||
| 966 | - the first key will be used. | ||
| 973 | + Keys cannot be duplicated within the same or different namespaces. | ||
| 967 | 974 | ||
| 968 | 975 | The configuration parser will throw an error if the configuration file contains | |
| 969 | - unknown keys or keys that cannot used in `NODE_OPTIONS`. | ||
| 976 | + unknown keys or keys that cannot be used in a namespace. | ||
| 970 | 977 | ||
| 971 | 978 | Node.js will not sanitize or perform validation on the user-provided configuration, | |
| 972 | 979 | so **NEVER** use untrusted configuration files. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -584,6 +584,135 @@ | |||
| 584 | 584 | } | |
| 585 | 585 | }, | |
| 586 | 586 | "type": "object" | |
| 587 | + }, | ||
| 588 | + "testRunner": { | ||
| 589 | + "type": "object", | ||
| 590 | + "additionalProperties": false, | ||
| 591 | + "properties": { | ||
| 592 | + "experimental-test-coverage": { | ||
| 593 | + "type": "boolean" | ||
| 594 | + }, | ||
| 595 | + "experimental-test-module-mocks": { | ||
| 596 | + "type": "boolean" | ||
| 597 | + }, | ||
| 598 | + "test-concurrency": { | ||
| 599 | + "type": "number" | ||
| 600 | + }, | ||
| 601 | + "test-coverage-branches": { | ||
| 602 | + "type": "number" | ||
| 603 | + }, | ||
| 604 | + "test-coverage-exclude": { | ||
| 605 | + "oneOf": [ | ||
| 606 | + { | ||
| 607 | + "type": "string" | ||
| 608 | + }, | ||
| 609 | + { | ||
| 610 | + "items": { | ||
| 611 | + "type": "string", | ||
| 612 | + "minItems": 1 | ||
| 613 | + }, | ||
| 614 | + "type": "array" | ||
| 615 | + } | ||
| 616 | + ] | ||
| 617 | + }, | ||
| 618 | + "test-coverage-functions": { | ||
| 619 | + "type": "number" | ||
| 620 | + }, | ||
| 621 | + "test-coverage-include": { | ||
| 622 | + "oneOf": [ | ||
| 623 | + { | ||
| 624 | + "type": "string" | ||
| 625 | + }, | ||
| 626 | + { | ||
| 627 | + "items": { | ||
| 628 | + "type": "string", | ||
| 629 | + "minItems": 1 | ||
| 630 | + }, | ||
| 631 | + "type": "array" | ||
| 632 | + } | ||
| 633 | + ] | ||
| 634 | + }, | ||
| 635 | + "test-coverage-lines": { | ||
| 636 | + "type": "number" | ||
| 637 | + }, | ||
| 638 | + "test-force-exit": { | ||
| 639 | + "type": "boolean" | ||
| 640 | + }, | ||
| 641 | + "test-global-setup": { | ||
| 642 | + "type": "string" | ||
| 643 | + }, | ||
| 644 | + "test-isolation": { | ||
| 645 | + "type": "string" | ||
| 646 | + }, | ||
| 647 | + "test-name-pattern": { | ||
| 648 | + "oneOf": [ | ||
| 649 | + { | ||
| 650 | + "type": "string" | ||
| 651 | + }, | ||
| 652 | + { | ||
| 653 | + "items": { | ||
| 654 | + "type": "string", | ||
| 655 | + "minItems": 1 | ||
| 656 | + }, | ||
| 657 | + "type": "array" | ||
| 658 | + } | ||
| 659 | + ] | ||
| 660 | + }, | ||
| 661 | + "test-only": { | ||
| 662 | + "type": "boolean" | ||
| 663 | + }, | ||
| 664 | + "test-reporter": { | ||
| 665 | + "oneOf": [ | ||
| 666 | + { | ||
| 667 | + "type": "string" | ||
| 668 | + }, | ||
| 669 | + { | ||
| 670 | + "items": { | ||
| 671 | + "type": "string", | ||
| 672 | + "minItems": 1 | ||
| 673 | + }, | ||
| 674 | + "type": "array" | ||
| 675 | + } | ||
| 676 | + ] | ||
| 677 | + }, | ||
| 678 | + "test-reporter-destination": { | ||
| 679 | + "oneOf": [ | ||
| 680 | + { | ||
| 681 | + "type": "string" | ||
| 682 | + }, | ||
| 683 | + { | ||
| 684 | + "items": { | ||
| 685 | + "type": "string", | ||
| 686 | + "minItems": 1 | ||
| 687 | + }, | ||
| 688 | + "type": "array" | ||
| 689 | + } | ||
| 690 | + ] | ||
| 691 | + }, | ||
| 692 | + "test-shard": { | ||
| 693 | + "type": "string" | ||
| 694 | + }, | ||
| 695 | + "test-skip-pattern": { | ||
| 696 | + "oneOf": [ | ||
| 697 | + { | ||
| 698 | + "type": "string" | ||
| 699 | + }, | ||
| 700 | + { | ||
| 701 | + "items": { | ||
| 702 | + "type": "string", | ||
| 703 | + "minItems": 1 | ||
| 704 | + }, | ||
| 705 | + "type": "array" | ||
| 706 | + } | ||
| 707 | + ] | ||
| 708 | + }, | ||
| 709 | + "test-timeout": { | ||
| 710 | + "type": "number" | ||
| 711 | + }, | ||
| 712 | + "test-update-snapshots": { | ||
| 713 | + "type": "boolean" | ||
| 714 | + } | ||
| 715 | + } | ||
| 587 | 716 | } | |
| 588 | 717 | }, | |
| 589 | 718 | "type": "object" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ const { | |||
| 13 | 13 | getCLIOptionsInfo, | |
| 14 | 14 | getEmbedderOptions: getEmbedderOptionsFromBinding, | |
| 15 | 15 | getEnvOptionsInputType, | |
| 16 | + getNamespaceOptionsInputType, | ||
| 16 | 17 | } = internalBinding('options'); | |
| 17 | 18 | ||
| 18 | 19 | let warnOnAllowUnauthorized = true; | |
@@ -38,7 +39,22 @@ function getEmbedderOptions() { | |||
| 38 | 39 | } | |
| 39 | 40 | ||
| 40 | 41 | function generateConfigJsonSchema() { | |
| 41 | - const map = getEnvOptionsInputType(); | ||
| 42 | + const envOptionsMap = getEnvOptionsInputType(); | ||
| 43 | + const namespaceOptionsMap = getNamespaceOptionsInputType(); | ||
| 44 | + | ||
| 45 | + function createPropertyForType(type) { | ||
| 46 | + if (type === 'array') { | ||
| 47 | + return { | ||
| 48 | + __proto__: null, | ||
| 49 | + oneOf: [ | ||
| 50 | + { __proto__: null, type: 'string' }, | ||
| 51 | + { __proto__: null, items: { __proto__: null, type: 'string', minItems: 1 }, type: 'array' }, | ||
| 52 | + ], | ||
| 53 | + }; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + return { __proto__: null, type }; | ||
| 57 | + } | ||
| 42 | 58 | ||
| 43 | 59 | const schema = { | |
| 44 | 60 | __proto__: null, | |
@@ -60,31 +76,58 @@ function generateConfigJsonSchema() { | |||
| 60 | 76 | type: 'object', | |
| 61 | 77 | }; | |
| 62 | 78 | ||
| 63 | - const nodeOptions = schema.properties.nodeOptions.properties; | ||
| 79 | + // Get the root properties object for adding namespaces | ||
| 80 | + const rootProperties = schema.properties; | ||
| 81 | + const nodeOptions = rootProperties.nodeOptions.properties; | ||
| 64 | 82 | ||
| 65 | - for (const { 0: key, 1: type } of map) { | ||
| 83 | + // Add env options to nodeOptions (backward compatibility) | ||
| 84 | + for (const { 0: key, 1: type } of envOptionsMap) { | ||
| 66 | 85 | const keyWithoutPrefix = StringPrototypeReplace(key, '--', ''); | |
| 67 | - if (type === 'array') { | ||
| 68 | - nodeOptions[keyWithoutPrefix] = { | ||
| 69 | - __proto__: null, | ||
| 70 | - oneOf: [ | ||
| 71 | - { __proto__: null, type: 'string' }, | ||
| 72 | - { __proto__: null, items: { __proto__: null, type: 'string', minItems: 1 }, type: 'array' }, | ||
| 73 | - ], | ||
| 74 | - }; | ||
| 75 | - } else { | ||
| 76 | - nodeOptions[keyWithoutPrefix] = { __proto__: null, type }; | ||
| 86 | + nodeOptions[keyWithoutPrefix] = createPropertyForType(type); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + // Add namespace properties at the root level | ||
| 90 | + for (const { 0: namespace, 1: optionsMap } of namespaceOptionsMap) { | ||
| 91 | + // Create namespace object at the root level | ||
| 92 | + rootProperties[namespace] = { | ||
| 93 | + __proto__: null, | ||
| 94 | + type: 'object', | ||
| 95 | + additionalProperties: false, | ||
| 96 | + properties: { __proto__: null }, | ||
| 97 | + }; | ||
| 98 | + | ||
| 99 | + const namespaceProperties = rootProperties[namespace].properties; | ||
| 100 | + | ||
| 101 | + // Add all options for this namespace | ||
| 102 | + for (const { 0: optionName, 1: optionType } of optionsMap) { | ||
| 103 | + const keyWithoutPrefix = StringPrototypeReplace(optionName, '--', ''); | ||
| 104 | + namespaceProperties[keyWithoutPrefix] = createPropertyForType(optionType); | ||
| 77 | 105 | } | |
| 106 | + | ||
| 107 | + // Sort the namespace properties alphabetically | ||
| 108 | + const sortedNamespaceKeys = ArrayPrototypeSort(ObjectKeys(namespaceProperties)); | ||
| 109 | + const sortedNamespaceProperties = ObjectFromEntries( | ||
| 110 | + ArrayPrototypeMap(sortedNamespaceKeys, (key) => [key, namespaceProperties[key]]), | ||
| 111 | + ); | ||
| 112 | + rootProperties[namespace].properties = sortedNamespaceProperties; | ||
| 78 | 113 | } | |
| 79 | 114 | ||
| 80 | - // Sort the proerties by key alphabetically. | ||
| 115 | + // Sort the top-level properties by key alphabetically | ||
| 81 | 116 | const sortedKeys = ArrayPrototypeSort(ObjectKeys(nodeOptions)); | |
| 82 | 117 | const sortedProperties = ObjectFromEntries( | |
| 83 | 118 | ArrayPrototypeMap(sortedKeys, (key) => [key, nodeOptions[key]]), | |
| 84 | 119 | ); | |
| 85 | 120 | ||
| 86 | 121 | schema.properties.nodeOptions.properties = sortedProperties; | |
| 87 | 122 | ||
| 123 | + // Also sort the root level properties | ||
| 124 | + const sortedRootKeys = ArrayPrototypeSort(ObjectKeys(rootProperties)); | ||
| 125 | + const sortedRootProperties = ObjectFromEntries( | ||
| 126 | + ArrayPrototypeMap(sortedRootKeys, (key) => [key, rootProperties[key]]), | ||
| 127 | + ); | ||
| 128 | + | ||
| 129 | + schema.properties = sortedRootProperties; | ||
| 130 | + | ||
| 88 | 131 | return schema; | |
| 89 | 132 | } | |
| 90 | 133 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -98,7 +98,13 @@ let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { | |||
| 98 | 98 | }); | |
| 99 | 99 | ||
| 100 | 100 | const kIsolatedProcessName = Symbol('kIsolatedProcessName'); | |
| 101 | - const kFilterArgs = ['--test', '--experimental-test-coverage', '--watch']; | ||
| 101 | + const kFilterArgs = [ | ||
| 102 | + '--test', | ||
| 103 | + '--experimental-test-coverage', | ||
| 104 | + '--watch', | ||
| 105 | + '--experimental-default-config-file', | ||
| 106 | + '--experimental-config-file', | ||
| 107 | + ]; | ||
| 102 | 108 | const kFilterArgValues = ['--test-reporter', '--test-reporter-destination']; | |
| 103 | 109 | const kDiagnosticsFilterArgs = ['tests', 'suites', 'pass', 'fail', 'cancelled', 'skipped', 'todo', 'duration_ms']; | |
| 104 | 110 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -910,7 +910,7 @@ static ExitCode InitializeNodeWithArgsInternal( | |||
| 910 | 910 | default: | |
| 911 | 911 | UNREACHABLE(); | |
| 912 | 912 | } | |
| 913 | - node_options_from_config = per_process::config_reader.AssignNodeOptions(); | ||
| 913 | + node_options_from_config = per_process::config_reader.GetNodeOptions(); | ||
| 914 | 914 | // (@marco-ippolito) Avoid reparsing the env options again | |
| 915 | 915 | std::vector<std::string> env_argv_from_config = | |
| 916 | 916 | ParseNodeOptionsEnvVar(node_options_from_config, errors); | |
@@ -956,7 +956,19 @@ static ExitCode InitializeNodeWithArgsInternal( | |||
| 956 | 956 | #endif | |
| 957 | 957 | ||
| 958 | 958 | if (!(flags & ProcessInitializationFlags::kDisableCLIOptions)) { | |
| 959 | - const ExitCode exit_code = | ||
| 959 | + // Parse the options coming from the config file. | ||
| 960 | + // This is done before parsing the command line options | ||
| 961 | + // as the cli flags are expected to override the config file ones. | ||
| 962 | + std::vector<std::string> extra_argv = | ||
| 963 | + per_process::config_reader.GetNamespaceFlags(); | ||
| 964 | + // [0] is expected to be the program name, fill it in from the real argv. | ||
| 965 | + extra_argv.insert(extra_argv.begin(), argv->at(0)); | ||
| 966 | + // Parse the extra argv coming from the config file | ||
| 967 | + ExitCode exit_code = ProcessGlobalArgsInternal( | ||
| 968 | + &extra_argv, nullptr, errors, kDisallowedInEnvvar); | ||
| 969 | + if (exit_code != ExitCode::kNoFailure) return exit_code; | ||
| 970 | + // Parse options coming from the command line. | ||
| 971 | + exit_code = | ||
| 960 | 972 | ProcessGlobalArgsInternal(argv, exec_argv, errors, kDisallowedInEnvvar); | |
| 961 | 973 | if (exit_code != ExitCode::kNoFailure) return exit_code; | |
| 962 | 974 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments