util#format TypeScript Examples

The following examples show how to use util#format. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: hooks.ts    From posthog-foss with MIT License 6 votes vote down vote up
export function getFormattedMessage(
    action: Action,
    event: PluginEvent,
    person: Person | undefined,
    siteUrl: string,
    webhookType: WebhookType
): [string, string] {
    const messageFormat = action.slack_message_format || '[action.name] was triggered by [user.name]'
    let messageText: string
    let messageMarkdown: string

    try {
        const [tokens, tokenizedMessage] = getTokens(messageFormat)
        const values: string[] = []
        const markdownValues: string[] = []

        for (const token of tokens) {
            const tokenParts = token.match(/\w+/g) || []

            const [value, markdownValue] = getValueOfToken(action, event, person, siteUrl, webhookType, tokenParts)
            values.push(value)
            markdownValues.push(markdownValue)
        }
        messageText = format(tokenizedMessage, ...values)
        messageMarkdown = format(tokenizedMessage, ...markdownValues)
    } catch (error) {
        const [actionName, actionMarkdown] = getActionDetails(action, siteUrl, webhookType)
        messageText = `⚠ Error: There are one or more formatting errors in the message template for action "${actionName}".`
        messageMarkdown = `*⚠ Error: There are one or more formatting errors in the message template for action "${actionMarkdown}".*`
    }

    return [messageText, messageMarkdown]
}
Example #2
Source File: echo.ts    From gitmars with GNU General Public License v3.0 6 votes vote down vote up
/**
 * 读取gitmars在线版本列表
 *
 * @param name - 需要查询的内容
 * @returns {Object} arr 返回配置对象
 */
function echo(message: string): void {
    let output = format(message)
    output += '\n'
    process.stdout.write(output)
}
Example #3
Source File: echo.ts    From gitmars with GNU General Public License v3.0 6 votes vote down vote up
/**
 * 输出日志
 * @example
 *
 * @param message - 需要输出的内容
 * @param type - 输出的类型
 */
function echo(
    message: string,
    type?: 'warning' | 'info' | 'error' | 'success'
): void {
    let output = format(message)
    switch (type) {
        case 'warning':
            output = yellow(output)
            break
        case 'error':
            output = red(output)
            break
        case 'success':
            output = green(output)
            break
        default:
            break
    }
    output += '\n'
    process.stdout.write(output)
}
Example #4
Source File: installer.ts    From azure-pipelines-tasks-flyway with MIT License 6 votes vote down vote up
function getDownloadUrl(version: string): string {
    var url = format("https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/%s/flyway-commandline-%s-%s", version, version);
    switch(os.type()){
        case 'Linux':
            return format(url, "linux-x64.tar.gz");
        case 'Darwin':
            return format(url, "macosx-x64.tar.gz");        
        case 'Windows_NT':
            return format(url, "windows-x64.zip");
        default:
            throw new Error(`Operating system ${os.type()} is not supported.`);
    }
}
Example #5
Source File: filestorage.ts    From foodie with MIT License 6 votes vote down vote up
uploadImageToStorage = (file) => {
    return new Promise((resolve, reject) => {
        if (!file) {
            reject('No image file');
        }
        let newFileName = `${file.originalname}`;

        let fileUpload = bucket.file(newFileName);

        const blobStream = fileUpload.createWriteStream({
            metadata: {
                contentType: file.mimetype
            }
        });

        blobStream.on('error', (err) => {
            console.log(err);
            reject('Something is wrong! Unable to upload at the moment.');
        });

        blobStream.on('finish', () => {
            // The public URL can be used to directly access the file via HTTP.
            const url = format(`https://storage.googleapis.com/${bucket.name}/${fileUpload.name}`);
            resolve(url);
        });

        blobStream.end(file.buffer);
    });
}
Example #6
Source File: debug.ts    From hoprnet with GNU General Public License v3.0 6 votes vote down vote up
wrappedDebug = (namespace: any) => {
  return (message: any, ...parameters: any[]) => {
    if (process.env.TELEMETRY && process.env.TELEMETRY_ID) {
      const log = format(message, ...parameters)
      logger.info({ id: process.env.TELEMETRY_ID, log: log, ts: new Date(Date.now()).toISOString() })
    }
    return debug(namespace)(message, ...parameters)
  }
}
Example #7
Source File: log-delivery.ts    From cloudformation-cli-typescript-plugin with Apache License 2.0 6 votes vote down vote up
log(message?: any, ...optionalParams: any[]): void {
        const formatted = format(message, ...optionalParams);
        const eventTime = new Date(Date.now());
        for (const logPublisher of this.logPublishers) {
            this.tracker.addSubmitted();
            (async () => {
                try {
                    await logPublisher.publishLogEvent(formatted, eventTime);
                    this.tracker.addCompleted();
                } catch (err) {
                    console.error(err);
                    if (err.retryable === true) {
                        try {
                            await logPublisher.publishLogEvent(formatted, eventTime);
                            this.tracker.addCompleted();
                        } catch (err) {
                            console.error(err);
                            this.tracker.addFailed();
                        }
                    } else {
                        this.tracker.addFailed();
                    }
                }
            })();
        }
    }
