mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fixed all src/** tests, moved from spec/src to source code locations
This commit is contained in:
parent
a772ef6b94
commit
43b3453e24
@ -3,7 +3,8 @@ module.exports = {
|
||||
match: jest.fn(),
|
||||
app: {
|
||||
getVersion: jest.fn().mockReturnValue("3.0.0"),
|
||||
getPath: jest.fn().mockReturnValue("/foo/bar")
|
||||
getPath: jest.fn().mockReturnValue("tmp"),
|
||||
getLocale: jest.fn().mockRejectedValue("en"),
|
||||
},
|
||||
remote: {
|
||||
app: {
|
||||
|
||||
@ -25,8 +25,8 @@
|
||||
"build:linux": "yarn compile && electron-builder --linux --dir -c.productName=LensDev",
|
||||
"build:mac": "yarn compile && electron-builder --mac --dir -c.productName=LensDev",
|
||||
"build:win": "yarn compile && electron-builder --win --dir -c.productName=LensDev",
|
||||
"test": "jest spec/src $@",
|
||||
"integration": "jest spec/integration $@",
|
||||
"test": "jest --env=jsdom src $@",
|
||||
"integration": "jest --coverage integration $@",
|
||||
"dist": "yarn compile && electron-builder -p onTag",
|
||||
"dist:win": "yarn compile && electron-builder -p onTag --x64 --ia32",
|
||||
"dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null",
|
||||
@ -63,7 +63,7 @@
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"testRegex": ".*_(spec)\\.[jt]sx?$",
|
||||
"testRegex": ".*_(spec|test)\\.[jt]sx?$",
|
||||
"collectCoverage": false,
|
||||
"verbose": true,
|
||||
"testEnvironment": "node",
|
||||
|
||||
@ -1,17 +1,7 @@
|
||||
import mockFs from "mock-fs"
|
||||
import yaml from "js-yaml"
|
||||
import { ClusterStore } from "../../../src/common/cluster-store";
|
||||
import { Cluster } from "../../../src/main/cluster";
|
||||
|
||||
jest.mock("electron", () => {
|
||||
return {
|
||||
app: {
|
||||
getVersion: () => '99.99.99',
|
||||
getPath: () => 'tmp',
|
||||
getLocale: () => 'en'
|
||||
}
|
||||
}
|
||||
})
|
||||
import { ClusterStore } from "./cluster-store";
|
||||
import { Cluster } from "../main/cluster";
|
||||
|
||||
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
||||
console.log("");
|
||||
@ -1,15 +1,7 @@
|
||||
import mockFs from "mock-fs"
|
||||
import { userStore, UserStore } from "../../../src/common/user-store"
|
||||
import { userStore, UserStore } from "./user-store"
|
||||
|
||||
jest.mock("electron", () => {
|
||||
return {
|
||||
app: {
|
||||
getVersion: () => '99.99.99',
|
||||
getPath: () => 'tmp',
|
||||
getLocale: () => 'en'
|
||||
}
|
||||
}
|
||||
})
|
||||
jest.mock("electron")
|
||||
|
||||
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
|
||||
console.log("");
|
||||
@ -1,4 +1,4 @@
|
||||
import { splitArray } from "../splitArray";
|
||||
import { splitArray } from "./splitArray";
|
||||
|
||||
describe("split array on element tests", () => {
|
||||
test("empty array", () => {
|
||||
@ -12,6 +12,7 @@ export const isDebugging = process.env.DEBUG === "true";
|
||||
export const isProduction = process.env.NODE_ENV === "production"
|
||||
export const isDevelopment = isDebugging || !isProduction;
|
||||
export const buildVersion = process.env.BUILD_VERSION;
|
||||
export const isTestEnv = !!process.env.JEST_WORKER_ID;
|
||||
|
||||
// Paths
|
||||
export const contextDir = process.cwd();
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
import packageInfo from "../../../package.json"
|
||||
|
||||
// fixme: ENOENT: no such file or directory, mkdir '/foo/bar'
|
||||
// import { bundledKubectl, Kubectl } from "../../../src/main/kubectl";
|
||||
var bundledKubectl: any;
|
||||
var Kubectl: any;
|
||||
import packageInfo from "../../package.json"
|
||||
import { bundledKubectl, Kubectl } from "../../src/main/kubectl";
|
||||
|
||||
jest.mock("electron")
|
||||
jest.mock("../../../src/common/user-store")
|
||||
jest.mock("../common/user-store")
|
||||
|
||||
xdescribe("kubectlVersion", () => {
|
||||
describe("kubectlVersion", () => {
|
||||
it("returns bundled version if exactly same version used", async () => {
|
||||
const kubectl = new Kubectl(bundledKubectl.kubectlVersion)
|
||||
expect(kubectl.kubectlVersion).toBe(bundledKubectl.kubectlVersion)
|
||||
@ -1,24 +1,25 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { getFreePort } from "./port"
|
||||
import net from "net"
|
||||
|
||||
jest.mock("net");
|
||||
|
||||
class MockServer extends EventEmitter {
|
||||
listen = jest.fn((obj) => {
|
||||
this.emit('listening', {})
|
||||
return this
|
||||
})
|
||||
address = () => { return { port: 12345 }}
|
||||
address = () => {
|
||||
return { port: 12345 }
|
||||
}
|
||||
unref = jest.fn()
|
||||
close = jest.fn((cb) => {
|
||||
cb()
|
||||
})
|
||||
close = jest.fn(cb => cb())
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const net = require("net")
|
||||
jest.mock("net")
|
||||
|
||||
import * as port from "../../../src/main/port"
|
||||
|
||||
describe("getFreePort", () => {
|
||||
describe.only("getFreePort", () => {
|
||||
beforeEach(() => {
|
||||
// @ts-ignore
|
||||
// fixme: find a better way to support types for mocked module
|
||||
net.createServer.mockReturnValue(new MockServer)
|
||||
})
|
||||
|
||||
@ -27,6 +28,6 @@ describe("getFreePort", () => {
|
||||
})
|
||||
|
||||
it("finds the next free port", async () => {
|
||||
return expect(port.getFreePort()).resolves.toEqual(expect.any(Number))
|
||||
return expect(getFreePort()).resolves.toEqual(expect.any(Number))
|
||||
})
|
||||
})
|
||||
@ -1,8 +1,12 @@
|
||||
/* Early store format had the kubeconfig directly under context name, this moves
|
||||
it under the kubeConfig key */
|
||||
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.0.0-beta.2");
|
||||
if(!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.0.0-beta.2");
|
||||
}
|
||||
for (const value of store) {
|
||||
const contextName = value[0];
|
||||
// Looping all the keys gives out the store internal stuff too...
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
// Cleans up a store that had the state related data stored
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.4.1");
|
||||
if (!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.4.1");
|
||||
}
|
||||
for (const value of store) {
|
||||
const contextName = value[0];
|
||||
if(contextName === "__internal__") continue;
|
||||
if (contextName === "__internal__") continue;
|
||||
const cluster = value[1];
|
||||
|
||||
store.set(contextName, { kubeConfig: cluster.kubeConfig, icon: cluster.icon || null, preferences: cluster.preferences || {} });
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
// Move cluster icon from root to preferences
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.2");
|
||||
if(!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.2");
|
||||
}
|
||||
for (const value of store) {
|
||||
const clusterKey = value[0];
|
||||
if(clusterKey === "__internal__") continue
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import * as yaml from "js-yaml"
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
// Convert access token and expiry from arrays into strings
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.3");
|
||||
if(!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.6.0-beta.3");
|
||||
}
|
||||
for (const value of store) {
|
||||
const clusterKey = value[0];
|
||||
if(clusterKey === "__internal__") continue
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
// Add existing clusters to "default" workspace
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.0");
|
||||
if(!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.0");
|
||||
}
|
||||
for (const value of store) {
|
||||
const clusterKey = value[0];
|
||||
if(clusterKey === "__internal__") continue
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
// add id for clusters and store them to array
|
||||
import { v4 as uuid } from "uuid"
|
||||
import { isTestEnv } from "../../common/vars";
|
||||
|
||||
export function migration(store: any) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.1");
|
||||
if(!isTestEnv) {
|
||||
console.log("CLUSTER STORE, MIGRATION: 2.7.0-beta.1");
|
||||
}
|
||||
const clusters: any[] = []
|
||||
for (const value of store) {
|
||||
const clusterKey = value[0];
|
||||
|
||||
103
src/renderer/api/kube-api-parse.ts
Normal file
103
src/renderer/api/kube-api-parse.ts
Normal file
@ -0,0 +1,103 @@
|
||||
// Parse kube-api path and get api-version, group, etc.
|
||||
import { splitArray } from "../../common/utils";
|
||||
|
||||
export interface IKubeApiLinkRef {
|
||||
apiPrefix?: string;
|
||||
apiVersion: string;
|
||||
resource: string;
|
||||
name: string;
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
||||
apiBase: string;
|
||||
apiGroup: string;
|
||||
apiVersionWithGroup: string;
|
||||
}
|
||||
|
||||
export function parseApi(path: string): IKubeApiLinkBase {
|
||||
path = new URL(path, location.origin).pathname;
|
||||
const [, prefix, ...parts] = path.split("/");
|
||||
const apiPrefix = `/${prefix}`;
|
||||
|
||||
const [left, right, namespaced] = splitArray(parts, "namespaces");
|
||||
let apiGroup, apiVersion, namespace, resource, name;
|
||||
|
||||
if (namespaced) {
|
||||
switch (right.length) {
|
||||
case 1:
|
||||
name = right[0];
|
||||
// fallthrough
|
||||
case 0:
|
||||
resource = "namespaces"; // special case this due to `split` removing namespaces
|
||||
break;
|
||||
default:
|
||||
[namespace, resource, name] = right;
|
||||
break;
|
||||
}
|
||||
|
||||
apiVersion = left.pop();
|
||||
apiGroup = left.join("/");
|
||||
} else {
|
||||
switch (left.length) {
|
||||
case 2:
|
||||
resource = left.pop();
|
||||
// fallthrough
|
||||
case 1:
|
||||
apiVersion = left.pop();
|
||||
apiGroup = "";
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Given that
|
||||
* - `apiVersion` is `GROUP/VERSION` and
|
||||
* - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i
|
||||
* where length <= 63
|
||||
* - `GROUP` is /^D(\.D)*$/ where D is `DNS_LABEL` and length <= 253
|
||||
*
|
||||
* There is no well defined selection from an array of items that were
|
||||
* seperated by '/'
|
||||
*
|
||||
* Solution is to create a huristic. Namely:
|
||||
* 1. if '.' in left[0] then apiGroup <- left[0]
|
||||
* 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1]
|
||||
* 3. otherwise assume apiVersion <- left[0]
|
||||
* 4. always resource, name <- left[(0 or 1)+1..]
|
||||
*/
|
||||
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
|
||||
[apiGroup, apiVersion] = left;
|
||||
resource = left.slice(2).join("/")
|
||||
} else {
|
||||
apiGroup = "";
|
||||
apiVersion = left[0];
|
||||
[resource, name] = left.slice(1)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const apiVersionWithGroup = [apiGroup, apiVersion].filter(v => v).join("/");
|
||||
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
|
||||
|
||||
if (!apiBase) {
|
||||
throw new Error(`invalid apiPath: ${path}`)
|
||||
}
|
||||
|
||||
return {
|
||||
apiBase,
|
||||
apiPrefix, apiGroup,
|
||||
apiVersion, apiVersionWithGroup,
|
||||
namespace, resource, name,
|
||||
};
|
||||
}
|
||||
|
||||
export function createApiLink(ref: IKubeApiLinkRef): string {
|
||||
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
|
||||
let { namespace } = ref;
|
||||
if (namespace) {
|
||||
namespace = `namespaces/${namespace}`
|
||||
}
|
||||
return [apiPrefix, apiVersion, namespace, resource, name]
|
||||
.filter(v => v)
|
||||
.join("/")
|
||||
}
|
||||
@ -1,11 +1,11 @@
|
||||
import { IKubeApiLinkBase, KubeApi } from "../kube-api";
|
||||
import { IKubeApiLinkBase, parseApi } from "./kube-api-parse";
|
||||
|
||||
interface ParseAPITest {
|
||||
interface KubeApi_Parse_Test {
|
||||
url: string;
|
||||
expected: Required<IKubeApiLinkBase>;
|
||||
}
|
||||
|
||||
const tests: ParseAPITest[] = [
|
||||
const tests: KubeApi_Parse_Test[] = [
|
||||
{
|
||||
url: "/api/v1/namespaces/kube-system/pods/coredns-6955765f44-v8p27",
|
||||
expected: {
|
||||
@ -112,12 +112,11 @@ const tests: ParseAPITest[] = [
|
||||
},
|
||||
];
|
||||
|
||||
jest.mock('../kube-watch-api.ts', () => 'KubeWatchApi');
|
||||
describe("parseApi unit tests", () => {
|
||||
describe.only("parseApi unit tests", () => {
|
||||
for (const i in tests) {
|
||||
const { url: tUrl, expected:tExpect} = tests[i];
|
||||
test(`test #${parseInt(i)+1}`, () => {
|
||||
expect(KubeApi.parseApi(tUrl)).toStrictEqual(tExpect);
|
||||
expect(parseApi(tUrl)).toStrictEqual(tExpect);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -7,7 +7,7 @@ import { IKubeObjectRef, KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } fro
|
||||
import { apiKube } from "./index";
|
||||
import { kubeWatchApi } from "./kube-watch-api";
|
||||
import { apiManager } from "./api-manager";
|
||||
import { splitArray } from "../../common/utils";
|
||||
import { createApiLink, parseApi } from "./kube-api-parse";
|
||||
|
||||
export interface IKubeApiOptions<T extends KubeObject> {
|
||||
kind: string; // resource type within api-group, e.g. "Namespace"
|
||||
@ -25,107 +25,9 @@ export interface IKubeApiQueryParams {
|
||||
continue?: string; // might be used with ?limit from second request
|
||||
}
|
||||
|
||||
export interface IKubeApiLinkRef {
|
||||
apiPrefix?: string;
|
||||
apiVersion: string;
|
||||
resource: string;
|
||||
name: string;
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
||||
apiBase: string;
|
||||
apiGroup: string;
|
||||
apiVersionWithGroup: string;
|
||||
}
|
||||
|
||||
export class KubeApi<T extends KubeObject = any> {
|
||||
static parseApi(apiPath = ""): IKubeApiLinkBase {
|
||||
apiPath = new URL(apiPath, location.origin).pathname;
|
||||
const [, prefix, ...parts] = apiPath.split("/");
|
||||
const apiPrefix = `/${prefix}`;
|
||||
|
||||
const [left, right, namespaced] = splitArray(parts, "namespaces");
|
||||
let apiGroup, apiVersion, namespace, resource, name;
|
||||
|
||||
if (namespaced) {
|
||||
switch (right.length) {
|
||||
case 1:
|
||||
name = right[0];
|
||||
// fallthrough
|
||||
case 0:
|
||||
resource = "namespaces"; // special case this due to `split` removing namespaces
|
||||
break;
|
||||
default:
|
||||
[namespace, resource, name] = right;
|
||||
break;
|
||||
}
|
||||
|
||||
apiVersion = left.pop();
|
||||
apiGroup = left.join("/");
|
||||
} else {
|
||||
switch (left.length) {
|
||||
case 2:
|
||||
resource = left.pop();
|
||||
// fallthrough
|
||||
case 1:
|
||||
apiVersion = left.pop();
|
||||
apiGroup = "";
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Given that
|
||||
* - `apiVersion` is `GROUP/VERSION` and
|
||||
* - `VERSION` is `DNS_LABEL` which is /^[a-z0-9]((-[a-z0-9])|[a-z0-9])*$/i
|
||||
* where length <= 63
|
||||
* - `GROUP` is /^D(\.D)*$/ where D is `DNS_LABEL` and length <= 253
|
||||
*
|
||||
* There is no well defined selection from an array of items that were
|
||||
* seperated by '/'
|
||||
*
|
||||
* Solution is to create a huristic. Namely:
|
||||
* 1. if '.' in left[0] then apiGroup <- left[0]
|
||||
* 2. if left[1] matches /^v[0-9]/ then apiGroup, apiVersion <- left[0], left[1]
|
||||
* 3. otherwise assume apiVersion <- left[0]
|
||||
* 4. always resource, name <- left[(0 or 1)+1..]
|
||||
*/
|
||||
if (left[0].includes('.') || left[1].match(/^v[0-9]/)) {
|
||||
[apiGroup, apiVersion] = left;
|
||||
resource = left.slice(2).join("/")
|
||||
} else {
|
||||
apiGroup = "";
|
||||
apiVersion = left[0];
|
||||
[resource, name] = left.slice(1)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const apiVersionWithGroup = [apiGroup, apiVersion].filter(v => v).join("/");
|
||||
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
|
||||
|
||||
if (!apiBase) {
|
||||
throw new Error(`invalid apiPath: ${apiPath}`)
|
||||
}
|
||||
|
||||
return {
|
||||
apiBase,
|
||||
apiPrefix, apiGroup,
|
||||
apiVersion, apiVersionWithGroup,
|
||||
namespace, resource, name,
|
||||
};
|
||||
}
|
||||
|
||||
static createLink(ref: IKubeApiLinkRef): string {
|
||||
const { apiPrefix = "/apis", resource, apiVersion, name } = ref;
|
||||
let { namespace } = ref;
|
||||
if (namespace) {
|
||||
namespace = `namespaces/${namespace}`
|
||||
}
|
||||
return [apiPrefix, apiVersion, namespace, resource, name]
|
||||
.filter(v => v)
|
||||
.join("/")
|
||||
}
|
||||
static parseApi = parseApi;
|
||||
static createLink = createApiLink;
|
||||
|
||||
static watchAll(...apis: KubeApi[]) {
|
||||
const disposers = apis.map(api => api.watch());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user