Skip to content

Commit 6bfa2e3

Browse files
committed
INIT - setup
0 parents  commit 6bfa2e3

File tree

7 files changed

+160
-0
lines changed

7 files changed

+160
-0
lines changed

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NPM
2+
node_modules
3+
package-lock.json

‎.vscode/extensions.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
// See http://go.microsoft.com/fwlink/?LinkId=827846
3+
// for the documentation about the extensions.json format
4+
"recommendations": ["dbaeumer.vscode-eslint"]
5+
}

‎.vscode/launch.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "Run Tests",
8+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
9+
"args": ["--reporter=spec", "--colors", "--bail", "--timeout", "9999999"],
10+
"console": "internalConsole",
11+
"internalConsoleOptions": "openOnSessionStart"
12+
}
13+
]
14+
}

‎.vscode/settings.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"editor.codeActionsOnSave": {
4+
"source.fixAll": true
5+
}
6+
}

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Backend Challenges: package.json

‎coderoad/package.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "coderoad-fcc-learn-npm",
3+
"repository": {
4+
"type": "git",
5+
"url": "https://github.com/coderoad/fcc-learn-npm"
6+
},
7+
"scripts": {
8+
"test": "mocha",
9+
"programmatic-test": "mocha --reporter=mocha-tap-reporter"
10+
},
11+
"dependencies": {
12+
"mocha": "^7.0.1",
13+
"mocha-tap-reporter": "^0.1.3"
14+
}
15+
}

‎coderoad/test/utils.js

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const util = require("util");
4+
const { join } = require("path");
5+
6+
const readFile = util.promisify(fs.readFile);
7+
const readdir = util.promisify(fs.readdir);
8+
9+
const getPackageJson = async (dir = path.join(process.cwd(), "..")) => {
10+
// load package.json file
11+
const pathToPackageJson = join(dir, "package.json");
12+
const packageJson = await readFile(pathToPackageJson, "utf8").catch(
13+
console.error
14+
);
15+
if (!packageJson) {
16+
throw new Error("Missing root package.json");
17+
}
18+
// parse as JSON
19+
const json = JSON.parse(packageJson);
20+
if (!json) {
21+
throw new Error("The package.json content looks invalid");
22+
}
23+
return json;
24+
};
25+
26+
exports.getPackageJson = getPackageJson;
27+
28+
const versionMatch = (current, expected) => {
29+
let currentSemver = current;
30+
if (["~", "^"].includes(current[0])) {
31+
currentSemver = current.substring(1);
32+
}
33+
return currentSemver === expected;
34+
};
35+
36+
/**
37+
* isModuleInstalled
38+
* @param { name, type } params
39+
* "name" - the name of the dependency
40+
* "type" - "dependency", "devDependency", "peerDependency"
41+
* @returns boolean
42+
*/
43+
const isModuleInstalled = async ({ name, type, version }) => {
44+
// 1. load package.json file
45+
const json = await getPackageJson();
46+
47+
// 2. verify package lists dependency by type
48+
let installCommand;
49+
let hasDependency;
50+
let currentVersion;
51+
52+
switch (type) {
53+
case "dependency":
54+
installCommand = "--save";
55+
hasDependency = !!json.dependencies && json.dependencies[name];
56+
currentVersion = json.dependencies[name];
57+
break;
58+
case "devDependency":
59+
installCommand = "--save-dev";
60+
hasDependency = !!json.devDependencies && json.devDependencies[name];
61+
currentVersion = json.devDependencies[name];
62+
break;
63+
case "peerDependency":
64+
throw new Error("Peer dependencies unsupported");
65+
default:
66+
throw new Error("Unsupported packaged type");
67+
}
68+
69+
if (!hasDependency) {
70+
throw new Error(`Run "npm install ${installCommand} ${name}"`);
71+
}
72+
73+
// 3. if version, check dependency version
74+
if (version && !versionMatch(currentVersion, version)) {
75+
throw new Error(
76+
`Dependency ${name} version ${currentVersion} does not match expected ${version}`
77+
);
78+
}
79+
80+
// 4. verify node_module installed
81+
const pathToNodeModule = join(process.cwd(), "..", "node_modules", name);
82+
const hasNodeModules = await readdir(pathToNodeModule).catch(() => {
83+
throw new Error('Missing node_modules. Run "npm install"');
84+
});
85+
if (!hasNodeModules) {
86+
throw new Error('Missing node_modules. Run "npm install"');
87+
}
88+
89+
// 5. if version, has installed node_module version
90+
if (version) {
91+
const nodeModulePackageJson = await getPackageJson(pathToNodeModule);
92+
if (!versionMatch(nodeModulePackageJson.version, version)) {
93+
throw new Error(
94+
`Dependency ${name} version ${version} is not yet installed. Run "npm install"`
95+
);
96+
}
97+
}
98+
99+
return true;
100+
};
101+
102+
exports.isModuleInstalled = isModuleInstalled;
103+
104+
// created because assert.doesNotThrow not working predictably with async fns
105+
const doesNotThrow = async (fn) => {
106+
let result = true;
107+
try {
108+
await fn();
109+
} catch (error) {
110+
console.error(error);
111+
result = false;
112+
}
113+
return result;
114+
};
115+
116+
exports.doesNotThrow = doesNotThrow;

0 commit comments

Comments
 (0)