Example #8
Source File: nexpect.ts    From amplify-codegen with Apache License 2.0 6 votes vote down vote up
function createExpectationError(expected: string | RegExp, actual: string) {
  var expectation;
  if (isRegExp(expected)) {
    expectation = 'to match ' + expected;
  } else {
    expectation = 'to contain ' + JSON.stringify(expected);
  }

  var err = new AssertionError({
    message: format('expected %j %s', actual, expectation),
    actual: actual,
    expected: expected,
  });
  return err;
}
Example #9
Source File: filesystem.ts    From devoirs with MIT License 6 votes vote down vote up
async load(): Promise<Token> {
    const path = await this.getPath();

    if (!(await this.exists())) {
      throw new Error(format('File not exists or not a file: %s', path));
    }

    return await readFile(path, {
      encoding: this.encoding,
    });
  }
Example #10
Source File: client.ts    From devoirs with MIT License 6 votes vote down vote up
transform = (assignment: Assignment) => {
  const dueDateTime = moment(assignment.dueDateTime);
  const nowDateTime = moment();

  return {
    ...assignment,
    dueDateTime: dueDateTime.format('ll LTS'),
    isOverdue: !assignment.isCompleted && dueDateTime.isBefore(nowDateTime),
  };
}
Example #11
Source File: log.ts    From elephize with MIT License 6 votes vote down vote up
public _printLog(message: string, msgid: string, params: string[], severity: LogSeverity, context = '') {
    if (this.baseDir && severity !== LogSeverity.SPECIAL) {
      message = message.replace(this.baseDir, '[base]');
    }
    if (this.outDir && severity !== LogSeverity.SPECIAL) {
      message = message.replace(this.outDir, '[out]');
    }

    let marker: string = chalk.dim(`[i #${msgid}]`);
    switch (severity) {
      case LogSeverity.ERROR:
        marker = chalk.bgRedBright(chalk.black(`[E #${msgid}]`));
        break;
      case LogSeverity.WARN:
        marker = chalk.bgYellowBright(chalk.black(`[W #${msgid}]`));
        break;
      case LogSeverity.SPECIAL:
        marker = chalk.bgGreenBright(chalk.black(`[! #${msgid}]`));
        break;
      case LogSeverity.INFO:
      default:
        break;
    }

    message = format(message, ...params); // apply parameters to string strictly after hashing

    const dt = new Date();
    const pieces = [dt.getHours(), dt.getMinutes(), dt.getSeconds()].map((p) => p.toString().padStart(2, '0'));
    const timer = chalk.ansi(90)(`[${pieces.join(':')}:${dt.getMilliseconds().toString().padStart(3, '0')}]`);

    const str = `${marker}${timer} ${message}${context ? '\n   ' + context : ''}`;
    if (severity === LogSeverity.ERROR || this.forceStderr) {
      writeSync(STDERR_FILE_DESCRIPTOR, str + (str.endsWith('\n') ? '' : '\n'));
    } else {
      writeSync(STDOUT_FILE_DESCRIPTOR, str + (str.endsWith('\n') ? '' : '\n'));
    }
  }
Example #12
Source File: log.ts    From AIPerf with MIT License 6 votes vote down vote up
/**
     * if the experiment is not in readonly mode, write log content to stream
     * @param level log level
     * @param param the params to be written
     */
    private log(level: string, param: any[]): void {
        if (!this.readonly) {
            const logContent = `[${(new Date()).toLocaleString()}] ${level} ${format(param)}\n`;
            if (this.writable && this.bufferSerialEmitter) {
                const buffer: WritableStreamBuffer = new WritableStreamBuffer();
                buffer.write(logContent);
                buffer.end();
                this.bufferSerialEmitter.feed(buffer.getContents());
            } else {
                console.log(logContent);
            }
        }
    }
Example #13
Source File: client.ts    From devoirs with MIT License 5 votes vote down vote up
async start(): Promise<void> {
    const assetsDirectory = await this.resourceResolver.resolve('assets');
    const page = await this.chromiumLauncher.launch(
      format(
        'file:///%s',
        [...assetsDirectory.split(sep).map(encode), 'index.html'].join('/')
      )
    );

    for (const c of await this.apiClient.getClasses()) {
      const assignments = (await this.apiClient.getAssignments(c.id))
        .sort(compare)
        .map(transform);

      await page.evaluate(
        (c: Class, assignments: (Assignment & { isOverdue: boolean })[]) => {
          const $classes = document.getElementById('classes');
          const $class = document.createElement('li');
          const $name = document.createElement('span');
          const $assignments = document.createElement('ul');

          for (const a of assignments) {
            const $assignment = document.createElement('li');

            $assignment.textContent = a.displayName;
            $assignment.setAttribute('data-due-datetime', a.dueDateTime);
            $assignment.setAttribute('data-overdue', a.isOverdue ? '1' : '0');
            $assignment.setAttribute(
              'data-completed',
              a.isCompleted ? '1' : '0'
            );

            $assignments.appendChild($assignment);
          }

          $name.textContent = c.name;
          $name.addEventListener('click', () => {
            $class.classList.toggle('is-hidden');
          });

          $class.appendChild($name);
          $class.appendChild($assignments);
          $classes.appendChild($class);
        },
        (c as unknown) as JSONObject,
        (assignments as unknown) as JSONObject
      );
    }
  }
