export async function copyTestCase()

in src/tdmlEditor/utilities/tdmlXmlUtils.ts [278:452]


export async function copyTestCase(
  xmlFilePath: string,
  destinationFilePath: string,
  append = false
) {
  var xmlBuffer = await readTDMLFileContents(xmlFilePath)
  var destinationBuffer = await readTDMLFileContents(destinationFilePath)

  var xmlObj: Element | ElementCompact = xml2js(xmlBuffer)
  var destinationObj: Element | ElementCompact = xml2js(destinationBuffer)

  const sourceTestSuite = (xmlObj as Element).elements?.filter((node) =>
    node.name?.endsWith(testSuiteElement)
  )

  if (sourceTestSuite === undefined) {
    vscode.window.showErrorMessage(
      'TDML ERROR: No test suite found in source XML buffer'
    )
    throw `No test suite found in source XML buffer`
  }

  if (sourceTestSuite.length !== 1) {
    vscode.window.showErrorMessage(
      'TDML ERROR: More than one test suite found in source XML buffer'
    )
    throw `More than one test suite found in source XML buffer`
  }

  const sourceTestCase = sourceTestSuite[0].elements?.filter((childNode) =>
    childNode.name?.endsWith(testCaseElement)
  )

  if (sourceTestCase === undefined) {
    vscode.window.showErrorMessage(
      'TDML ERROR: No test case found in source XML buffer'
    )
    throw `No test case found in source XML buffer`
  }

  if (sourceTestCase.length !== 1) {
    vscode.window.showErrorMessage(
      'TDML ERROR: More than one test case found in source XML buffer'
    )
    throw `More than one test case found in source XML buffer`
  }

  const rootNode = (xmlObj as Element).elements?.filter((node) =>
    node.name?.endsWith(testSuiteElement)
  )

  if (
    sourceTestCase[0].attributes !== undefined &&
    sourceTestCase[0].attributes[testCaseModelAttribute] !== undefined &&
    rootNode !== undefined
  ) {
    // Each TDML file contains at least one test case
    const testCases = rootNode[0].elements?.filter((node) =>
      node.name?.endsWith(testCaseElement)
    )

    /**
     * Creates an absolute path from the given relative path to the temp TDML file
     *
     * @param relativePath - Relative path to convert into an absolute path
     * @returns
     */
    const getAbsolutePathFromRelativeToTempTDMLFIlePath = (
      relativePath: string
    ) => resolve(dirname(getTmpTDMLFilePath()), relativePath)

    // set to relative path to DFDL file from destination folder
    sourceTestCase[0].attributes[testCaseModelAttribute] = relative(
      dirname(destinationFilePath),
      getAbsolutePathFromRelativeToTempTDMLFIlePath(
        sourceTestCase[0].attributes[testCaseModelAttribute].toString() // Contains relative path to the temp TDML file
      )
    )

    // Each test case may contain any number of documents
    testCases?.forEach((testCaseNode) => {
      testCaseNode.elements
        ?.filter((childNode) => childNode.name?.endsWith(documentElement))
        .forEach((documentNode) =>
          documentNode.elements
            ?.filter((childNode) =>
              childNode.name?.endsWith(documentPartElement)
            )
            .forEach((documentPartNode) => {
              if (
                documentPartNode.elements !== undefined &&
                documentPartNode.elements[0].text !== undefined
              )
                // Set to relative path to data file from destination folder
                documentPartNode.elements[0].text = relative(
                  dirname(destinationFilePath),
                  getAbsolutePathFromRelativeToTempTDMLFIlePath(
                    documentPartNode.elements[0].text.toString() // Contains relative path to the temp TDML file
                  )
                )
            })
        )
    })

    // Each test case may contain any number of infoset
    testCases?.forEach((testCaseNode) => {
      testCaseNode.elements
        ?.filter((childNode) => childNode.name?.endsWith(infosetElement))
        .forEach((infosetNode) =>
          infosetNode.elements
            ?.filter((childNode) =>
              childNode.name?.endsWith(dfdlInfosetElement)
            )
            .forEach((dfdlInfosetNode) => {
              if (
                dfdlInfosetNode.elements !== undefined &&
                dfdlInfosetNode.elements[0].text !== undefined
              ) {
                // Set relative path to infoset from destinatino
                dfdlInfosetNode.elements[0].text = relative(
                  dirname(destinationFilePath),
                  getAbsolutePathFromRelativeToTempTDMLFIlePath(
                    dfdlInfosetNode.elements[0].text.toString() // Relative path from temp TDML file to infoset file
                  )
                )
              }
            })
        )
    })
  }

  if (append) {
    const destinationTestSuite = (destinationObj as Element).elements?.filter(
      (node) => node.name?.endsWith(testSuiteElement)
    )

    if (destinationTestSuite === undefined) {
      vscode.window.showErrorMessage(
        'TDML ERROR: No test suites found in destination XML buffer'
      )
      throw `No test suites found in destination XML buffer`
    }

    if (destinationTestSuite.length !== 1) {
      vscode.window.showErrorMessage(
        'TDML ERROR: More than one test suite found in destination XML buffer'
      )
      throw `More than one test suite found in destination XML buffer`
    }

    const destinationTestCases = destinationTestSuite[0].elements?.filter(
      (childNode) => childNode.name?.endsWith(testCaseElement)
    )
    destinationTestCases?.forEach((testCase) => {
      // Check to see if we are trying to append a duplicate
      // Per the TDML spec, a duplicate is a name-only check
      if (
        testCase.attributes !== undefined &&
        sourceTestCase[0].attributes !== undefined &&
        testCase.attributes[testCaseNameAttribute] ===
          sourceTestCase[0].attributes[testCaseNameAttribute]
      ) {
        vscode.window.showErrorMessage(
          'TDML ERROR: Duplicate Test Case Name Found'
        )
        throw `Duplicate Test Case Name Found`
      }
    })
    destinationTestSuite[0].elements?.push(sourceTestCase[0])

    return js2xml(destinationObj)
  } else {
    return js2xml(xmlObj)
  }
}