| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,7 @@ | |||
| 1 | 1 | # Environment Variables | |
| 2 | 2 | ||
| 3 | + <!--introduced_in=v20.12.0--> | ||
| 4 | + | ||
| 3 | 5 | Environment variables are variables associated to the environment the Node.js process runs in. | |
| 4 | 6 | ||
| 5 | 7 | ## CLI Environment Variables | |
@@ -20,8 +22,6 @@ Set of utilities for dealing with additional environment variables defined in `. | |||
| 20 | 22 | ||
| 21 | 23 | > Stability: 2 - Stable | |
| 22 | 24 | ||
| 23 | - <!--introduced_in=v20.12.0--> | ||
| 24 | - | ||
| 25 | 25 | ### .env files | |
| 26 | 26 | ||
| 27 | 27 | `.env` files (also known as dotenv files) are files that define environment variables, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,162 @@ | |||
| 1 | + import * as common from '../common/index.mjs'; | ||
| 2 | + | ||
| 3 | + import assert from 'node:assert'; | ||
| 4 | + import { existsSync } from 'node:fs'; | ||
| 5 | + import fs from 'node:fs/promises'; | ||
| 6 | + import path from 'node:path'; | ||
| 7 | + | ||
| 8 | + // This tests that `make doc` generates the JSON documentation properly. | ||
| 9 | + // Note that for this test to pass, `make doc` must be run first. | ||
| 10 | + | ||
| 11 | + if (common.isWindows) { | ||
| 12 | + common.skip('`make doc` does not run on Windows'); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + function validateModule(module) { | ||
| 16 | + assert.strictEqual(typeof module, 'object'); | ||
| 17 | + assert.strictEqual(module.type, 'module'); | ||
| 18 | + assert.ok(module.name); | ||
| 19 | + assert.ok(module.textRaw); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + function validateMisc(misc) { | ||
| 23 | + assert.strictEqual(typeof misc, 'object'); | ||
| 24 | + assert.strictEqual(misc.type, 'misc'); | ||
| 25 | + assert.ok(misc.name); | ||
| 26 | + assert.strictEqual(typeof misc.name, 'string'); | ||
| 27 | + assert.ok(misc.textRaw); | ||
| 28 | + assert.strictEqual(typeof misc.textRaw, 'string'); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + let numberOfDeprecatedSections = 0; | ||
| 32 | + let numberOfRemovedAPIs = 0; | ||
| 33 | + | ||
| 34 | + const metaExpectedKeys = new Set([ | ||
| 35 | + 'added', | ||
| 36 | + 'changes', | ||
| 37 | + 'deprecated', | ||
| 38 | + 'napiVersion', | ||
| 39 | + 'removed', | ||
| 40 | + ]); | ||
| 41 | + | ||
| 42 | + function validateMeta(meta) { | ||
| 43 | + assert.partialDeepStrictEqual(metaExpectedKeys, new Set(Object.keys(meta))); | ||
| 44 | + assert.ok(!Object.hasOwn(meta, 'added') || Array.isArray(meta.added) || typeof meta.added === 'string'); | ||
| 45 | + if (meta.deprecated) { | ||
| 46 | + numberOfDeprecatedSections++; | ||
| 47 | + assert.ok(Array.isArray(meta.deprecated) || typeof meta.deprecated === 'string'); | ||
| 48 | + } | ||
| 49 | + if (meta.removed) { | ||
| 50 | + numberOfRemovedAPIs++; | ||
| 51 | + assert.ok(Array.isArray(meta.removed) || typeof meta.removed === 'string'); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + assert.ok(!Object.hasOwn(meta, 'napiVersion') || Number(meta.napiVersion)); | ||
| 55 | + assert.ok(Array.isArray(meta.changes)); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + function findAllKeys(obj, allKeys = new Set()) { | ||
| 59 | + for (const [key, value] of Object.entries(obj)) { | ||
| 60 | + if (Number.isNaN(Number(key))) allKeys.add(key); | ||
| 61 | + if (typeof value === 'object') findAllKeys(value, allKeys); | ||
| 62 | + | ||
| 63 | + if (key === 'miscs') { | ||
| 64 | + assert.ok(Array.isArray(value)); | ||
| 65 | + assert.ok(value.length); | ||
| 66 | + value.forEach(validateMisc); | ||
| 67 | + } else if (key === 'modules') { | ||
| 68 | + assert.ok(Array.isArray(value)); | ||
| 69 | + assert.ok(value.length); | ||
| 70 | + value.forEach(validateModule); | ||
| 71 | + } else if (key === 'meta') { | ||
| 72 | + validateMeta(value); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + return allKeys; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + const allExpectedKeys = new Set([ | ||
| 79 | + 'added', | ||
| 80 | + 'changes', | ||
| 81 | + 'classes', | ||
| 82 | + 'classMethods', | ||
| 83 | + 'commit', | ||
| 84 | + 'ctors', | ||
| 85 | + 'default', | ||
| 86 | + 'deprecated', | ||
| 87 | + 'desc', | ||
| 88 | + 'description', | ||
| 89 | + 'displayName', | ||
| 90 | + 'events', | ||
| 91 | + 'examples', | ||
| 92 | + 'globals', | ||
| 93 | + 'introduced_in', | ||
| 94 | + 'meta', | ||
| 95 | + 'methods', | ||
| 96 | + 'miscs', | ||
| 97 | + 'modules', | ||
| 98 | + 'name', | ||
| 99 | + 'napiVersion', | ||
| 100 | + 'options', | ||
| 101 | + 'params', | ||
| 102 | + 'pr-url', | ||
| 103 | + 'properties', | ||
| 104 | + 'removed', | ||
| 105 | + 'return', | ||
| 106 | + 'shortDesc', | ||
| 107 | + 'signatures', | ||
| 108 | + 'source', | ||
| 109 | + 'stability', | ||
| 110 | + 'stabilityText', | ||
| 111 | + 'textRaw', | ||
| 112 | + 'type', | ||
| 113 | + 'version', | ||
| 114 | + ]); | ||
| 115 | + | ||
| 116 | + for await (const dirent of await fs.opendir(new URL('../../out/doc/api/', import.meta.url))) { | ||
| 117 | + if (!dirent.name.endsWith('.md')) continue; | ||
| 118 | + | ||
| 119 | + const jsonPath = path.join(dirent.parentPath, dirent.name.slice(0, -2) + 'json'); | ||
| 120 | + const expectedSource = `doc/api/${dirent.name}`; | ||
| 121 | + if (dirent.name === 'quic.md') { | ||
| 122 | + assert.ok(!existsSync(jsonPath)); // QUIC documentation is not public yet | ||
| 123 | + continue; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + console.log('testing', jsonPath, 'based on', expectedSource); | ||
| 127 | + | ||
| 128 | + const fileContent = await fs.readFile(jsonPath, 'utf8'); | ||
| 129 | + // A proxy to check if the file is human readable is to count if it contains | ||
| 130 | + // at least 3 line return. | ||
| 131 | + assert.strictEqual(fileContent.split('\n', 3).length, 3); | ||
| 132 | + | ||
| 133 | + const json = JSON.parse(fileContent); | ||
| 134 | + | ||
| 135 | + assert.strictEqual(json.type, 'module'); | ||
| 136 | + assert.strictEqual(json.source, expectedSource); | ||
| 137 | + if (dirent.name !== 'index.md') { | ||
| 138 | + assert.ok(json.introduced_in || Object.values(json).at(-1)?.[0].introduced_in); | ||
| 139 | + } | ||
| 140 | + assert.deepStrictEqual(Object.keys(json), ['type', 'source', ...({ | ||
| 141 | + 'addons.md': ['introduced_in', 'miscs'], | ||
| 142 | + 'cli.md': ['introduced_in', 'miscs'], | ||
| 143 | + 'corepack.md': ['introduced_in', 'meta', 'stability', 'stabilityText', 'miscs'], | ||
| 144 | + 'debugger.md': ['introduced_in', 'stability', 'stabilityText', 'miscs'], | ||
| 145 | + 'deprecations.md': ['introduced_in', 'miscs'], | ||
| 146 | + 'documentation.md': ['introduced_in', 'miscs'], | ||
| 147 | + 'errors.md': ['introduced_in', 'classes', 'miscs'], | ||
| 148 | + 'esm.md': ['introduced_in', 'meta', 'stability', 'stabilityText', 'properties', 'miscs'], | ||
| 149 | + 'globals.md': ['introduced_in', 'stability', 'stabilityText', 'classes', 'methods', 'miscs'], | ||
| 150 | + 'index.md': [], | ||
| 151 | + 'intl.md': ['introduced_in', 'miscs'], | ||
| 152 | + 'n-api.md': ['introduced_in', 'stability', 'stabilityText', 'miscs'], | ||
| 153 | + 'packages.md': ['introduced_in', 'meta', 'miscs'], | ||
| 154 | + 'process.md': ['globals'], | ||
| 155 | + 'report.md': ['introduced_in', 'stability', 'stabilityText', 'meta', 'miscs'], | ||
| 156 | + }[dirent.name] ?? ['modules'])]); | ||
| 157 | + | ||
| 158 | + assert.partialDeepStrictEqual(allExpectedKeys, findAllKeys(json)); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + assert.strictEqual(numberOfDeprecatedSections, 39); // Increase this number every time a new API is deprecated. | ||
| 162 | + assert.strictEqual(numberOfRemovedAPIs, 46); // Increase this number every time a section is marked as removed. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments