chore(client): migrate TestSuite component to TypeScript (#43794)
* chore: rename Test-Suite.js to test-suite.tsx * feat: migrate test-suite to ts * feat: use type guard to narrow down tests prop * revert: text prop from Test type I added when rebasing * remove optionality from props Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com> Co-authored-by: Shaun Hamilton <shauhami020@gmail.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>pull/44311/head
parent
0deac73642
commit
a152420041
|
@ -1,17 +1,18 @@
|
|||
import React, { useEffect, ReactElement } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { Test } from '../../../redux/prop-types';
|
||||
|
||||
import { mathJaxScriptLoader } from '../../../utils/script-loaders';
|
||||
import { challengeTestsSelector } from '../redux';
|
||||
import TestSuite from './Test-Suite';
|
||||
import TestSuite from './test-suite';
|
||||
import ToolPanel from './tool-panel';
|
||||
|
||||
import './side-panel.css';
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
challengeTestsSelector,
|
||||
(tests: Record<string, unknown>[]) => ({
|
||||
(tests: Test[]) => ({
|
||||
tests
|
||||
})
|
||||
);
|
||||
|
@ -22,7 +23,7 @@ interface SidePanelProps {
|
|||
guideUrl: string;
|
||||
instructionsPanelRef: React.RefObject<HTMLDivElement>;
|
||||
showToolPanel: boolean;
|
||||
tests?: Record<string, unknown>[];
|
||||
tests: Test[];
|
||||
videoUrl: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import Fail from '../../../assets/icons/fail';
|
||||
|
@ -6,12 +5,22 @@ import GreenPass from '../../../assets/icons/green-pass';
|
|||
import Initial from '../../../assets/icons/initial';
|
||||
|
||||
import './test-suite.css';
|
||||
import { ChallengeTest, Test } from '../../../redux/prop-types';
|
||||
|
||||
const propTypes = {
|
||||
tests: PropTypes.arrayOf(PropTypes.object)
|
||||
};
|
||||
type TestSuiteTest = {
|
||||
err?: string;
|
||||
pass?: boolean;
|
||||
} & ChallengeTest;
|
||||
|
||||
function getAccessibleText(err, pass, text) {
|
||||
function isTestSuiteTest(test: Test): test is TestSuiteTest {
|
||||
return 'text' in test;
|
||||
}
|
||||
|
||||
interface TestSuiteProps {
|
||||
tests: Test[];
|
||||
}
|
||||
|
||||
function getAccessibleText(text: string, err?: string, pass?: boolean) {
|
||||
let accessibleText = 'Waiting';
|
||||
const cleanText = text.replace(/<\/?code>/g, '');
|
||||
|
||||
|
@ -26,17 +35,19 @@ function getAccessibleText(err, pass, text) {
|
|||
return accessibleText + ' - ' + cleanText;
|
||||
}
|
||||
|
||||
function TestSuite({ tests }) {
|
||||
function TestSuite({ tests }: TestSuiteProps): JSX.Element {
|
||||
const testSuiteTests = tests.filter(isTestSuiteTest);
|
||||
|
||||
return (
|
||||
<div className='challenge-test-suite'>
|
||||
{tests.map(({ err, pass = false, text = '' }, index) => {
|
||||
{testSuiteTests.map(({ err, pass = false, text = '' }, index) => {
|
||||
const isInitial = !pass && !err;
|
||||
const statusIcon = pass && !err ? <GreenPass /> : <Fail />;
|
||||
return (
|
||||
<div
|
||||
aria-label={getAccessibleText(err, pass, text)}
|
||||
aria-label={getAccessibleText(text, err, pass)}
|
||||
className='test-result'
|
||||
key={text.slice(-6) + index}
|
||||
key={text.slice(-6) + String(index)}
|
||||
>
|
||||
<div className='test-status-icon'>
|
||||
{isInitial ? <Initial /> : statusIcon}
|
||||
|
@ -45,7 +56,6 @@ function TestSuite({ tests }) {
|
|||
aria-hidden='true'
|
||||
className='test-output'
|
||||
dangerouslySetInnerHTML={{ __html: text }}
|
||||
xs={10}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -55,6 +65,5 @@ function TestSuite({ tests }) {
|
|||
}
|
||||
|
||||
TestSuite.displayName = 'TestSuite';
|
||||
TestSuite.propTypes = propTypes;
|
||||
|
||||
export default TestSuite;
|
|
@ -20,11 +20,11 @@ import {
|
|||
} from '../../../../redux/prop-types';
|
||||
import ChallengeDescription from '../../components/Challenge-Description';
|
||||
import Hotkeys from '../../components/Hotkeys';
|
||||
import TestSuite from '../../components/Test-Suite';
|
||||
import ChallengeTitle from '../../components/challenge-title';
|
||||
import CompletionModal from '../../components/completion-modal';
|
||||
import HelpModal from '../../components/help-modal';
|
||||
import Output from '../../components/output';
|
||||
import TestSuite from '../../components/test-suite';
|
||||
import {
|
||||
challengeMounted,
|
||||
challengeTestsSelector,
|
||||
|
|
Loading…
Reference in New Issue