mirror of
https://github.com/github/codeql-action.git
synced 2025-12-27 01:30:10 +08:00
240 lines
12 KiB
JavaScript
240 lines
12 KiB
JavaScript
'use strict'
|
|
|
|
function diffShallow (api, actual, expected, theme, indent) {
|
|
const childBuffer = api.lineBuilder.buffer()
|
|
const propertyBuffer = api.lineBuilder.buffer()
|
|
|
|
return {
|
|
append (formatted, origin) {
|
|
if (origin.isItem === true) {
|
|
childBuffer.append(formatted)
|
|
} else {
|
|
propertyBuffer.append(formatted)
|
|
}
|
|
},
|
|
|
|
finalize: () => {
|
|
const namesAreEqual = actual.compareNames(expected)
|
|
const actualName = actual.formatName(theme)
|
|
const expectedName = expected.formatName(theme)
|
|
|
|
const openTag = theme.react.openTag
|
|
const innerIndentation = indent.increase()
|
|
|
|
const allChildren = childBuffer.withFirstPrefixed(innerIndentation)
|
|
const children = allChildren.decompose()
|
|
|
|
const allProperties = propertyBuffer.withFirstPrefixed(innerIndentation)
|
|
const properties = allProperties.decompose()
|
|
// If the first properties are also the last, and either side has no
|
|
// children, ensure the properties are treated as being last. This
|
|
// leads to a better balanced diff.
|
|
if (properties.remaining.isEmpty && (!actual.hasChildren || !expected.hasChildren)) {
|
|
properties.last = properties.first
|
|
properties.first = {actual: api.lineBuilder.buffer(), expected: api.lineBuilder.buffer()}
|
|
}
|
|
|
|
const result = api.lineBuilder.buffer()
|
|
|
|
// Create a custom diff that is as neat as possible. It's likely
|
|
// there's a generic algorithm that can be used, but for expediency's
|
|
// sake handles all possible diffs by brute force instead.
|
|
if (actual.hasProperties && expected.hasProperties) {
|
|
if (namesAreEqual) {
|
|
result
|
|
.append(api.lineBuilder.first(openTag.start + actualName))
|
|
.append(properties.first.actual.stripFlags())
|
|
.append(properties.first.expected.stripFlags())
|
|
} else {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName))
|
|
.append(properties.first.actual.stripFlags())
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName))
|
|
.append(properties.first.expected.stripFlags())
|
|
}
|
|
result.append(properties.remaining.stripFlags())
|
|
|
|
if (actual.hasChildren && expected.hasChildren) {
|
|
result
|
|
.append(properties.last.actual.stripFlags())
|
|
.append(properties.last.expected.stripFlags())
|
|
.append(api.lineBuilder.line(indent + openTag.end))
|
|
|
|
if (namesAreEqual) {
|
|
result
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
} else {
|
|
result
|
|
.append(children.first.actual.stripFlags())
|
|
.append(children.first.expected.stripFlags())
|
|
.append(children.remaining.stripFlags())
|
|
.append(children.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
}
|
|
} else if (actual.hasChildren) {
|
|
result
|
|
.append(properties.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.line(indent + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(properties.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + openTag.selfClose + openTag.end))
|
|
} else if (expected.hasChildren) {
|
|
result
|
|
.append(properties.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + openTag.selfClose + openTag.end))
|
|
.append(properties.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.line(indent + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
} else {
|
|
result
|
|
.append(properties.last.actual.stripFlags())
|
|
.append(properties.last.expected.stripFlags())
|
|
.append(api.lineBuilder.last(indent + openTag.selfClose + openTag.end))
|
|
}
|
|
} else if (actual.hasProperties) {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName))
|
|
.append(allProperties.stripFlags())
|
|
|
|
if (actual.hasChildren && expected.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.line(indent + openTag.end))
|
|
.append(children.first.actual.stripFlags())
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName + openTag.end))
|
|
.append(children.first.expected.stripFlags())
|
|
.append(children.remaining.stripFlags())
|
|
|
|
if (namesAreEqual) {
|
|
result
|
|
.append(children.last.actual.stripFlags())
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
} else {
|
|
result
|
|
.append(children.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
}
|
|
} else if (actual.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.last(indent + openTag.selfClose + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(api.lineBuilder.expected.single(openTag.start + expectedName + openTag.selfCloseVoid + openTag.end))
|
|
} else if (expected.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.last(indent + openTag.selfClose + openTag.end))
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
} else {
|
|
result
|
|
.append(api.lineBuilder.actual.last(indent + openTag.selfClose + openTag.end))
|
|
.append(api.lineBuilder.expected.single(openTag.start + expectedName + openTag.selfCloseVoid + openTag.end))
|
|
}
|
|
} else if (expected.hasProperties) {
|
|
if (actual.hasChildren && expected.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName + openTag.end))
|
|
.append(children.first.actual.stripFlags())
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName))
|
|
.append(allProperties.stripFlags())
|
|
.append(api.lineBuilder.expected.line(indent + openTag.end))
|
|
.append(children.first.expected.stripFlags())
|
|
.append(children.remaining.stripFlags())
|
|
|
|
if (namesAreEqual) {
|
|
result
|
|
.append(children.last.actual.stripFlags())
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
} else {
|
|
result
|
|
.append(children.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
}
|
|
} else if (actual.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName))
|
|
.append(allProperties.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + openTag.selfClose + openTag.end))
|
|
} else if (expected.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.single(openTag.start + actualName + openTag.selfCloseVoid + openTag.end))
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName))
|
|
.append(allProperties.stripFlags())
|
|
.append(api.lineBuilder.expected.line(indent + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
} else {
|
|
result
|
|
.append(api.lineBuilder.actual.single(openTag.start + actualName + openTag.selfCloseVoid + openTag.end))
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName))
|
|
.append(allProperties.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + openTag.selfCloseVoid + openTag.end))
|
|
}
|
|
} else {
|
|
if (actual.hasChildren && expected.hasChildren) {
|
|
if (namesAreEqual) {
|
|
result
|
|
.append(api.lineBuilder.first(openTag.start + actualName + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
} else {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName + openTag.end))
|
|
.append(children.first.actual.stripFlags())
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName + openTag.end))
|
|
.append(children.first.expected.stripFlags())
|
|
.append(children.remaining.stripFlags())
|
|
.append(children.last.actual.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(children.last.expected.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, expectedName)))
|
|
}
|
|
} else if (actual.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.first(openTag.start + actualName + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.actual.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
.append(api.lineBuilder.expected.single(openTag.start + expectedName + openTag.selfCloseVoid + openTag.end))
|
|
} else if (expected.hasChildren) {
|
|
result
|
|
.append(api.lineBuilder.actual.single(openTag.start + actualName + openTag.selfCloseVoid + openTag.end))
|
|
.append(api.lineBuilder.expected.first(openTag.start + expectedName + openTag.end))
|
|
.append(allChildren.stripFlags())
|
|
.append(api.lineBuilder.expected.last(indent + api.wrapFromTheme(theme.react.closeTag, actualName)))
|
|
} else {
|
|
if (namesAreEqual) {
|
|
result.append(api.lineBuilder.single(openTag.start + actualName + openTag.selfCloseVoid + openTag.end))
|
|
} else {
|
|
result
|
|
.append(api.lineBuilder.actual.single(openTag.start + actualName + openTag.selfCloseVoid + openTag.end))
|
|
.append(api.lineBuilder.expected.single(openTag.start + expectedName + openTag.selfCloseVoid + openTag.end))
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
},
|
|
|
|
shouldFormat (subject) {
|
|
return subject.isItem === true || subject.isProperty === true
|
|
},
|
|
|
|
increaseIndent: true
|
|
}
|
|
}
|
|
module.exports = diffShallow
|