1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-06 04:00:05 +00:00

Added suggestions

This commit is contained in:
2020-07-16 15:02:17 -04:00
parent b614bafd03
commit 334a849caa
19 changed files with 185 additions and 193 deletions

View File

@@ -44,4 +44,4 @@
"devDependencies": {
"node-sass": "^4.14.1"
}
}
}

View File

@@ -5,5 +5,6 @@ import App from './App';
test('renders learn react link', () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -9,9 +9,7 @@ const App = (): ReactElement<{}> => {
const { adapter } = useContext(AppContext);
useEffect(() => {
if (adapter) {
adapter.setDebugState(debug);
}
if (adapter) adapter.setDebugState(debug);
}, [debug, adapter]);
useEffect(() => {
@@ -33,7 +31,7 @@ const App = (): ReactElement<{}> => {
<label className="switch">
<input
type="checkbox"
onChange={(e) => setDebug(e.target.checked)}
onChange={(e) => setDebug(e.target.checked)} // FIXME: rename 'e' => 'event'
/>
<span className="knob"></span>
</label>
@@ -45,7 +43,7 @@ const App = (): ReactElement<{}> => {
type="text"
className="app-loc-input"
value={appLoc}
onChange={(e) => setAppLoc(e.target.value)}
onChange={(e) => setAppLoc(e.target.value)} // FIXME: rename 'e' => 'event'
placeholder="AppLoc"
/>
</div>

View File

@@ -9,11 +9,14 @@ const Login = (): ReactElement<{}> => {
const appContext = useContext(AppContext);
const handleSubmit = useCallback(
(e) => {
(e) => { // FIXME: rename 'e' => 'event'
e.preventDefault();
appContext.adapter.logIn(username, password).then(() => {
appContext.setIsLoggedIn(true);
});
appContext.adapter.logIn(username, password)
.then(() => {
appContext.setIsLoggedIn(true);
});
// FIXME: catch block
},
[username, password, appContext]
);
@@ -38,7 +41,7 @@ const Login = (): ReactElement<{}> => {
type="password"
value={password}
required
onChange={(e) => setPassword(e.target.value)}
onChange={(e) => setPassword(e.target.value)} // FIXME: rename 'e' => 'event'
/>
</div>
<button type="submit" className="submit-button">
@@ -51,4 +54,4 @@ const Login = (): ReactElement<{}> => {
);
};
export default Login;
export default Login;

View File

@@ -8,16 +8,14 @@ interface PrivateRouteProps {
path: string;
}
const PrivateRoute = (
props: PrivateRouteProps
): ReactElement<PrivateRouteProps> => {
const PrivateRoute = (props: PrivateRouteProps): ReactElement<PrivateRouteProps> => {
const { component, path, exact } = props;
const appContext = useContext(AppContext);
return appContext.isLoggedIn ? (
return appContext.isLoggedIn ?
<Route component={component} path={path} exact={exact} />
) : (
:
<Redirect to="/login" />
);
};
export default PrivateRoute;
export default PrivateRoute;

View File

@@ -2,25 +2,24 @@ import React, { useEffect, useState, ReactElement, useContext } from "react";
import TestSuiteComponent from "./components/TestSuite";
import TestSuiteCard from "./components/TestSuiteCard";
import { TestSuite, Test } from "./types";
import { basicTests } from "./testSuites/Basic";
import { basicTests } from "./testSuites/Basic"; // FIXME: declared but never used
import "./TestSuiteRunner.scss";
import SASjs from "sasjs";
import { AppContext } from "./context/AppContext";
import { sendArrTests, sendObjTests } from "./testSuites/RequestData";
import { sendArrTests, sendObjTests } from "./testSuites/RequestData"; // FIXME: declared but never used
import { specialCaseTests } from "./testSuites/SpecialCases";
import { sasjsRequestTests } from "./testSuites/SasjsRequests";
import { sasjsRequestTests } from "./testSuites/SasjsRequests"; // FIXME: declared but never used
interface TestSuiteRunnerProps {
adapter: SASjs;
}
const TestSuiteRunner = (
props: TestSuiteRunnerProps
): ReactElement<TestSuiteRunnerProps> => {
const TestSuiteRunner = (props: TestSuiteRunnerProps): ReactElement<TestSuiteRunnerProps> => {
const { adapter } = props;
const { config } = useContext(AppContext);
const { config } = useContext(AppContext); // FIXME: declared but never used
const [testSuites, setTestSuites] = useState<TestSuite[]>([]);
const [runTests, setRunTests] = useState(false);
const [completedTestSuites, setCompletedTestSuites] = useState<
const [completedTestSuites, setCompletedTestSuites] = useState< // FIXME: create interface
{
name: string;
completedTests: {
@@ -65,20 +64,23 @@ const TestSuiteRunner = (
<>
<div className="button-container">
<button
className={runTests ? "submit-button disabled" : "submit-button"}
className={runTests ? "submit-button disabled" : "submit-button"} // TODO: 'submit-button' class should be assigned by default
onClick={() => setRunTests(true)}
disabled={runTests}
>
{runTests ? (
<>
<div className="loading-spinner"></div>Running tests...
{
// FIXME: fragment is not needed in this case
}
<div className="loading-spinner"></div>Running tests...
</>
) : (
"Run tests!"
)}
</button>
</div>
{completedTestSuites.map((completedTestSuite, index) => {
{completedTestSuites.map((completedTestSuite, index) => { // TODO: refactor
return (
<TestSuiteCard
key={index}
@@ -100,22 +102,19 @@ const TestSuiteRunner = (
}[]
) => {
const currentIndex = testSuites.indexOf(currentTestSuite);
const nextIndex =
currentIndex < testSuites.length - 1 ? currentIndex + 1 : -1;
if (nextIndex >= 0) {
setCurrentTestSuite(testSuites[nextIndex]);
} else {
setCurrentTestSuite(null);
}
const nextIndex = currentIndex < testSuites.length - 1 ? currentIndex + 1 : -1;
if (nextIndex >= 0) setCurrentTestSuite(testSuites[nextIndex]);
else setCurrentTestSuite(null);
const newCompletedTestSuites = [
...completedTestSuites,
{ name, completedTests },
];
setCompletedTestSuites(newCompletedTestSuites);
if (newCompletedTestSuites.length === testSuites.length) {
setRunTests(false);
}
if (newCompletedTestSuites.length === testSuites.length) setRunTests(false);
}}
/>
)}
@@ -123,4 +122,4 @@ const TestSuiteRunner = (
);
};
export default TestSuiteRunner;
export default TestSuiteRunner;

View File

@@ -1,6 +1,6 @@
import React, { ReactElement, useEffect, useState } from "react";
import TestCard from "./TestCard";
import { start } from "repl";
import { start } from "repl"; // FIXME: declared but never used
interface TestProps {
title: string;
@@ -39,28 +39,36 @@ const Test = (props: TestProps): ReactElement<TestProps> => {
useEffect(() => {
if (test && assertion) {
const startTime = new Date().valueOf();
const startTime = new Date().valueOf()
setIsRunning(true);
setIsPassed(false);
beforeTestFunction()
.then(() => test(context))
.then((res) => {
setIsRunning(false);
setIsPassed(assertion(res, context));
setIsPassed(assertion(res, context))
return Promise.resolve(assertion(res, context));
})
.then((testResult) => {
afterTestFunction();
const endTime = new Date().valueOf();
const executionTime = (endTime - startTime) / 1000;
onCompleted({ result: testResult, error: null, executionTime });
})
.catch((e) => {
setIsRunning(false);
setIsPassed(false);
console.error(e);
const endTime = new Date().valueOf();
const executionTime = (endTime - startTime) / 1000;
onCompleted({ result: false, error: e, executionTime });
});
}
@@ -76,4 +84,4 @@ const Test = (props: TestProps): ReactElement<TestProps> => {
);
};
export default Test;
export default Test;

View File

@@ -18,7 +18,7 @@ const TestCard = (props: TestCardProps): ReactElement<TestCardProps> => {
<span className="execution-time">
{executionTime ? executionTime.toFixed(2) + "s" : ""}
</span>
{status === "running" && (
{status === "running" && ( // FIXME: use switch statement
<div>
<span className="icon running"></span>Running...
</div>
@@ -40,4 +40,4 @@ const TestCard = (props: TestCardProps): ReactElement<TestCardProps> => {
);
};
export default TestCard;
export default TestCard;

View File

@@ -22,7 +22,7 @@ interface TestSuiteProps {
const TestSuite = (props: TestSuiteProps): ReactElement<TestSuiteProps> => {
const { name, tests, beforeAll, afterAll, onCompleted } = props;
const [context, setContext] = useState<any>(null);
const [completedTests, setCompletedTests] = useState<
const [completedTests, setCompletedTests] = useState< // TODO: create an interface
{
test: Test;
result: boolean;
@@ -31,24 +31,21 @@ const TestSuite = (props: TestSuiteProps): ReactElement<TestSuiteProps> => {
}[]
>([]);
const [currentTest, setCurrentTest] = useState<Test | null>(
(null as unknown) as Test
(null as unknown) as Test // ?
);
useEffect(() => {
if (beforeAll) {
beforeAll().then((data) => setContext({ data }));
}
if (beforeAll) beforeAll().then((data) => setContext({ data }))
}, [beforeAll]);
useEffect(() => {
if (tests.length) {
setCurrentTest(tests[0]);
}
if (tests.length) setCurrentTest(tests[0])
setCompletedTests([]);
setContext(null);
}, [tests]);
return (!!beforeAll && !!context) || !beforeAll ? (
return (!!beforeAll && !!context) || !beforeAll ? ( // ?
<div className="test-suite">
<div className="test-suite-name running">{name}</div>
{currentTest && (
@@ -64,29 +61,27 @@ const TestSuite = (props: TestSuiteProps): ReactElement<TestSuiteProps> => {
error: completedTest.error,
executionTime: completedTest.executionTime,
},
];
]
setCompletedTests(newCompleteTests);
const currentIndex = tests.indexOf(currentTest);
const nextIndex =
currentIndex < tests.length - 1 ? currentIndex + 1 : -1;
if (nextIndex >= 0) {
setCurrentTest(tests[nextIndex]);
} else {
setCurrentTest(null);
}
const nextIndex = currentIndex < tests.length - 1 ? currentIndex + 1 : -1;
if (nextIndex >= 0) setCurrentTest(tests[nextIndex]);
else setCurrentTest(null);
if (newCompleteTests.length === tests.length) {
if (afterAll) {
afterAll().then(() => onCompleted(name, newCompleteTests));
} else {
onCompleted(name, newCompleteTests);
}
if (afterAll) afterAll().then(() => onCompleted(name, newCompleteTests))
else onCompleted(name, newCompleteTests)
}
}}
/>
)}
{completedTests.map((completedTest, index) => {
const { test, result, error } = completedTest;
{completedTests.map((test, index) => {
const { test, result, error } = test;
const { title, description } = test;
return (
<TestCard
key={index}
@@ -99,8 +94,8 @@ const TestSuite = (props: TestSuiteProps): ReactElement<TestSuiteProps> => {
})}
</div>
) : (
<></>
<></> // FIXME: use {null} instead
);
};
export default TestSuite;
export default TestSuite;

View File

@@ -12,20 +12,19 @@ interface TestSuiteCardProps {
executionTime: number;
}[];
}
const TestSuiteCard = (
props: TestSuiteCardProps
): ReactElement<TestSuiteCardProps> => {
const TestSuiteCard = (props: TestSuiteCardProps): ReactElement<TestSuiteCardProps> => {
const { name, tests } = props;
const overallStatus = tests.map((t) => t.result).reduce((x, y) => x && y);
const overallStatus = tests.map((t) => t.result).reduce((x, y) => x && y); // TODO: refactor variable names
return (
<div className="test-suite">
<div className={`test-suite-name ${overallStatus ? "passed" : "failed"}`}>
{name}
</div>
{tests.map((completedTest, index) => {
const { test, result, error, executionTime } = completedTest;
{tests.map((test, index) => {
const { test, result, error, executionTime } = test;
const { title, description } = test;
return (
<TestCard
key={index}

View File

@@ -1,9 +1,9 @@
import React, { createContext, useState, useEffect, ReactNode } from "react";
import SASjs from "sasjs";
export const AppContext = createContext<{
config: any;
sasJsConfig: any;
export const AppContext = createContext<{ // TODO: create an interface
config: any; // TODO: be more specific on type declaration
sasJsConfig: any; // TODO: be more specific on type declaration
isLoggedIn: boolean;
setIsLoggedIn: (value: boolean) => void;
adapter: SASjs;
@@ -16,25 +16,24 @@ export const AppContext = createContext<{
});
export const AppProvider = (props: { children: ReactNode }) => {
const [config, setConfig] = useState<{ sasJsConfig: any }>({
sasJsConfig: null,
});
const [config, setConfig] = useState<{ sasJsConfig: any }>({sasJsConfig: null}); // TODO: be more specific on type declaration
const [adapter, setAdapter] = useState<SASjs>((null as unknown) as SASjs);
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
fetch("config.json")
fetch("config.json") // TODO: use axios instead of fetch
.then((res) => res.json())
.then((configJson: any) => {
.then((configJson: any) => { // TODO: be more specific on type declaration
setConfig(configJson);
const sasjs = new SASjs(configJson.sasJsConfig);
setAdapter(sasjs);
sasjs.checkSession().then((response) => {
setIsLoggedIn(response.isLoggedIn);
});
});
}); // FIXME: add catch block
});// FIXME: add catch block
}, []);
return (
@@ -50,4 +49,4 @@ export const AppProvider = (props: { children: ReactNode }) => {
{props.children}
</AppContext.Provider>
);
};
};

View File

@@ -33,18 +33,16 @@ export const basicTests = (
test: async () => {
return adapter.logIn(userName, password);
},
assertion: (response: any) =>
assertion: (response: any) => // FIXME: be more specific on type declaration
response && response.isLoggedIn && response.userName === userName,
},
{
title: "Default config",
description:
"Should instantiate with default config when none is provided",
test: async () => {
return Promise.resolve(new SASjs());
},
description: "Should instantiate with default config when none is provided",
test: async () => Promise.resolve(new SASjs()),
assertion: (sasjsInstance: SASjs) => {
const sasjsConfig = sasjsInstance.getSasjsConfig();
return (
sasjsConfig.serverUrl === defaultConfig.serverUrl &&
sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 &&

View File

@@ -1,12 +1,12 @@
import SASjs from "sasjs";
import { TestSuite } from "../types";
const stringData: any = { table1: [{ col1: "first col value" }] };
const numericData: any = { table1: [{ col1: 3.14159265 }] };
const multiColumnData: any = {
const stringData: any = { table1: [{ col1: "first col value" }] }; // TODO: be more specific on type declaration
const numericData: any = { table1: [{ col1: 3.14159265 }] }; // TODO: be more specific on type declaration
const multiColumnData: any = { // TODO: be more specific on type declaration
table1: [{ col1: 42, col2: 1.618, col3: "x", col4: "x" }],
};
const multipleRowsWithNulls: any = {
const multipleRowsWithNulls: any = { // TODO: be more specific on type declaration
table1: [
{ col1: 42, col2: null, col3: "x", col4: "" },
{ col1: 42, col2: null, col3: "x", col4: "" },
@@ -15,7 +15,7 @@ const multipleRowsWithNulls: any = {
{ col1: 42, col2: 1.62, col3: "x", col4: "x" },
],
};
const multipleColumnsWithNulls: any = {
const multipleColumnsWithNulls: any = { // TODO: be more specific on type declaration
table1: [
{ col1: 42, col2: null, col3: "x", col4: null },
{ col1: 42, col2: null, col3: "x", col4: null },
@@ -25,21 +25,20 @@ const multipleColumnsWithNulls: any = {
],
};
const getLongStringData = (length = 32764) => {
const getLongStringData = (length = 32764) => { // FIXME: add type declaration
let x = "X";
for (let i = 1; i <= length; i++) {
x = x + "X";
}
const data: any = { table1: [{ col1: x }] };
for (let i = 1; i <= length; i++) x += 'X'
const data: any = { table1: [{ col1: x }] }; // TODO: be more specific on type declaration
return data;
};
const getLargeObjectData = () => {
const data = { table1: [{ big: "data" }] };
for (let i = 1; i < 10000; i++) {
data.table1.push(data.table1[0]);
}
for (let i = 1; i < 10000; i++) data.table1.push(data.table1[0])
return data;
};
@@ -50,12 +49,8 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
{
title: "Single string value",
description: "Should send an array with a single string value",
test: () => {
return adapter.request("common/sendArr", stringData);
},
assertion: (res: any) => {
return res.table1[0][0] === stringData.table1[0].col1;
},
test: () => adapter.request("common/sendArr", stringData),
assertion: (res: any) => res.table1[0][0] === stringData.table1[0].col1 // TODO: be more specific on type declaration
},
{
title: "Long string value",
@@ -64,22 +59,17 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendArr", getLongStringData());
},
assertion: (res: any) => {
const longStringData = getLongStringData();
return res.table1[0][0] === longStringData.table1[0].col1;
},
assertion: (res: any) => res.table1[0][0] === getLongStringData().table1[0].col1 // TODO: be more specific on type declaration
},
{
title: "Overly long string value",
description:
"Should error out with long string values over 32765 characters",
test: () => {
return adapter
.request("common/sendArr", getLongStringData(32767))
.catch((e) => e);
},
assertion: (error: any) => {
return !!error && !!error.MESSAGE;
test: () => adapter
.request("common/sendArr", getLongStringData(32767))
.catch((e) => e), // TODO: rename
assertion: (error: any) => { // TODO: be more specific on type declaration
return !!error && !!error.MESSAGE; // FIXME: refactor
},
},
{
@@ -88,7 +78,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendArr", numericData);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
return res.table1[0][0] === numericData.table1[0].col1;
},
},
@@ -98,7 +88,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendArr", multiColumnData);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
return (
res.table1[0][0] === multiColumnData.table1[0].col1 &&
res.table1[0][1] === multiColumnData.table1[0].col2 &&
@@ -113,9 +103,10 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendArr", multipleRowsWithNulls);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
let result = true;
multipleRowsWithNulls.table1.forEach((_: any, index: number) => {
multipleRowsWithNulls.table1.forEach((_: any, index: number) => { // TODO: be more specific on type declaration
// FIXME: use loop
result =
result &&
res.table1[index][0] === multipleRowsWithNulls.table1[index].col1;
@@ -129,6 +120,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
result &&
res.table1[index][3] === multipleRowsWithNulls.table1[index].col4;
});
return result;
},
},
@@ -138,9 +130,9 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendArr", multipleColumnsWithNulls);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
let result = true;
multipleColumnsWithNulls.table1.forEach((_: any, index: number) => {
multipleColumnsWithNulls.table1.forEach((_: any, index: number) => { // TODO: be more specific on type declaration
result =
result &&
res.table1[index][0] ===
@@ -171,12 +163,12 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
title: "Invalid column name",
description: "Should throw an error",
test: async () => {
const invalidData: any = {
const invalidData: any = { // TODO: be more specific on type declaration
"1 invalid table": [{ col1: 42 }],
};
return adapter.request("common/sendObj", invalidData).catch((e) => e);
},
assertion: (error: any) => !!error && !!error.MESSAGE,
assertion: (error: any) => !!error && !!error.MESSAGE, // TODO: be more specific on type declaration
},
{
title: "Single string value",
@@ -184,7 +176,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", stringData);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
return res.table1[0].COL1 === stringData.table1[0].col1;
},
},
@@ -195,7 +187,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", getLongStringData());
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
const longStringData = getLongStringData();
return res.table1[0].COL1 === longStringData.table1[0].col1;
},
@@ -209,7 +201,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
.request("common/sendObj", getLongStringData(32767))
.catch((e) => e);
},
assertion: (error: any) => {
assertion: (error: any) => { // TODO: be more specific on type declaration
return !!error && !!error.MESSAGE;
},
},
@@ -219,7 +211,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", numericData);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
return res.table1[0].COL1 === numericData.table1[0].col1;
},
},
@@ -230,7 +222,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", getLargeObjectData());
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
const data = getLargeObjectData();
return res.table1[9000].BIG === data.table1[9000].big;
},
@@ -241,7 +233,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", multiColumnData);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
return (
res.table1[0].COL1 === multiColumnData.table1[0].col1 &&
res.table1[0].COL2 === multiColumnData.table1[0].col2 &&
@@ -256,9 +248,9 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", multipleRowsWithNulls);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
let result = true;
multipleRowsWithNulls.table1.forEach((_: any, index: number) => {
multipleRowsWithNulls.table1.forEach((_: any, index: number) => { // TODO: be more specific on type declaration
result =
result &&
res.table1[index].COL1 === multipleRowsWithNulls.table1[index].col1;
@@ -281,9 +273,9 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
test: () => {
return adapter.request("common/sendObj", multipleColumnsWithNulls);
},
assertion: (res: any) => {
assertion: (res: any) => { // TODO: be more specific on type declaration
let result = true;
multipleColumnsWithNulls.table1.forEach((_: any, index: number) => {
multipleColumnsWithNulls.table1.forEach((_: any, index: number) => { // TODO: be more specific on type declaration
result =
result &&
res.table1[index].COL1 ===
@@ -305,4 +297,4 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
},
},
],
});
});

View File

@@ -1,7 +1,7 @@
import SASjs from "sasjs";
import { TestSuite } from "../types";
const data: any = { table1: [{ col1: "first col value" }] };
const data: any = { table1: [{ col1: "first col value" }] }; // TODO: be more specific on type declaration
export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
name: "SASjs Requests",
@@ -9,16 +9,11 @@ export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
{
title: "WORK tables",
description: "Should get WORK tables after request",
test: async () => {
return adapter.request("common/sendArr", data);
},
test: async () => adapter.request("common/sendArr", data),
assertion: (res: any) => {
const requests = adapter.getSasRequests();
if (adapter.getSasjsConfig().debug) {
return requests[0].SASWORK !== null;
} else {
return requests[0].SASWORK === null;
}
return adapter.getSasjsConfig().debug ? requests[0].SASWORK !== null : requests[0].SASWORK === null
},
},
],

View File

@@ -1,7 +1,7 @@
import SASjs from "sasjs";
import { TestSuite } from "../types";
const specialCharData: any = {
const specialCharData: any = { // TODO: be more specific on type definition
table1: [
{
tab: "\t",
@@ -9,8 +9,8 @@ const specialCharData: any = {
cr: "\r",
semicolon: ";semi",
percent: "%",
singleQuote: "'",
doubleQuote: '"',
singleQuote: "'", // TODO: use ``
doubleQuote: '"', // TODO: use ``
crlf: "\r\n",
euro: "€euro",
banghash: "!#banghash",
@@ -18,7 +18,7 @@ const specialCharData: any = {
],
};
const moreSpecialCharData: any = {
const moreSpecialCharData: any = { // TODO: be more specific on type definition
table1: [
{
speech0: '"speech',
@@ -36,44 +36,46 @@ const moreSpecialCharData: any = {
],
};
const getWideData = () => {
const cols: any = {};
for (let i = 1; i <= 10000; i++) {
const getWideData = () => { // FIXME: declared but never used
const cols: any = {}; // TODO: be more specific on type definition
for (let i = 1; i <= 10000; i++) { // Why 10000?
cols["col" + i] = "test" + i;
}
const data: any = {
const data: any = { // TODO: be more specific on type definition
table1: [cols],
};
return data;
};
const getTables = () => {
const tables: any = {};
const getTables = () => { // FIXME: declared but never used
const tables: any = {}; // TODO: be more specific on type definition
for (let i = 1; i <= 100; i++) {
for (let i = 1; i <= 100; i++) { // why 100
tables["table" + i] = [{ col1: "x", col2: "x", col3: "x", col4: "x" }];
}
return tables;
};
const getLargeDataset = () => {
const rows: any = [];
const colData: string =
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const rows: any = []; // TODO: be more specific on type definition
const colData: string = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // FIXME: no need to explicitly mention data type
for (let i = 1; i <= 10000; i++) {
rows.push({ col1: colData, col2: colData, col3: colData, col4: colData });
}
const data: any = {
const data: any = { // TODO: be more specific on type definition
table1: rows,
};
return data;
};
const errorAndCsrfData: any = {
// FIXME: declared but never used
const errorAndCsrfData: any = { // TODO: be more specific on type definition
error: [{ col1: "q", col2: "w", col3: "e", col4: "r" }],
_csrf: [{ col1: "q", col2: "w", col3: "e", col4: "r" }],
};
@@ -84,10 +86,8 @@ export const specialCaseTests = (adapter: SASjs): TestSuite => ({
{
title: "Common special characters",
description: "Should handle common special characters",
test: () => {
return adapter.request("common/sendArr", specialCharData);
},
assertion: (res: any) => {
test: () => adapter.request("common/sendArr", specialCharData),
assertion: (res: any) => { // TODO: be more specific on type definition
return (
res.table1[0][0] === specialCharData.table1[0].tab &&
res.table1[0][1] === specialCharData.table1[0].lf &&
@@ -102,6 +102,8 @@ export const specialCaseTests = (adapter: SASjs): TestSuite => ({
);
},
},
// TODO: delete commented out code
// {
// title: "Other special characters",
// description: "Should handle other special characters",
@@ -180,15 +182,15 @@ export const specialCaseTests = (adapter: SASjs): TestSuite => ({
{
title: "Large dataset",
description: "Should handle 5mb of data",
test: () => {
return adapter.request("common/sendArr", getLargeDataset());
},
assertion: (res: any) => {
test: () => adapter.request("common/sendArr", getLargeDataset()),
assertion: (res: any) => { // TODO: be more specific on type definition
const data = getLargeDataset();
let result = true;
let result = true; // TODO: rename
for (let i = 0; i <= 10; i++) {
result = result && res.table1[i][0] === data.table1[i][0];
}
return result;
},
},
@@ -232,4 +234,4 @@ export const specialCaseTests = (adapter: SASjs): TestSuite => ({
// },
// },
],
});
});

View File

@@ -12,4 +12,4 @@ export interface TestSuite {
tests: Test[];
beforeAll?: (...args: any) => Promise<any>;
afterAll?: (...args: any) => Promise<any>;
}
}

View File

@@ -3,20 +3,21 @@ export const assert = (
message = "Assertion failed"
) => {
let result;
try {
if (typeof expression === "boolean") {
result = expression;
} else {
result = expression();
}
if (typeof expression === "boolean") result = expression;
else result = expression();
} catch (e) {
console.error(message);
throw new Error(message);
}
if (!!result) {
return;
} else {
console.error(message);
throw new Error(message);
}
};

View File

@@ -3,21 +3,25 @@ export const uploadFile = (file: File, fileName: string, url: string) => {
const data = new FormData();
data.append("file", file);
data.append("filename", fileName);
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
xhr.addEventListener("readystatechange", function () { // TODO: use ES6
if (this.readyState === 4) {
let response: any;
try {
response = JSON.parse(this.responseText);
} catch (e) {
reject(e);
}
resolve(response);
}
});
xhr.open("POST", url);
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
});
};
};

View File

@@ -1,10 +1,10 @@
export const splitChunks = (content: string) => {
const size = 16000;
export const splitChunks = (content: string) => { // TODO: set return type
const size = 16000; // why 16000?
const numChunks = Math.ceil(content.length / size);
const chunks = new Array(numChunks);
for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
for (let i = 0, o = 0; i < numChunks; ++i, o += size) { // FIXME: name variables properly
chunks[i] = content.substr(o, size);
}