Skip to content

Commit

Permalink
Add unit tests for validation service (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
Heniker authored Dec 30, 2021
1 parent 519795a commit 948a0d4
Show file tree
Hide file tree
Showing 14 changed files with 337 additions and 155 deletions.
44 changes: 25 additions & 19 deletions src/extension/services/validationService/checks/adb.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as semver from "semver";
import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import { createNotFoundMessage, createVersionErrorMessage, getVersion } from "../util";
import {
basicCheck,
createNotFoundMessage,
createVersionErrorMessage,
parseVersion,
} from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

nls.config({
Expand All @@ -17,40 +20,43 @@ const toLocale = nls.loadMessageBundle();
const label = "ADB";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("adb")) {
const result = await basicCheck({
command: "adb",
versionRange: "30.0.0",
getVersion: parseVersion.bind(null, "adb --version", /^.*\n.*version (.*?)( |$|\n)/gi),
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
};
}

const version = await getVersion("adb --version", /^.*\n.*version (.*?)( |$|\n)/gi);

if (!version) {
if (result.versionCompare === undefined) {
return {
status: "failure",
comment: createVersionErrorMessage(label),
};
}

const isOlder = semver.lt(version, "30.0.0");
return isOlder
? {
status: "partial-success",
comment:
"Detected version is older than 30.0.0. " +
"Please update SDK tools in case of errors",
}
: {
status: "success",
};
if (result.versionCompare === -1) {
return {
status: "partial-success",
comment:
"Detected version is older than 30.0.0. " +
"Please update SDK tools in case of errors",
};
}

return { status: "success" };
}

const adbAndroid: IValidation = {
label,
description: toLocale(
"AdbCheckAndroidDescription",
"Required for app installition. Minimal version is 12",
"Required for app installation. Minimal version is 12",
),
category: ValidationCategoryE.Android,
exec: test,
Expand Down
9 changes: 6 additions & 3 deletions src/extension/services/validationService/checks/cocoaPods.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import { createNotFoundMessage } from "../util";
import { basicCheck, createNotFoundMessage } from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

nls.config({
Expand All @@ -16,7 +15,11 @@ const toLocale = nls.loadMessageBundle();
const label = "CocoaPods";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("pod")) {
const result = await basicCheck({
command: "pod",
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
Expand Down
45 changes: 19 additions & 26 deletions src/extension/services/validationService/checks/emulator.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as semver from "semver";
import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import {
basicCheck,
createNotFoundMessage,
createVersionErrorMessage,
executeCommand,
normizeStr,
parseVersion,
} from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

Expand All @@ -22,41 +20,36 @@ const toLocale = nls.loadMessageBundle();
const label = "Android Emulator";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("emulator")) {
const result = await basicCheck({
command: "emulator",
versionRange: "30.0.0",
getVersion: parseVersion.bind(null, "emulator -version", /version (.*?)( |$)/gi),
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
};
}

const command = "emulator -version";
const data = await executeCommand(command);

const text = normizeStr(data.stdout).split("\n")[0];
const reg = /version (.*?)( |$)/gi;

// something like '30.9.5.0' converts to '30.9.5', safe with nulls
const version = semver.coerce(reg.exec(text)?.[1]);

if (!version) {
if (result.versionCompare === undefined) {
return {
status: "failure",
comment: createVersionErrorMessage(label),
};
}

const isOlder = semver.lt(version, "30.0.0");
if (result.versionCompare === -1) {
return {
status: "partial-success",
comment:
"Detected version is older than 30.0.0. " +
"Please update SDK tools in case of errors",
};
}

return isOlder
? {
status: "partial-success",
comment:
"Detected version is older than 30.0.0. " +
"Please update SDK tools in case of errors",
}
: {
status: "success",
};
return { status: "success" };
}

const main: IValidation = {
Expand Down
8 changes: 4 additions & 4 deletions src/extension/services/validationService/checks/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ const toLocale = nls.loadMessageBundle();
const convertPathWithVars = (str: string) =>
str.replace(/%([^%]+)%/g, (_, n) => process.env[n] || _);

const envVars = {
ANDROID_HOME: process.env.ANDROID_HOME,
};

async function test(): Promise<ValidationResultT> {
const envVars = {
ANDROID_HOME: process.env.ANDROID_HOME,
};

const resolvedEnv = fromEntries(
Object.entries(envVars).map(([key, val]) => [
key,
Expand Down
13 changes: 7 additions & 6 deletions src/extension/services/validationService/checks/expoCli.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import { createNotFoundMessage } from "../util";
import { basicCheck, createNotFoundMessage } from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

nls.config({
Expand All @@ -16,16 +15,18 @@ const toLocale = nls.loadMessageBundle();
const label = "Expo CLI";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("expo-cli")) {
const result = await basicCheck({
command: "expo-cli",
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
};
}

return {
status: "success",
};
return { status: "success" };
}

const main: IValidation = {
Expand Down
23 changes: 9 additions & 14 deletions src/extension/services/validationService/checks/gradle.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as semver from "semver";
import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import {
basicCheck,
createNotFoundMessage,
createVersionErrorMessage,
executeCommand,
normizeStr,
parseVersion,
} from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

Expand All @@ -22,28 +20,25 @@ const toLocale = nls.loadMessageBundle();
const label = "Gradle";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("gradle")) {
const result = await basicCheck({
command: "gradle",
getVersion: parseVersion.bind(null, "gradle -version", /gradle (.*?)( |$)/gim),
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
};
}

const command = "gradle -version";
const data = await executeCommand(command);

const text = normizeStr(data.stdout).split("\n")[2];
const reg = /gradle (.*?)( |$)/gi;
const version = semver.coerce(reg.exec(text)?.[1]);

if (!version) {
if (result.versionCompare === undefined) {
return {
status: "failure",
comment: createVersionErrorMessage(label),
};
}

// #todo> Not sure which gradle versions are required
return {
status: "success",
};
Expand Down
9 changes: 6 additions & 3 deletions src/extension/services/validationService/checks/iosDeploy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import { createNotFoundMessage } from "../util";
import { basicCheck, createNotFoundMessage } from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

nls.config({
Expand All @@ -16,7 +15,11 @@ const toLocale = nls.loadMessageBundle();
const label = "ios-deploy";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("ios-deploy")) {
const result = await basicCheck({
command: "ios-deploy",
});

if (!result.exists) {
return {
status: "partial-success", // not necessary required
comment: createNotFoundMessage(label),
Expand Down
42 changes: 13 additions & 29 deletions src/extension/services/validationService/checks/java.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

import * as semver from "semver";
import * as cexists from "command-exists";
import * as nls from "vscode-nls";
import {
basicCheck,
createNotFoundMessage,
createVersionErrorMessage,
executeCommand,
normizeStr,
parseVersion,
} from "../util";
import { ValidationCategoryE, IValidation, ValidationResultT } from "./types";

Expand All @@ -22,42 +20,28 @@ const toLocale = nls.loadMessageBundle();
const label = "Java";

async function test(): Promise<ValidationResultT> {
if (!cexists.sync("java")) {
// for future changes: keep in mind that java version format has changed since Java8
const result = await basicCheck({
command: "java",
getVersion: parseVersion.bind(null, "java -version", /version "(.*?)"( |$|\n)/gi, "stderr"),
versionRange: "1.8.0",
});

if (!result.exists) {
return {
status: "failure",
comment: createNotFoundMessage(label),
};
}

const command = "java -version";

const data = await executeCommand(command);

// https://stackoverflow.com/questions/13483443/why-does-java-version-go-to-stderr
// `java -version` goes to stderr...
const text = normizeStr(data.stderr).split("\n")[0];
// something like 1.8.0
// example `java -version` output: java version "16.0.1" 2021-04-20
const vOldReg = /version "(.*?)"( |$)/gi;
// something like 11.0.12
// this regex parses the output of `java --version`, which should not be required,
// but let's leave it here just to be sure nothing breaks in future java versions
// example `java --version` output: java 16.0.1 2021-04-20
const vNewReg = /java (.*?)( |$)/gi;
const version = semver.coerce(vOldReg.exec(text)?.[1] || vNewReg.exec(text)?.[1]);

if (!version) {
if (result.versionCompare === undefined) {
return {
status: "failure",
comment: createVersionErrorMessage("label"),
comment: createVersionErrorMessage(label),
};
}

// the fact that version format has changed after java8 does not
// change this line, but it is something to keep in mind
const isOlder = semver.lt(version, "1.8.0");

if (isOlder) {
if (result.versionCompare === -1) {
return {
status: "partial-success",
comment: `Detected version is older than 1.8.0. Please install ${label} 8 in case of errors`,
Expand Down
Loading

0 comments on commit 948a0d4

Please sign in to comment.