Example #14
Source File: update-electron-app.ts    From tailchat with GNU General Public License v3.0 5 votes vote down vote up
userAgent = format(
  '%s/%s (%s: %s)',
  pkg.name,
  pkg.version,
  os.platform(),
  os.arch()
)
Example #15
Source File: Logger.ts    From yumeko with GNU Affero General Public License v3.0 5 votes vote down vote up
public date(): string {
        return moment(Date.now()).format(momentFormat);
    }
Example #16
Source File: Logger.ts    From yumeko with GNU Affero General Public License v3.0 5 votes vote down vote up
public color(input: unknown, hex: string): string {
        input = typeof input === "string" ? input : format(input);
        return chalk.hex(hex)(input);
    }
Example #17
Source File: Logger.ts    From yumeko with GNU Affero General Public License v3.0 5 votes vote down vote up
public print(input: unknown): void {
        process.stdout.write(`${format(input)}\n`);
    }
Example #18
Source File: solidity-unit-testing.tsx    From remix-project with MIT License 4 votes vote down vote up
SolidityUnitTesting = (props: Record<string, any>) => { // eslint-disable-line @typescript-eslint/no-explicit-any

  const { helper, testTab, initialPath } = props
  const { testTabLogic } = testTab

  const [toasterMsg, setToasterMsg] = useState<string>('')

  const [disableCreateButton, setDisableCreateButton] = useState<boolean>(true)
  const [disableGenerateButton, setDisableGenerateButton] = useState<boolean>(false)
  const [disableStopButton, setDisableStopButton] = useState<boolean>(true)
  const [disableRunButton, setDisableRunButton] = useState<boolean>(false)
  const [runButtonTitle, setRunButtonTitle] = useState<string>('Run tests')
  const [stopButtonLabel, setStopButtonLabel] = useState<string>('Stop')

  const [checkSelectAll, setCheckSelectAll] = useState<boolean>(true)
  const [testsOutput, setTestsOutput] = useState<ReactElement[]>([])

  const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState<boolean>(true)
  const [progressBarHidden, setProgressBarHidden] = useState<boolean>(true)
  const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState<boolean>(true)

  let [testFiles, setTestFiles] = useState<TestObject[]>([]) // eslint-disable-line
  const [pathOptions, setPathOptions] = useState<string[]>([''])

  const [inputPathValue, setInputPathValue] = useState<string>('tests')

  let [readyTestsNumber, setReadyTestsNumber] = useState<number>(0) // eslint-disable-line
  let [runningTestsNumber, setRunningTestsNumber] = useState<number>(0) // eslint-disable-line

  const areTestsRunning = useRef<boolean>(false)
  const hasBeenStopped = useRef<boolean>(false)
  const isDebugging = useRef<boolean>(false)
  const allTests = useRef<string[]>([])
  const selectedTests = useRef<string[]>([])
  const currentTestFiles:any = useRef([]) // stores files for which tests have been run
  const currentErrors:any = useRef([]) // eslint-disable-line @typescript-eslint/no-explicit-any

  const defaultPath = 'tests'

  let runningTestFileName: string
  const filesContent: Record<string, Record<string, string>> = {}
  const testsResultByFilename: Record<string, Record<string, Record<string, any>>> = {} // eslint-disable-line @typescript-eslint/no-explicit-any

  const trimTestDirInput = (input: string) => {
    if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/')
    else return input.trim()
  }

  const clearResults = () => {
    setProgressBarHidden(true)
    testTab.call('editor', 'clearAnnotations')
    setTestsOutput([])
    setTestsExecutionStoppedHidden(true)
    setTestsExecutionStoppedErrorHidden(true)
  }

  const updateForNewCurrent = async (file: string | null = null) => {
    // Ensure that when someone clicks on compilation error and that opens a new file
    // Test result, which is compilation error in this case, is not cleared
    if (currentErrors.current) {
      if (Array.isArray(currentErrors.current) && currentErrors.current.length > 0) {
        const errFiles = currentErrors.current.map((err:any) => { if (err.sourceLocation && err.sourceLocation.file) return err.sourceLocation.file }) // eslint-disable-line
        if (errFiles.includes(file)) return
      } else if (currentErrors.current.sourceLocation && currentErrors.current.sourceLocation.file && currentErrors.current.sourceLocation.file === file) return
    }
    // if current file is changed while debugging and one of the files imported in test file are opened
    // do not clear the test results in SUT plugin
    if ((isDebugging.current && testTab.allFilesInvolved.includes(file)) || currentTestFiles.current.includes(file)) return
    allTests.current = []
    updateTestFileList()
    clearResults()
    try {
      const tests = await testTabLogic.getTests()
      allTests.current = tests
      selectedTests.current = [...allTests.current]
      updateTestFileList()
      if (!areTestsRunning.current) await updateRunAction(file)
    } catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any
      console.log(e)
      setToasterMsg(e)
    }
  }

  /**
 * Changes the current path of Unit Testing Plugin
 * @param path - the path from where UT plugin takes _test.sol files to run
 */
  const setCurrentPath = async (path: string) => {
    testTabLogic.setCurrentPath(path)
    setInputPathValue(path)
    updateDirList(path)
    await updateForNewCurrent()
  }

  useEffect(() => {
    if (initialPath) setCurrentPath(initialPath)
  }, [initialPath]) // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    testTab.on('filePanel', 'newTestFileCreated', async (file: string) => {
      try {
        const tests = await testTabLogic.getTests()
        allTests.current = tests
        selectedTests.current = [...allTests.current]
        updateTestFileList()
      } catch (e) {
        console.log(e)
        allTests.current.push(file)
        selectedTests.current.push(file)
      }
    })

    testTab.on('filePanel', 'setWorkspace', async () => {
      await setCurrentPath(defaultPath)
    })

    testTab.fileManager.events.on('noFileSelected', async () => { await updateForNewCurrent() })
    testTab.fileManager.events.on('currentFileChanged', async (file: string) => await updateForNewCurrent(file))

  }, []) // eslint-disable-line

  const updateDirList = (path: string) => {
    testTabLogic.dirList(path).then((options: string[]) => {
      setPathOptions(options)
    })
  }

  const handleTestDirInput = async (e: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    let testDirInput = trimTestDirInput(e.target.value)
    testDirInput = helper.removeMultipleSlashes(testDirInput)
    setInputPathValue(testDirInput)
    if (testDirInput) {
      if (testDirInput.endsWith('/') && testDirInput !== '/') {
        testDirInput = helper.removeTrailingSlashes(testDirInput)
        if (testTabLogic.currentPath === testDirInput.substr(0, testDirInput.length - 1)) {
          setDisableCreateButton(true)
          setDisableGenerateButton(true)
        }
        updateDirList(testDirInput)
      } else {
        // If there is no matching folder in the workspace with entered text, enable Create button
        if (await testTabLogic.pathExists(testDirInput)) {
          setDisableCreateButton(true)
          setDisableGenerateButton(false)
          
        } else {
          // Enable Create button
          setDisableCreateButton(false)
          // Disable Generate button because dir does not exist
          setDisableGenerateButton(true)
        }
        await setCurrentPath(testDirInput)
      }
    } else {
      await setCurrentPath('/')
      setDisableCreateButton(true)
      setDisableGenerateButton(false)
    }
  }

  const handleCreateFolder = async () => {
    let inputPath = trimTestDirInput(inputPathValue)
    let path = helper.removeMultipleSlashes(inputPath)
    if (path !== '/') path = helper.removeTrailingSlashes(path)
    if (inputPath === '') inputPath = defaultPath
    setInputPathValue(path)
    await testTabLogic.generateTestFolder(inputPath)
    setToasterMsg('Folder created successfully')
    setDisableCreateButton(true)
    setDisableGenerateButton(false)
    testTabLogic.setCurrentPath(inputPath)
    await updateRunAction()
    await updateForNewCurrent()
    pathOptions.push(inputPath)
    setPathOptions(pathOptions)
  }

  const cleanFileName = (fileName: string, testSuite: string) => {
    return fileName ? fileName.replace(/\//g, '_').replace(/\./g, '_') + testSuite : fileName
  }

  const startDebug = async (txHash: string, web3: Web3) => {
    isDebugging.current = true
    if (!await testTab.appManager.isActive('debugger')) await testTab.appManager.activatePlugin('debugger')
    testTab.call('menuicons', 'select', 'debugger')
    testTab.call('debugger', 'debug', txHash, web3)
  }

  const printHHLogs = (logsArr: Record<string, any>[], testName: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    let finalLogs = `<b>${testName}:</b>\n`
    for (const log of logsArr) {
      let formattedLog
      // Hardhat implements the same formatting options that can be found in Node.js' console.log,
      // which in turn uses util.format: https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args
      // For example: console.log("Name: %s, Age: %d", remix, 6) will log 'Name: remix, Age: 6'
      // We check first arg to determine if 'util.format' is needed
      if (typeof log[0] === 'string' && (log[0].includes('%s') || log[0].includes('%d'))) {
        formattedLog = format(log[0], ...log.slice(1))
      } else {
        formattedLog = log.join(' ')
      }
      finalLogs = finalLogs + '&emsp;' + formattedLog + '\n'
    }
    _paq.push(['trackEvent', 'solidityUnitTesting', 'hardhat', 'console.log'])
    testTab.call('terminal', 'log', { type: 'info', value: finalLogs })
  }

  const discardHighlight = async () => {
    await testTab.call('editor', 'discardHighlight')
  }

  const highlightLocation = async (location: string, fileName: string) => {
    if (location) {
      const split = location.split(':')
      const file = split[2]
      const parsedLocation = {
        start: parseInt(split[0]),
        length: parseInt(split[1])
      }
      const locationToHighlight = testTab.offsetToLineColumnConverter.offsetToLineColumnWithContent(
        parsedLocation,
        parseInt(file),
        filesContent[fileName].content
      )
      await testTab.call('editor', 'discardHighlight')
      await testTab.call('editor', 'highlight', locationToHighlight, fileName, '', { focus: true })
    }
  }

  const renderContract = (filename: string, contract: string|null, index: number, withoutLabel = false) => {
    if (withoutLabel) {
      const contractCard: ReactElement = (
        <div id={runningTestFileName} data-id="testTabSolidityUnitTestsOutputheader" className="pt-1">
          <span className="font-weight-bold">{contract ? contract : ''} ({filename})</span>
        </div>
      )
      setTestsOutput(prevCards => ([...prevCards, contractCard]))
      return
    }
    let label
    if (index > -1) {
      const className = "alert-danger d-inline-block mb-1 mr-1 p-1 failed_" + runningTestFileName
      label = (<div
      className={className}
      title="At least one contract test failed"
    >
      FAIL
    </div>)
    } else {
      const className = "alert-success d-inline-block mb-1 mr-1 p-1 passed_" + runningTestFileName
      label = (<div
      className={className}
      title="All contract tests passed"
    >
      PASS
    </div>)
    }
    // show contract and file name with label
    const ContractCard: ReactElement = (
      <div id={runningTestFileName} data-id="testTabSolidityUnitTestsOutputheader" className="pt-1">
        {label}<span className="font-weight-bold">{contract} ({filename})</span>
      </div>
    )
    setTestsOutput(prevCards => {
      const index = prevCards.findIndex((card: ReactElement) => card.props.id === runningTestFileName)
      prevCards[index] = ContractCard
      return prevCards
    })
  }

  const renderTests = (tests: TestResultInterface[], contract: string, filename: string) => {
    const index = tests.findIndex((test: TestResultInterface) => test.type === 'testFailure')
    // show filename and contract
    renderContract(filename, contract, index)
    // show tests
    for (const test of tests) {
      if (!test.rendered) {
        let debugBtn
        if (test.debugTxHash) {
          const { web3, debugTxHash } = test
          debugBtn = (
            <div id={test.value.replaceAll(' ', '_')} className="btn border btn btn-sm ml-1" style={{ cursor: 'pointer' }} title="Start debugging" onClick={() => startDebug(debugTxHash, web3)}>
              <i className="fas fa-bug"></i>
            </div>
          )
        }
        if (test.type === 'testPass') {
          if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
          const testPassCard: ReactElement = (
            <div
              id={runningTestFileName}
              data-id="testTabSolidityUnitTestsOutputheader"
              className="testPass testLog bg-light mb-2 px-2 text-success border-0"
              onClick={() => discardHighlight()}
            >
              <div className="d-flex my-1 align-items-start justify-content-between">
                <span > ✓ {test.value}</span>
                {debugBtn}
              </div>
            </div>
          )
          setTestsOutput(prevCards => ([...prevCards, testPassCard]))
          test.rendered = true
        } else if (test.type === 'testFailure') {
          if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
          if (!test.assertMethod) {
            const testFailCard1: ReactElement = (<div
              className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0"
              id={"UTContext" + test.context}
              onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}}
            >
              <div className="d-flex my-1 align-items-start justify-content-between">
                <span> ✘ {test.value}</span>
                {debugBtn}
              </div>
              <span className="text-dark">Error Message:</span>
              <span className="pb-2 text-break">"{test.errMsg}"</span>
            </div>)
            setTestsOutput(prevCards => ([...prevCards, testFailCard1]))
          } else {
            const preposition = test.assertMethod === 'equal' || test.assertMethod === 'notEqual' ? 'to' : ''
            const method = test.assertMethod === 'ok' ? '' : test.assertMethod
            const expected = test.assertMethod === 'ok' ? '\'true\'' : test.expected
            const testFailCard2: ReactElement = (<div
              className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0"
              id={"UTContext" + test.context}
              onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}}
            >
              <div className="d-flex my-1 align-items-start justify-content-between">
                <span> ✘ {test.value}</span>
                {debugBtn}
              </div>
              <span className="text-dark">Error Message:</span>
              <span className="pb-2 text-break">"{test.errMsg}"</span>
              <span className="text-dark">Assertion:</span>
              <div className="d-flex flex-wrap">
                <span>Expected value should be</span>
                <div className="mx-1 font-weight-bold">{method}</div>
                <div>{preposition} {expected}</div>
              </div>
              <span className="text-dark">Received value:</span>
              <span>{test.returned}</span>
              <span className="text-dark text-sm pb-2">Skipping the remaining tests of the function.</span>
            </div>)
            setTestsOutput(prevCards => ([...prevCards, testFailCard2]))
          }
          test.rendered = true
        } else if (test.type === 'logOnly') {
          if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
          test.rendered = true
        }
      }
    }
  }

  const showTestsResult = () => {
    const filenames = Object.keys(testsResultByFilename)
    currentTestFiles.current = filenames
    for (const filename of filenames) {
      const fileTestsResult = testsResultByFilename[filename]
      const contracts = Object.keys(fileTestsResult)
      for (const contract of contracts) {
        if (contract && contract !== 'summary' && contract !== 'errors') {
          runningTestFileName = cleanFileName(filename, contract)
          const tests = fileTestsResult[contract] as TestResultInterface[]
          if (tests?.length) {
            renderTests(tests, contract, filename)
          } else {
            // show only contract and file name
            renderContract(filename, contract, -1, true)
          }
        } else if (contract === 'errors' && fileTestsResult['errors']) {
          const errors = fileTestsResult['errors']
          if (errors && errors.errors) {
            errors.errors.forEach((err: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
              const errorCard: ReactElement = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} />
              setTestsOutput(prevCards => ([...prevCards, errorCard]))
            })
          } else if (errors && Array.isArray(errors) && (errors[0].message || errors[0].formattedMessage)) {
            errors.forEach((err) => {
              const errorCard: ReactElement = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} />
              setTestsOutput(prevCards => ([...prevCards, errorCard]))
            })
          } else if (errors && !errors.errors && !Array.isArray(errors)) {
            // To track error like this: https://github.com/ethereum/remix/pull/1438
            const errorCard: ReactElement = <Renderer message={errors.formattedMessage || errors.message} plugin={testTab} opt={{ type: 'error' }} />
            setTestsOutput(prevCards => ([...prevCards, errorCard]))
          }
        }
      }
      // show summary
      const testSummary = fileTestsResult['summary']
      if (testSummary && testSummary.filename && !testSummary.rendered) {
        const summaryCard: ReactElement = (<div className="d-flex alert-secondary mb-3 p-3 flex-column">
          <span className="font-weight-bold">Result for {testSummary.filename}</span>
          <span className="text-success">Passed: {testSummary.passed}</span>
          <span className="text-danger">Failed: {testSummary.failed}</span>
          <span>Time Taken: {testSummary.timeTaken}s</span>
        </div>)
        setTestsOutput(prevCards => ([...prevCards, summaryCard]))
        fileTestsResult['summary']['rendered'] = true
      }
    }
  }

  const testCallback = (result: Record<string, any>) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    if (result.filename) {
      if (!testsResultByFilename[result.filename]) {
        testsResultByFilename[result.filename] = {}
        testsResultByFilename[result.filename]['summary'] = {}
      }
      if (result.type === 'contract') {
        testsResultByFilename[result.filename][result.value] = {}
        testsResultByFilename[result.filename][result.value] = []
      } else {
        // Set that this test is not rendered on UI
        result.rendered = false
        testsResultByFilename[result.filename][result.context].push(result)
      }
      showTestsResult()
    }
  }

  const resultsCallback = (_err: any, result: any, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    // total stats for the test
    // result.passingNum
    // result.failureNum
    // result.timePassed
    cb()
  }

  const updateFinalResult = (_errors: any, result: FinalResult|null, filename: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    ++readyTestsNumber
    setReadyTestsNumber(readyTestsNumber)
    if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) {
      // show only file name
      renderContract(filename, null, -1, true)
      currentErrors.current = _errors.errors
    }
    if (result) {
      const totalTime = parseFloat(result.totalTime).toFixed(2)
      const testsSummary = { filename, passed: result.totalPassing, failed: result.totalFailing, timeTaken: totalTime, rendered: false }
      testsResultByFilename[filename]['summary'] = testsSummary
      showTestsResult()
    } else if (_errors) {
      if (!testsResultByFilename[filename]) {
        testsResultByFilename[filename] = {}
      }
      testsResultByFilename[filename]['errors'] = _errors
      setTestsExecutionStoppedErrorHidden(false)
      showTestsResult()
    }

    if (hasBeenStopped.current && (readyTestsNumber !== runningTestsNumber)) {
      // if all tests has been through before stopping no need to print this.
      setTestsExecutionStoppedHidden(false)
    }
    if (_errors || hasBeenStopped.current || readyTestsNumber === runningTestsNumber) {
      // All tests are ready or the operation has been canceled or there was a compilation error in one of the test files.
      setDisableStopButton(true)
      setStopButtonLabel('Stop')
      if (selectedTests.current?.length !== 0) {
        setDisableRunButton(false)
      }
      areTestsRunning.current = false
    }
  }

  const runTest = (testFilePath: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    isDebugging.current = false
    if (hasBeenStopped.current) {
      updateFinalResult(null, null, testFilePath)
      return
    }
    testTab.fileManager.readFile(testFilePath).then((content: string) => {
      const runningTests: Record<string, Record<string, string>> = {}
      runningTests[testFilePath] = { content }
      filesContent[testFilePath] = { content }
      const { currentVersion, evmVersion, optimize, runs, isUrl } = testTab.compileTab.getCurrentCompilerConfig()
      const currentCompilerUrl = isUrl ? currentVersion : urlFromVersion(currentVersion)
      const compilerConfig = {
        currentCompilerUrl,
        evmVersion,
        optimize,
        usingWorker: canUseWorker(currentVersion),
        runs
      }
      const deployCb = async (file: string, contractAddress: string) => {
        const compilerData = await testTab.call('compilerArtefacts', 'getCompilerAbstract', file)
        await testTab.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilerData)
      }
      testTab.testRunner.runTestSources(
        runningTests,
        compilerConfig,
        (result: Record<string, any>) => testCallback(result), // eslint-disable-line @typescript-eslint/no-explicit-any
        (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), // eslint-disable-line @typescript-eslint/no-explicit-any
        deployCb,
        (error: any, result: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
          updateFinalResult(error, result, testFilePath)
          callback(error)
        }, (url: string, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
          return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: Error) => cb(error.message)) // eslint-disable-line @typescript-eslint/no-explicit-any
        }, { testFilePath }
      )
    }).catch((error: Error) => {
      console.log(error)
      if (error) return // eslint-disable-line
    })
  }

  const runTests = () => {
    areTestsRunning.current = true
    hasBeenStopped.current = false
    readyTestsNumber = 0
    setReadyTestsNumber(readyTestsNumber)
    runningTestsNumber = selectedTests.current.length
    setRunningTestsNumber(runningTestsNumber)
    setDisableStopButton(false)
    clearResults()
    setProgressBarHidden(false)
    const tests: string[] = selectedTests.current
    if (!tests || !tests.length) return
    else setProgressBarHidden(false)
    _paq.push(['trackEvent', 'solidityUnitTesting', 'runTests'])
    eachOfSeries(tests, (value: string, key: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
      if (hasBeenStopped.current) return
      runTest(value, callback)
    })
  }

  const updateRunAction = async (currentFile: any = null) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    const isSolidityActive = await testTab.appManager.isActive('solidity')
    if (!isSolidityActive || !selectedTests.current.length) {
      setDisableRunButton(true)
      if (!currentFile || (currentFile && currentFile.split('.').pop().toLowerCase() !== 'sol')) {
        setRunButtonTitle('No solidity file selected')
      } else {
        setRunButtonTitle('The "Solidity Plugin" should be activated')
      }
    } else setDisableRunButton(false)
  }

  const stopTests = () => {
    hasBeenStopped.current = true
    setStopButtonLabel('Stopping')
    setDisableStopButton(true)
    setDisableRunButton(true)
  }

  const getCurrentSelectedTests = () => {
    const selectedTestsList: TestObject[] = testFiles.filter(testFileObj => testFileObj.checked)
    return selectedTestsList.map(testFileObj => testFileObj.fileName)
  }

  const toggleCheckbox = (eChecked: boolean, index: number) => {
    testFiles[index].checked = eChecked
    setTestFiles([...testFiles])
    selectedTests.current = getCurrentSelectedTests()
    if (eChecked) {
      setCheckSelectAll(true)
      setDisableRunButton(false)
      if ((readyTestsNumber === runningTestsNumber || hasBeenStopped.current) && stopButtonLabel.trim() === 'Stop') {
        setRunButtonTitle('Run tests')
      }
    } else if (!selectedTests.current.length) {
      setCheckSelectAll(false)
      setDisableRunButton(true)
      setRunButtonTitle('No test file selected')
    } else setCheckSelectAll(false)
  }

  const checkAll = (event: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
    testFiles.forEach((testFileObj) => testFileObj.checked = event.target.checked)
    setTestFiles([...testFiles])
    setCheckSelectAll(event.target.checked)
    if (event.target.checked) {
      selectedTests.current = getCurrentSelectedTests()
      setDisableRunButton(false)
    } else {
      selectedTests.current = []
      setDisableRunButton(true)
    }
  }

  const updateTestFileList = () => {
    if (allTests.current?.length) {
      testFiles = allTests.current.map((testFile: string) => { return { 'fileName': testFile, 'checked': true } })
      setCheckSelectAll(true)
    }
    else
      testFiles = []
    setTestFiles([...testFiles])
  }

  return (
    <div className="px-2" id="testView">
      <Toaster message={toasterMsg} />
      <div className="infoBox">
        <p className="text-lg"> Test your smart contract in Solidity.</p>
        <p> Select directory to load and generate test files.</p>
        <label>Test directory:</label>
        <div>
          <div className="d-flex p-2">
            <datalist id="utPathList">{
              pathOptions.map(function (path) {
                return <option key={path}>{path}</option>
              })
            }
            </datalist>
            <input
              list="utPathList"
              className="inputFolder custom-select"
              id="utPath"
              data-id="uiPathInput"
              name="utPath"
              value={inputPathValue}
              title="Press 'Enter' to change the path for test files."
              style={{ backgroundImage: "var(--primary)" }}
              onKeyDown={() => { if (inputPathValue === '/') setInputPathValue('')} }
              onChange={handleTestDirInput}
              onClick = {() => { if (inputPathValue === '/') setInputPathValue('')} }
            />
            <button
              className="btn border ml-2"
              data-id="testTabGenerateTestFolder"
              title="Create a test folder"
              disabled={disableCreateButton}
              onClick={handleCreateFolder}
            >
              Create
            </button>
          </div>
        </div>
      </div>
      <div>
        <div className="d-flex p-2">
          <button
            className="btn border w-50"
            data-id="testTabGenerateTestFile"
            title="Generate sample test file."
            disabled={disableGenerateButton}
            onClick={async () => {
              await testTabLogic.generateTestFile((err:any) => { if (err) setToasterMsg(err)}) // eslint-disable-line @typescript-eslint/no-explicit-any
              await updateForNewCurrent()
            }}
          >
            Generate
          </button>
          <a className="btn border text-decoration-none pr-0 d-flex w-50 ml-2" title="Check out documentation." target="__blank" href="https://remix-ide.readthedocs.io/en/latest/unittesting.html#test-directory">
            <label className="btn p-1 ml-2 m-0">How to use...</label>
          </a>
        </div>
        <div className="d-flex p-2">
          <button id="runTestsTabRunAction" title={runButtonTitle} data-id="testTabRunTestsTabRunAction" className="w-50 btn btn-primary" disabled={disableRunButton} onClick={runTests}>
            <span className="fas fa-play ml-2"></span>
            <label className="labelOnBtn btn btn-primary p-1 ml-2 m-0">Run</label>
          </button>
          <button id="runTestsTabStopAction" data-id="testTabRunTestsTabStopAction" className="w-50 pl-2 ml-2 btn btn-secondary" disabled={disableStopButton} title="Stop running tests" onClick={stopTests}>
            <span className="fas fa-stop ml-2"></span>
            <label className="labelOnBtn btn btn-secondary p-1 ml-2 m-0" id="runTestsTabStopActionLabel">{stopButtonLabel}</label>
          </button>
        </div>
        <div className="d-flex align-items-center mx-3 pb-2 mt-2 border-bottom">
          <input id="checkAllTests"
            type="checkbox"
            data-id="testTabCheckAllTests"
            onClick={checkAll}
            checked={checkSelectAll}
            onChange={() => { }} // eslint-disable-line
          />
          <label className="text-nowrap pl-2 mb-0" htmlFor="checkAllTests"> Select all </label>
        </div>
        <div className="testList py-2 mt-0 border-bottom">{testFiles.length ? testFiles.map((testFileObj: TestObject, index) => {
          const elemId = `singleTest${testFileObj.fileName}`
          return (
            <div className="d-flex align-items-center py-1" key={index}>
              <input className="singleTest" id={elemId} onChange={(e) => toggleCheckbox(e.target.checked, index)} type="checkbox" checked={testFileObj.checked} />
              <label className="singleTestLabel text-nowrap pl-2 mb-0" htmlFor={elemId}>{testFileObj.fileName}</label>
            </div>
          )
        })
          : "No test file available"} </div>
        <div className="align-items-start flex-column mt-2 mx-3 mb-0">
          <span className='text-info h6' hidden={progressBarHidden}>Progress: {readyTestsNumber} finished (of {runningTestsNumber})</span>
          <label className="text-warning h6" data-id="testTabTestsExecutionStopped" hidden={testsExecutionStoppedHidden}>The test execution has been stopped</label>
          <label className="text-danger h6" data-id="testTabTestsExecutionStoppedError" hidden={testsExecutionStoppedErrorHidden}>The test execution has been stopped because of error(s) in your test file</label>
        </div>
        <div className="mx-3 mb-2 pb-4 border-primary" id="solidityUnittestsOutput" data-id="testTabSolidityUnitTestsOutput">{testsOutput}</div>
      </div>
    </div>
  )
}