All files / src/preprocessor resolvePeopleRefs.ts

50.64% Statements 39/77
45% Branches 9/20
100% Functions 5/5
50% Lines 37/74

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133        1x       32x 32x     32x   32x 9x 9x     9x 9x       54x     8x 23x               3x 3x 3x 3x     8x 8x 8x 8x     8x 8x 8x 8x     3x 3x 3x 3x                 1x 1x 1x 1x                                                                                                     8x     8x 54x     8x     32x    
import { DOMParser } from 'xmldom'
 
import PersonGenerator from '../generators/PersonGenerator'
 
export const resolvePeopleRefs = (
    xml: string,
    people: Record<string, PersonGenerator> = {}
): string => {
    const parser = new DOMParser()
    const dom = parser.parseFromString(xml, 'text/xml')
 
    // replace person nodes with their actual content
    const usePersonNodes = Array.from(dom.getElementsByTagName('UsePerson'))
 
    usePersonNodes.forEach( usePersonNode => {
        const personName = usePersonNode.getAttribute('ref')
        Iif (!personName) return
 
        // get the person generator for this <UsePerson> tag
        const person = people[personName]
        if (!person) return
 
        // get the children of the <UsePerson> tag
        // these are the nodes that need to be resolved
        const children = Array.from(usePersonNode.childNodes).filter((n) => n.nodeType === 1)
 
        // resolve the children nodes
        children.forEach((child) => {
            switch (child.nodeName) {
            case 'Sex': {
                const sex = person.sex
                const textNode = dom.createTextNode(sex)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Prefix': {
                const prefix = person.getName('{prefix}')
                const textNode = dom.createTextNode(prefix)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'FirstName': {
                const firstName = person.getName('{firstName}')
                const textNode = dom.createTextNode(firstName)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'LastName': {
                const lastName = person.getName('{lastName}')
                const textNode = dom.createTextNode(lastName)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'MiddleName': {
                const middleName = person.getName('{middleName}')
                const textNode = dom.createTextNode(middleName)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'FullName': {
                const fullName = person.getName()
                const textNode = dom.createTextNode(fullName)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Email': {
                const email = person.getEmail()
                const textNode = dom.createTextNode(email)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Phone': {
                const phone = person.getPhone()
                const textNode = dom.createTextNode(phone)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Address': {
                const address = person.getAddress()
                const textNode = dom.createTextNode(address)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Street': {
                const street = person.getAddress('{street}')
                const textNode = dom.createTextNode(street)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'City': {
                const city = person.getAddress('{city}')
                const textNode = dom.createTextNode(city)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'State': {
                const state = person.getAddress('{state}')
                const textNode = dom.createTextNode(state)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Zip': {
                const zip = person.getAddress('{zip}')
                const textNode = dom.createTextNode(zip)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            case 'Country': {
                const country = person.getAddress('{country}')
                const textNode = dom.createTextNode(country)
                child.parentNode?.replaceChild(textNode, child)
                break
            }
            default:
                throw new Error(`Unknown tag: ${child.nodeName}`)
            }
        })
 
 
        // parent content is the child nodes of the <UsePerson> node
        const parentContent = Array.from(usePersonNode.childNodes)
 
        // replace the <UsePerson> node with the children nodes
        parentContent.forEach((child) => {
            usePersonNode.parentNode?.insertBefore(child, usePersonNode)
        })
 
        usePersonNode.parentNode?.removeChild(usePersonNode)
    })
 
    return dom.toString()
}