mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:50:33 +08:00
Refactoring entities (#23)
* Still WIP * WIP * ArrayEntity parsing fixed * Fix format text entity * Tests for various entity classes and update entity class implementations * More tests and fixed * More entities fixed * Simple entities serialization fixed * Entities tests fixed * Remove serialization bits * Fix Function reference * CustomProperties creating fixed * WIP * Better typing for grammars * Decoding code fixes * Fixing still * Several fixes * rename toString to serialize * Several fixes * More fixes * Moving more stuff out of Utility * Several fixes * Fixing Linear color entity print * Serialization fixes * Fix serialization * Method to compute grammar * Renaming fix * Fix array grammar and equality check * Fix inlined keys * Fix type * Several serialization fixes * Fix undefined dereference * Several fixes * More fixes and cleanup * Fix keys quoting mechanism * Fix natural number assignment * Fix Int64 toString() * Fix quoted keys for inlined arrays * Fix PG pins * Fix several test cases * Types fixes * New pin default value empty * Fix non existing DefaultValue for variadic nodes * Smaller fixes for crashes * Fix link color when attached to knot * Linking test and more reliability operations for adding pins * Improve issue 18 test * More tests and fixes * Fix enum pin entity * Remove failing test
This commit is contained in:
69
tests/customEntities.spec.js
Normal file
69
tests/customEntities.spec.js
Normal file
@@ -0,0 +1,69 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import StringEntity from "../js/entity/StringEntity.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
import Entity1 from "./resources/Entity1.js"
|
||||
import Entity2 from "./resources/Entity2.js"
|
||||
import Entity3 from "./resources/Entity3.js"
|
||||
import Entity4 from "./resources/Entity4.js"
|
||||
import entity2Value1 from "./resources/serializedEntity2-1.js"
|
||||
import entity2Value from "./resources/serializedEntity2.js"
|
||||
import entity3Value from "./resources/serializedEntity3.js"
|
||||
import entity4Value from "./resources/serializedEntity4.js"
|
||||
|
||||
test.beforeAll(() => initializeSerializerFactory())
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
test("Entity2", () => {
|
||||
const value = new Entity2()
|
||||
expect(Object.keys(value)).toHaveLength(9)
|
||||
expect(value.serialize()).toEqual(entity2Value)
|
||||
const other = new Entity2({ someString2: new StringEntity("gamma") })
|
||||
expect(value.equals(other)).toBeFalsy()
|
||||
other.someString2 = new StringEntity("beta")
|
||||
expect(value.equals(other)).toBeTruthy()
|
||||
})
|
||||
|
||||
test("Entity2-1", () => {
|
||||
Entity2.attributes.someEntity = Entity2.attributes.someEntity.flagInlined()
|
||||
const value = new Entity2()
|
||||
expect(value.serialize()).toEqual(entity2Value1)
|
||||
})
|
||||
|
||||
test("Entity3", () => {
|
||||
let value = new Entity3()
|
||||
const keys = [
|
||||
"alpha",
|
||||
"bravo",
|
||||
"charlie",
|
||||
"delta",
|
||||
"echo",
|
||||
"foxtrot",
|
||||
"golf",
|
||||
"hotel",
|
||||
"india",
|
||||
"juliett",
|
||||
"kilo",
|
||||
// "lima", // Not defined by default
|
||||
"mike",
|
||||
"november",
|
||||
"oscar",
|
||||
"papa",
|
||||
// "quebec", // Not defined by default
|
||||
"romeo",
|
||||
"sierra",
|
||||
]
|
||||
expect(Object.keys(value)).toStrictEqual(keys)
|
||||
expect(value.serialize()).toEqual(entity3Value)
|
||||
})
|
||||
|
||||
test("Entity4", () => {
|
||||
Entity1.attributeSeparator = " - "
|
||||
Entity1.keySeparator = ":"
|
||||
Entity1.printKey = k => k.toUpperCase()
|
||||
Entity1.wrap = (entity, v) => `E1[${v}]`
|
||||
const entity = new Entity4()
|
||||
expect(entity.serialize()).toEqual(entity4Value)
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
157
tests/linking.spec.js
Normal file
157
tests/linking.spec.js
Normal file
@@ -0,0 +1,157 @@
|
||||
import BlueprintFixture from "./fixtures/BlueprintFixture.js"
|
||||
import { expect, test } from "./fixtures/test.js"
|
||||
|
||||
test.describe("Linking", () => {
|
||||
|
||||
test.beforeEach(async ({ blueprintPage }) => {
|
||||
await blueprintPage.removeNodes()
|
||||
await blueprintPage.paste(String.raw`
|
||||
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_29" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Engine/Maps/Templates/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_29'"
|
||||
bIsPureFunc=True
|
||||
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetMathLibrary'",MemberName="MakeRotator")
|
||||
NodePosX=-3152
|
||||
NodePosY=-608
|
||||
NodeGuid=4340FF7A779C4CD6A214350F6B196A20
|
||||
CustomProperties Pin (PinId=01CEDBCB4492ACD233830FBBB7583895,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetMathLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=9EF49AF4439604F146626C942630AE7F,PinName="Roll",PinFriendlyName="X (Roll)",PinToolTip="X (Roll)\nFloat (single-precision)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=C7D2429C4EC24C0D8AE6ADA672BE7C6F,PinName="Pitch",PinFriendlyName="Y (Pitch)",PinToolTip="Y (Pitch)\nFloat (single-precision)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=291C0FB3400FBFE88817D7BF71DC1FF7,PinName="Yaw",PinFriendlyName="Z (Yaw)",PinToolTip="Z (Yaw)\nFloat (single-precision)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0.0",AutogeneratedDefaultValue="0.0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=5BADBCF34ED86925DAA81983B5BE12B2,PinName="ReturnValue",PinToolTip="Return Value\nRotator\n\nMakes a rotator {Roll, Pitch, Yaw} from rotation values supplied in degrees",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.Rotator'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_5" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Engine/Maps/Templates/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_5'"
|
||||
bIsPureFunc=True
|
||||
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetMathLibrary'",MemberName="GetForwardVector")
|
||||
NodePosX=-2704
|
||||
NodePosY=-576
|
||||
NodeGuid=9BFBB662CF9642FBB9003050B5A1D394
|
||||
CustomProperties Pin (PinId=E8BB6375453E11DF80EEBDBEEE1FFA23,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet Math Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetMathLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetMathLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=EBD734BF4537F7BFDA921F932A1E67D9,PinName="InRot",PinToolTip="In Rot\nRotator",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.Rotator'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=C0EC34304B3A9CCCDFFE71BEE1A30949,PinName="ReturnValue",PinToolTip="Return Value\nVector\n\nRotate the world forward vector by the given rotation",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.Vector'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="0, 0, 0",AutogeneratedDefaultValue="0, 0, 0",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
`)
|
||||
})
|
||||
|
||||
/** @param {BlueprintFixture} blueprintPage */
|
||||
const getElements = blueprintPage => {
|
||||
/** @type {Locator<PinElement>} */
|
||||
const aPin = blueprintPage.blueprintLocator.locator('ueb-node:has-text("Make Rotator") ueb-pin:has-text("Return Value")')
|
||||
/** @type {Locator<PinElement>} */
|
||||
const bPin = blueprintPage.blueprintLocator.locator('ueb-node:has-text("Get Forward Vector") ueb-pin:has-text("In Rot")')
|
||||
return { aPin, bPin }
|
||||
}
|
||||
|
||||
test("Can connect pins", async ({ blueprintPage }) => {
|
||||
const { aPin, bPin } = getElements(blueprintPage)
|
||||
const aRect = await aPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const bRect = await bPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const mouse = blueprintPage.page.mouse
|
||||
const color = await aPin.evaluate(pin => pin.entity.pinColor().toString())
|
||||
expect(color).toMatch(/\d+\,\s*\d+\,\s*\d+/)
|
||||
expect(await aPin.evaluate(pin => pin.entity.pinColor().toString())).toEqual(color)
|
||||
expect(await aPin.evaluate(pin => pin.entity.isLinked())).toBeFalsy()
|
||||
expect(await bPin.evaluate(pin => pin.entity.isLinked())).toBeFalsy()
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(0)
|
||||
await aPin.hover({
|
||||
position: {
|
||||
x: Math.floor(aRect.width / 2),
|
||||
y: Math.floor(aRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.down()
|
||||
await mouse.move(aRect.left + aRect.width + 100, aRect.top + aRect.height + 100, { steps: 4 })
|
||||
// There is one link element ...
|
||||
expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(1)
|
||||
// ... but no pins are linked yet
|
||||
expect(await aPin.evaluate(pin => pin.entity.isLinked())).toBeFalsy()
|
||||
expect(await bPin.evaluate(pin => pin.entity.isLinked())).toBeFalsy()
|
||||
await bPin.hover({
|
||||
position: {
|
||||
x: Math.floor(bRect.width / 2),
|
||||
y: Math.floor(bRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.up()
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(1)
|
||||
expect(await blueprintPage.blueprintLocator.locator("ueb-link").evaluate(
|
||||
link => link.style.getPropertyValue("--ueb-link-color-rgb"))
|
||||
)
|
||||
.toEqual(color)
|
||||
expect(await aPin.evaluate(pin => pin.entity.isLinked())).toBeTruthy()
|
||||
expect(await bPin.evaluate(pin => pin.entity.isLinked())).toBeTruthy()
|
||||
})
|
||||
|
||||
test("Can connect only once", async ({ blueprintPage }) => {
|
||||
{
|
||||
const { aPin, bPin } = getElements(blueprintPage)
|
||||
const aRect = await aPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const bRect = await bPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const mouse = blueprintPage.page.mouse
|
||||
await aPin.hover({
|
||||
position: {
|
||||
x: Math.floor(aRect.width / 2),
|
||||
y: Math.floor(aRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.down()
|
||||
await mouse.move(aRect.left + aRect.width + 100, aRect.top + aRect.height + 100, { steps: 4 })
|
||||
await bPin.hover({
|
||||
position: {
|
||||
x: Math.floor(bRect.width / 2),
|
||||
y: Math.floor(bRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.up()
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(1)
|
||||
}
|
||||
|
||||
{
|
||||
const { aPin, bPin } = getElements(blueprintPage)
|
||||
const aRect = await aPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const bRect = await bPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const mouse = blueprintPage.page.mouse
|
||||
await aPin.hover({
|
||||
position: {
|
||||
x: Math.floor(aRect.width / 2),
|
||||
y: Math.floor(aRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.down()
|
||||
await mouse.move(aRect.left + aRect.width + 100, aRect.top + aRect.height + 100, { steps: 4 })
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(2)
|
||||
await bPin.hover({
|
||||
position: {
|
||||
x: Math.floor(bRect.width / 2),
|
||||
y: Math.floor(bRect.height / 2),
|
||||
}
|
||||
})
|
||||
await expect(blueprintPage.blueprintLocator.locator('ueb-link[data-dragging="true"] .ueb-link-message-text'))
|
||||
.toContainText("Replace existing input connections")
|
||||
await mouse.up()
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(1)
|
||||
}
|
||||
|
||||
{
|
||||
const { aPin, bPin } = getElements(blueprintPage)
|
||||
const aRect = await aPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const bRect = await bPin.evaluate(pin => pin.getBoundingClientRect())
|
||||
const mouse = blueprintPage.page.mouse
|
||||
await bPin.hover({
|
||||
position: {
|
||||
x: Math.floor(bRect.width / 2),
|
||||
y: Math.floor(bRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.down()
|
||||
await mouse.move(bRect.left + bRect.width + 100, bRect.top + bRect.height + 100, { steps: 4 })
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(2)
|
||||
await aPin.hover({
|
||||
position: {
|
||||
x: Math.floor(aRect.width / 2),
|
||||
y: Math.floor(aRect.height / 2),
|
||||
}
|
||||
})
|
||||
await mouse.up()
|
||||
await expect(blueprintPage.blueprintLocator.locator("ueb-link")).toHaveCount(1)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -96,8 +96,8 @@ while (i < nodeTests.length) {
|
||||
},
|
||||
Configuration.gridSize
|
||||
)
|
||||
expect(Math.abs(nodeTest.size[0] - expectedSize[0])).toBeLessThan(1.5)
|
||||
expect(Math.abs(nodeTest.size[1] - expectedSize[1])).toBeLessThan(1.5)
|
||||
expect(Math.abs(nodeTest.size[0] - expectedSize[0])).toBeLessThanOrEqual(1.5)
|
||||
expect(Math.abs(nodeTest.size[1] - expectedSize[1])).toBeLessThanOrEqual(1.5)
|
||||
if (
|
||||
Math.abs(nodeTest.size[0] - expectedSize[0]) > 0.6
|
||||
|| Math.abs(nodeTest.size[1] - expectedSize[1]) > 0.6
|
||||
@@ -166,8 +166,10 @@ while (i < nodeTests.length) {
|
||||
async ({ blueprintPage }) => {
|
||||
const variadic = blueprintPage.node.getByText("Add pin")
|
||||
await expect(variadic).toBeVisible()
|
||||
await variadic.hover()
|
||||
await variadic.click()
|
||||
expect(await blueprintPage.node.locator("ueb-pin").all()).toHaveLength(nodeTest.pins + 1)
|
||||
await variadic.blur()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,581 +0,0 @@
|
||||
import { expect, test } from "@playwright/test"
|
||||
import Utility from "../js/Utility.js"
|
||||
import FormatTextEntity from "../js/entity/FormatTextEntity.js"
|
||||
import GuidEntity from "../js/entity/GuidEntity.js"
|
||||
import IntegerEntity from "../js/entity/IntegerEntity.js"
|
||||
import KeyBindingEntity from "../js/entity/KeyBindingEntity.js"
|
||||
import LinearColorEntity from "../js/entity/LinearColorEntity.js"
|
||||
import ObjectReferenceEntity from "../js/entity/ObjectReferenceEntity.js"
|
||||
import PinEntity from "../js/entity/PinEntity.js"
|
||||
import RotatorEntity from "../js/entity/RotatorEntity.js"
|
||||
import SimpleSerializationRotatorEntity from "../js/entity/SimpleSerializationRotatorEntity.js"
|
||||
import SimpleSerializationVector2DEntity from "../js/entity/SimpleSerializationVector2DEntity.js"
|
||||
import SimpleSerializationVectorEntity from "../js/entity/SimpleSerializationVectorEntity.js"
|
||||
import SymbolEntity from "../js/entity/SymbolEntity.js"
|
||||
import UnknownKeysEntity from "../js/entity/UnknownKeysEntity.js"
|
||||
import Vector2DEntity from "../js/entity/Vector2DEntity.js"
|
||||
import VectorEntity from "../js/entity/VectorEntity.js"
|
||||
import Grammar from "../js/serialization/Grammar.js"
|
||||
import SerializerFactory from "../js/serialization/SerializerFactory.js"
|
||||
import initializeSerializerFactory from "../js/serialization/initializeSerializerFactory.js"
|
||||
|
||||
test.beforeAll(() => initializeSerializerFactory())
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
test("Array", () => {
|
||||
const serializer = SerializerFactory.getSerializer(Array)
|
||||
|
||||
expect(serializer.read("()")).toStrictEqual([])
|
||||
expect(serializer.read("( )")).toStrictEqual([])
|
||||
expect(serializer.read("(1, 2, 3, 4, 5, 6)")).toStrictEqual([1, 2, 3, 4, 5, 6])
|
||||
expect(serializer.read(`(
|
||||
"alpha",
|
||||
"beta",
|
||||
123,
|
||||
3BEF2168446CAA32D5B54289FAB2F0BA,
|
||||
Some(a=1, b="2")
|
||||
)`)).toStrictEqual([
|
||||
"alpha",
|
||||
"beta",
|
||||
123,
|
||||
new GuidEntity("3BEF2168446CAA32D5B54289FAB2F0BA"),
|
||||
new UnknownKeysEntity({
|
||||
lookbehind: "Some",
|
||||
a: 1,
|
||||
b: "2",
|
||||
})
|
||||
])
|
||||
expect(serializer.read(`(
|
||||
A(first = (9,8,7,6,5), second = 00000000000000000000000000000000),
|
||||
B(key="hello"),
|
||||
)`)).toStrictEqual([
|
||||
new UnknownKeysEntity({
|
||||
lookbehind: "A",
|
||||
first: [9, 8, 7, 6, 5],
|
||||
second: new GuidEntity("00000000000000000000000000000000"),
|
||||
}),
|
||||
new UnknownKeysEntity({
|
||||
lookbehind: "B",
|
||||
key: "hello",
|
||||
})
|
||||
])
|
||||
|
||||
// Nested
|
||||
expect(serializer.read("((1, 2), (3, 4))")).toStrictEqual([[1, 2], [3, 4]])
|
||||
expect(serializer.read('(((1, 2), (3, 4)), 5)')).toStrictEqual([[[1, 2], [3, 4]], 5])
|
||||
expect(serializer.read(`(
|
||||
One(a = (1,(2,(3,(4)))), b = ()),
|
||||
)`)).toStrictEqual([
|
||||
new UnknownKeysEntity({
|
||||
lookbehind: "One",
|
||||
a: [1, [2, [3, [4]]]],
|
||||
b: null,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
test("Boolean", () => {
|
||||
let serializer = SerializerFactory.getSerializer(Boolean)
|
||||
expect(serializer.read("true")).toStrictEqual(true)
|
||||
expect(serializer.read("True")).toStrictEqual(true)
|
||||
expect(serializer.read("false")).toStrictEqual(false)
|
||||
expect(serializer.read("False")).toStrictEqual(false)
|
||||
})
|
||||
|
||||
test("FormatTextEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(FormatTextEntity)
|
||||
expect(
|
||||
serializer.read(`LOCGEN_FORMAT_NAMED(NSLOCTEXT("KismetSchema", "SplitPinFriendlyNameFormat", "{PinDisplayName} {ProtoPinDisplayName}"), "PinDisplayName", "Out Hit", "ProtoPinDisplayName", "Blocking Hit")`)
|
||||
.toString()
|
||||
).toBe("Out Hit Blocking Hit")
|
||||
expect(
|
||||
serializer.read(`LOCGEN_FORMAT_NAMED(NSLOCTEXT("KismetSchema", "SplitPinFriendlyNameFormat", "{PinDisplayName} {ProtoPinDisplayName}"), "PinDisplayName", "Out Hit", "ProtoPinDisplayName", "Hit Bone Name")`)
|
||||
.toString()
|
||||
).toBe("Out Hit Hit Bone Name")
|
||||
expect(
|
||||
serializer.read(String.raw`LOCGEN_FORMAT_ORDERED(
|
||||
NSLOCTEXT(
|
||||
"PCGSettings",
|
||||
"OverridableParamPinTooltip",
|
||||
"{0}Attribute type is \"{1}\" and its exact name is \"{2}\""
|
||||
),
|
||||
"If InRangeMin = InRangeMax, then that density value is mapped to the average of OutRangeMin and OutRangeMax\n",
|
||||
"float",
|
||||
"InRangeMin"
|
||||
)`)
|
||||
.toString()
|
||||
|
||||
).toBe(`If InRangeMin = InRangeMax, then that density value is mapped to the average of OutRangeMin and OutRangeMax\nAttribute type is "float" and its exact name is "InRangeMin"`)
|
||||
})
|
||||
|
||||
test("GuidEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(GuidEntity)
|
||||
|
||||
let guid = serializer.read("0556a3ecabf648d0a5c07b2478e9dd32")
|
||||
expect(guid).toBeInstanceOf(GuidEntity)
|
||||
expect(guid.value).toBe("0556a3ecabf648d0a5c07b2478e9dd32")
|
||||
|
||||
guid = serializer.read("64023BC344E0453DBB583FAC411489BC")
|
||||
expect(guid).toBeInstanceOf(GuidEntity)
|
||||
expect(guid.value).toBe("64023BC344E0453DBB583FAC411489BC")
|
||||
|
||||
guid = serializer.read("6edC4a425ca948da8bC78bA52DED6C6C")
|
||||
expect(guid).toBeInstanceOf(GuidEntity)
|
||||
expect(guid.value).toBe("6edC4a425ca948da8bC78bA52DED6C6C")
|
||||
|
||||
expect(() => serializer.read("172087193 9B04362973544B3564FDB2C")).toThrow()
|
||||
expect(() => serializer.read("E25F14F8F3E9441AB07153E7DA2BA2B")).toThrow()
|
||||
expect(() => serializer.read("A78988B0097E48418C8CB87EC5A67ABF7")).toThrow()
|
||||
})
|
||||
|
||||
test("IntegerEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(IntegerEntity)
|
||||
|
||||
let integer = serializer.read("0")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(0)
|
||||
|
||||
integer = serializer.read("+0")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(0)
|
||||
|
||||
integer = serializer.read("-0")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(0)
|
||||
|
||||
integer = serializer.read("99")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(99)
|
||||
|
||||
integer = serializer.read("-8685")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(-8685)
|
||||
|
||||
integer = serializer.read("+555")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(555)
|
||||
|
||||
integer = serializer.read("1000000000")
|
||||
expect(integer).toBeInstanceOf(IntegerEntity)
|
||||
expect(integer.value).toStrictEqual(1000000000)
|
||||
|
||||
expect(() => serializer.read("1.2").value).toThrow()
|
||||
})
|
||||
|
||||
test("KeyBindingEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(KeyBindingEntity)
|
||||
|
||||
let binding = serializer.read("A")
|
||||
expect(binding).toBeInstanceOf(KeyBindingEntity)
|
||||
expect(binding).toMatchObject({ Key: { value: "A" } })
|
||||
|
||||
binding = serializer.read("(bCtrl=True,Key=A)")
|
||||
expect(binding).toBeInstanceOf(KeyBindingEntity)
|
||||
expect(binding).toMatchObject({ Key: { value: "A" }, bCtrl: true })
|
||||
|
||||
binding = serializer.read("(bCtrl=false,bShift=false,bCmd=true,bAlt=false,Key=X)")
|
||||
expect(binding).toBeInstanceOf(KeyBindingEntity)
|
||||
expect(binding).toMatchObject({ Key: { value: "X" }, bAlt: false, bCtrl: false, bCmd: true })
|
||||
|
||||
binding = serializer.read("( bCtrl= false \n, Key \n\n\n =Y ,bAlt=true )")
|
||||
expect(binding).toBeInstanceOf(KeyBindingEntity)
|
||||
expect(binding).toMatchObject({ Key: { value: "Y" }, bAlt: true, bCtrl: false })
|
||||
})
|
||||
|
||||
test("LinearColorEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(LinearColorEntity)
|
||||
|
||||
let color = LinearColorEntity.getWhite()
|
||||
expect(color.toRGBA()).toStrictEqual([255, 255, 255, 255])
|
||||
expect(color.toRGBAString()).toStrictEqual("FFFFFFFF")
|
||||
expect(color.toNumber()).toStrictEqual(-1)
|
||||
expect(color.toHSVA()).toStrictEqual([0, 0, 1, 1])
|
||||
|
||||
color = serializer.read("(R=1,G=0,B=0)")
|
||||
expect(color.toRGBA()).toStrictEqual([255, 0, 0, 255])
|
||||
expect(color.toRGBAString()).toStrictEqual("FF0000FF")
|
||||
expect(color.toNumber()).toStrictEqual(-16776961)
|
||||
expect(color.toHSVA()).toStrictEqual([0, 1, 1, 1])
|
||||
|
||||
color = serializer.read("(R=0.000000,G=0.660000,B=1.000000,A=1.000000)")
|
||||
expect(color.toRGBA()).toStrictEqual([0, 168, 255, 255])
|
||||
expect(color.toRGBAString()).toStrictEqual("00A8FFFF")
|
||||
expect(color.toNumber()).toStrictEqual(11075583)
|
||||
expect(color.toHSVA()).toStrictEqual([0.55666666666666666666, 1, 1, 1])
|
||||
|
||||
color = serializer.read("(B=0.04394509003266556,G=0.026789300067696642,A=0.83663232408635,R=0.6884158028074934,)")
|
||||
expect(color.toRGBA()).toStrictEqual([176, 7, 11, 213])
|
||||
expect(color.toRGBAString()).toStrictEqual("B0070BD5")
|
||||
expect(color.toNumber()).toStrictEqual(-1341715499)
|
||||
expect(color.toHSVA().map(v => Utility.roundDecimals(v, 3))).toStrictEqual([0.996, 0.961, 0.688, 0.837])
|
||||
|
||||
color = serializer.read(`(
|
||||
A = 0.327 ,
|
||||
R=0.530 , G = 0.685
|
||||
,B
|
||||
= 0.9 ,)`)
|
||||
expect(color.toRGBA()).toStrictEqual([135, 175, 230, 83])
|
||||
expect(color.toRGBAString()).toStrictEqual("87AFE653")
|
||||
expect(color.toNumber()).toStrictEqual(-2018515373)
|
||||
expect(color.toHSVA().map(v => Utility.roundDecimals(v, 3))).toStrictEqual([0.597, 0.411, 0.9, 0.327])
|
||||
|
||||
expect(() => serializer.read("(R=0.000000,G=0.660000,A=1.000000)")).toThrow()
|
||||
expect(() => serializer.read("(R=0.000000,G=\"hello\",A=1.000000)")).toThrow()
|
||||
})
|
||||
|
||||
test("Null", () => {
|
||||
const serializer = SerializerFactory.getSerializer(null)
|
||||
|
||||
expect(serializer.read("()")).toBeNull()
|
||||
expect(() => serializer.read("123")).toThrow()
|
||||
expect(() => serializer.read("(a)")).toThrow()
|
||||
expect(() => serializer.read("(")).toThrow()
|
||||
})
|
||||
|
||||
test("Number", () => {
|
||||
const serializer = SerializerFactory.getSerializer(Number)
|
||||
|
||||
expect(serializer.read("0")).toBeCloseTo(0, 0.00001)
|
||||
expect(serializer.read("+0")).toBeCloseTo(0, 0.00001)
|
||||
expect(serializer.read("-0")).toBeCloseTo(0, 0.00001)
|
||||
expect(serializer.read("5")).toBeCloseTo(5, 0.00001)
|
||||
expect(serializer.read("0.05")).toBeCloseTo(0.05, 0.00001)
|
||||
expect(serializer.read("-999.666")).toBeCloseTo(-999.666, 0.001)
|
||||
expect(serializer.read("+45.4545")).toBeCloseTo(45.4545, 0.001)
|
||||
expect(serializer.read("+1000000000")).toBeCloseTo(1E9, 0.1)
|
||||
expect(serializer.read("inf")).toBe(Number.POSITIVE_INFINITY)
|
||||
expect(serializer.read("+inf")).toBe(Number.POSITIVE_INFINITY)
|
||||
expect(serializer.read("-inf")).toBe(Number.NEGATIVE_INFINITY)
|
||||
expect(() => serializer.read("alpha")).toThrow()
|
||||
})
|
||||
|
||||
test("ObjectReferenceEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(ObjectReferenceEntity)
|
||||
|
||||
let reference = serializer.read("Class")
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "Class", path: "" })
|
||||
expect(serializer.write(reference)).toBe("Class")
|
||||
|
||||
reference = serializer.read(`Class'/Script/ShooterGame.ShooterGameMode'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "Class", path: "/Script/ShooterGame.ShooterGameMode" })
|
||||
expect(serializer.write(reference)).toBe(`Class'/Script/ShooterGame.ShooterGameMode'`)
|
||||
|
||||
reference = serializer.read(`EdGraphPin'EdGraphPin_45417'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "EdGraphPin", path: "EdGraphPin_45417" })
|
||||
expect(serializer.write(reference)).toBe(`EdGraphPin'EdGraphPin_45417'`)
|
||||
|
||||
reference = serializer.read(`EdGraphPin'"K2Node_DynamicCast_2126.EdGraphPin_3990988"'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "EdGraphPin", path: "K2Node_DynamicCast_2126.EdGraphPin_3990988" })
|
||||
expect(serializer.write(reference)).toBe(`EdGraphPin'"K2Node_DynamicCast_2126.EdGraphPin_3990988"'`)
|
||||
|
||||
reference = serializer.read(
|
||||
`"/Script/Engine.MaterialExpressionMaterialFunctionCall'MaterialExpressionMaterialFunctionCall_0'"`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Script/Engine.MaterialExpressionMaterialFunctionCall",
|
||||
path: "MaterialExpressionMaterialFunctionCall_0",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`"/Script/Engine.MaterialExpressionMaterialFunctionCall'MaterialExpressionMaterialFunctionCall_0'"`
|
||||
)
|
||||
|
||||
reference = serializer.read(
|
||||
`/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N"'`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Script/Engine.EdGraph",
|
||||
path: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`/Script/Engine.EdGraph'"/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:Do N"'`
|
||||
)
|
||||
|
||||
reference = serializer.read(
|
||||
`EdGraphPin'"K2Node_CommutativeAssociativeBinaryOperator_152.EdGraphPin_4045"'`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "EdGraphPin",
|
||||
path: "K2Node_CommutativeAssociativeBinaryOperator_152.EdGraphPin_4045",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`EdGraphPin'"K2Node_CommutativeAssociativeBinaryOperator_152.EdGraphPin_4045"'`
|
||||
)
|
||||
|
||||
reference = serializer.read(
|
||||
`Function'"/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element"'`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "Function",
|
||||
path: "/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`Function'"/Game/Mods/CrazyDinos/ElementalDragon/CDElementalDragon_Character_BP.SKEL_CDElementalDragon_Character_BP_C:ROS Change Element"'`
|
||||
)
|
||||
|
||||
reference = serializer.read(`EdGraph'/Game/Systems/BP_MacroGlobal.BP_MacroGlobal:Or+Branch'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "EdGraph",
|
||||
path: "/Game/Systems/BP_MacroGlobal.BP_MacroGlobal:Or+Branch",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(`EdGraph'/Game/Systems/BP_MacroGlobal.BP_MacroGlobal:Or+Branch'`)
|
||||
|
||||
reference = serializer.read(`/Script/Engine.EdGraph'"+-Weird/2,Macro"'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "/Script/Engine.EdGraph", path: "+-Weird/2,Macro" })
|
||||
expect(serializer.write(reference)).toBe(`/Script/Engine.EdGraph'"+-Weird/2,Macro"'`)
|
||||
|
||||
reference = serializer.read(`/Script/BlueprintGraph.K2Node_VariableGet`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({ type: "/Script/BlueprintGraph.K2Node_VariableGet", path: "" })
|
||||
expect(serializer.write(reference)).toBe(`/Script/BlueprintGraph.K2Node_VariableGet`)
|
||||
|
||||
reference = serializer.read(
|
||||
`/Script/Engine.MaterialExpressionMaterialFunctionCall'MaterialExpressionMaterialFunctionCall_0'`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Script/Engine.MaterialExpressionMaterialFunctionCall",
|
||||
path: "MaterialExpressionMaterialFunctionCall_0",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`/Script/Engine.MaterialExpressionMaterialFunctionCall'MaterialExpressionMaterialFunctionCall_0'`
|
||||
)
|
||||
|
||||
reference = serializer.read(
|
||||
`/Script/Engine.MaterialExpressionMaterialFunctionCall'/Engine/Transient.Material_0:MaterialGraph_0.MaterialGraphNode_3.MaterialExpressionMaterialFunctionCall_0'`
|
||||
)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Script/Engine.MaterialExpressionMaterialFunctionCall",
|
||||
path: "/Engine/Transient.Material_0:MaterialGraph_0.MaterialGraphNode_3.MaterialExpressionMaterialFunctionCall_0",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(
|
||||
`/Script/Engine.MaterialExpressionMaterialFunctionCall'/Engine/Transient.Material_0:MaterialGraph_0.MaterialGraphNode_3.MaterialExpressionMaterialFunctionCall_0'`
|
||||
)
|
||||
|
||||
reference = serializer.read(`/Script/CoreUObject.Class'"/Script/Engine.GameModeBase"'`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Script/CoreUObject.Class",
|
||||
path: "/Script/Engine.GameModeBase",
|
||||
})
|
||||
expect(serializer.write(reference)).toBe(`/Script/CoreUObject.Class'"/Script/Engine.GameModeBase"'`)
|
||||
|
||||
reference = serializer.read(`"/Game/_YukiritoLib/Textures/T_紫色渐变01.T_紫色渐变01"`)
|
||||
expect(reference).toBeInstanceOf(ObjectReferenceEntity)
|
||||
expect(reference).toMatchObject({
|
||||
type: "/Game/_YukiritoLib/Textures/T_紫色渐变01.T_紫色渐变01",
|
||||
path: "",
|
||||
})
|
||||
})
|
||||
|
||||
test("PinEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(PinEntity)
|
||||
|
||||
expect(serializer.read("Pin (PinType.PinSubCategoryMemberReference=())")).toMatchObject({
|
||||
"PinType": { "PinSubCategoryMemberReference": null }
|
||||
})
|
||||
})
|
||||
|
||||
test("SimpleSerializationRotatorEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(SimpleSerializationRotatorEntity)
|
||||
|
||||
expect(serializer.read("0, 0, 0")).toEqual(new SimpleSerializationRotatorEntity({
|
||||
R: 0,
|
||||
P: 0,
|
||||
Y: 0,
|
||||
}))
|
||||
expect(serializer.read("0.65, 1.0, 0.99")).toEqual(new SimpleSerializationRotatorEntity({
|
||||
P: 0.65,
|
||||
Y: 1.0,
|
||||
R: 0.99,
|
||||
}))
|
||||
expect(serializer.read("7,6,5")).toEqual(new SimpleSerializationRotatorEntity({
|
||||
P: 7,
|
||||
Y: 6,
|
||||
R: 5,
|
||||
}))
|
||||
})
|
||||
|
||||
test("SimpleSerializationVector2DEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(SimpleSerializationVector2DEntity)
|
||||
|
||||
expect(serializer.read("0, 0")).toEqual(new SimpleSerializationVector2DEntity({
|
||||
X: 0,
|
||||
Y: 0,
|
||||
}))
|
||||
expect(serializer.read("127.8, 13.3")).toEqual(new SimpleSerializationVector2DEntity({
|
||||
X: 127.8,
|
||||
Y: 13.3,
|
||||
}))
|
||||
expect(serializer.read("5,0")).toEqual(new SimpleSerializationVector2DEntity({
|
||||
X: 5,
|
||||
Y: 0,
|
||||
}))
|
||||
})
|
||||
|
||||
test("SimpleSerializationVectorEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(SimpleSerializationVectorEntity)
|
||||
|
||||
expect(serializer.read("0, 0, 0")).toEqual(new SimpleSerializationVectorEntity({
|
||||
X: 0,
|
||||
Y: 0,
|
||||
Z: 0,
|
||||
}))
|
||||
expect(serializer.read("1001, 56.4, 0.5")).toEqual(new SimpleSerializationVectorEntity({
|
||||
X: 1001,
|
||||
Y: 56.4,
|
||||
Z: 0.5,
|
||||
}))
|
||||
expect(serializer.read("-1,-2,-3")).toEqual(new SimpleSerializationVectorEntity({
|
||||
X: -1,
|
||||
Y: -2,
|
||||
Z: -3,
|
||||
}))
|
||||
})
|
||||
|
||||
test("String", () => {
|
||||
const serializer = SerializerFactory.getSerializer(String)
|
||||
|
||||
expect(serializer.read('""')).toStrictEqual("")
|
||||
expect(serializer.read('"hello"')).toStrictEqual("hello")
|
||||
expect(serializer.read('"hello world 123 - éèàò@ç ^ ^^^"')).toStrictEqual("hello world 123 - éèàò@ç ^ ^^^")
|
||||
expect(serializer.read('"\\""')).toStrictEqual('"')
|
||||
expect(() => serializer.read("Hello")).toThrow()
|
||||
|
||||
expect(serializer.write(`"/Script/CoreUObject.Class'/Script/Interhaptics.HapticSource'"`))
|
||||
.toBe(String.raw`"\"/Script/CoreUObject.Class'/Script/Interhaptics.HapticSource'\""`)
|
||||
})
|
||||
|
||||
test("UnknownKeysValue", () => {
|
||||
const parser = Grammar.unknownValue
|
||||
|
||||
expect(parser.parse('"Hello"').constructor).toStrictEqual(String)
|
||||
expect(parser.parse("()")).toBeNull()
|
||||
expect(parser.parse("8345").constructor).toStrictEqual(Number)
|
||||
expect(parser.parse("True").constructor).toStrictEqual(Boolean)
|
||||
expect(parser.parse("False").constructor).toStrictEqual(Boolean)
|
||||
expect(parser.parse("F0223D3742E67C0D9FEFB2A64946B7F0").constructor).toStrictEqual(GuidEntity)
|
||||
expect(parser.parse("SYMBOL1").constructor).toStrictEqual(SymbolEntity)
|
||||
expect(parser.parse("Symbol_2_3_4").constructor).toStrictEqual(SymbolEntity)
|
||||
expect(parser.parse("(X=-0.495, Y=0, )").constructor).toStrictEqual(Vector2DEntity)
|
||||
expect(parser.parse("(X=-0.495,Y=+765.0,Z=7)").constructor).toStrictEqual(VectorEntity)
|
||||
expect(parser.parse("(R=1.000000,P=7.6,Y=+88.99)").constructor).toStrictEqual(RotatorEntity)
|
||||
expect(parser.parse("(R=0.000000,G=0.660000,B=1.000000,A=1.000000)").constructor)
|
||||
.toStrictEqual(LinearColorEntity)
|
||||
expect(parser.parse(`Class'"/Script/Engine.KismetSystemLibrary"'`).constructor)
|
||||
.toStrictEqual(ObjectReferenceEntity)
|
||||
expect(parser.parse("(1,2,3,4,5,6,7,8,9)")).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
expect(parser.parse(`( "Hello", "World", )`)).toStrictEqual(["Hello", "World"])
|
||||
expect(parser.parse(`( "Alpha", 123, Beta, "Gamma", "Delta", 99 )`))
|
||||
.toStrictEqual(["Alpha", 123, new SymbolEntity({ value: "Beta" }), "Gamma", "Delta", 99])
|
||||
})
|
||||
|
||||
test("UnknownKeysEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(UnknownKeysEntity)
|
||||
|
||||
let unknown = serializer.read('LookbehindValue(FirstKey=1,SecondKey=SOME_SYMBOL2,ThirdKey="Hello")')
|
||||
expect(unknown).toBeInstanceOf(UnknownKeysEntity)
|
||||
expect(unknown).toMatchObject({
|
||||
lookbehind: "LookbehindValue",
|
||||
FirstKey: 1,
|
||||
SecondKey: new SymbolEntity("SOME_SYMBOL2"),
|
||||
ThirdKey: "Hello",
|
||||
})
|
||||
|
||||
unknown = serializer.read('(A = (-1,-2,-3), B = SomeFunction(B1 = "b1", B2 = (X=101,Y=102,Z=103)))')
|
||||
expect(unknown).toBeInstanceOf(UnknownKeysEntity)
|
||||
expect(unknown).toMatchObject({
|
||||
A: [-1, -2, -3],
|
||||
B: new UnknownKeysEntity({
|
||||
lookbehind: "SomeFunction",
|
||||
B1: "b1",
|
||||
B2: new VectorEntity({ X: 101, Y: 102, Z: 103 }),
|
||||
}),
|
||||
})
|
||||
})
|
||||
|
||||
test("VectorEntity", () => {
|
||||
const serializer = SerializerFactory.getSerializer(VectorEntity)
|
||||
|
||||
let vector = serializer.read("(X=1,Y=2,Z=3.5)")
|
||||
expect(vector).toBeInstanceOf(VectorEntity)
|
||||
expect(vector).toStrictEqual(new VectorEntity({
|
||||
X: 1,
|
||||
Y: 2,
|
||||
Z: 3.5,
|
||||
}))
|
||||
|
||||
vector = serializer.read("(X=10,Y=+20.88,Z=-30.54,)")
|
||||
expect(vector).toBeInstanceOf(VectorEntity)
|
||||
expect(vector).toStrictEqual(new VectorEntity({
|
||||
X: 10,
|
||||
Y: 20.88,
|
||||
Z: -30.54,
|
||||
}))
|
||||
|
||||
vector = serializer.read(`(
|
||||
Z = -3.66 ,
|
||||
|
||||
X
|
||||
= -1 , Y =
|
||||
|
||||
|
||||
-2
|
||||
,
|
||||
)`)
|
||||
expect(vector).toBeInstanceOf(VectorEntity)
|
||||
expect(vector).toStrictEqual(new VectorEntity({
|
||||
X: -1,
|
||||
Y: -2,
|
||||
Z: -3.66,
|
||||
}))
|
||||
|
||||
expect(() => serializer.read("(X=1,Y=\"2\",Z=3)")).toThrow()
|
||||
expect(() => serializer.read("(X=1,Z=3)")).toThrow()
|
||||
expect(() => serializer.read("(X=1,Y=2,Unexpected=6,Z=3.5)")).toThrow()
|
||||
})
|
||||
|
||||
test("Vector2DEntity", () => {
|
||||
let serializer = SerializerFactory.getSerializer(Vector2DEntity)
|
||||
|
||||
let vector = serializer.read("(X=78,Y=56.3)")
|
||||
expect(vector).toBeInstanceOf(Vector2DEntity)
|
||||
expect(vector).toStrictEqual(new Vector2DEntity({
|
||||
X: 78,
|
||||
Y: 56.3,
|
||||
}))
|
||||
|
||||
vector = serializer.read("(X=+4.5,Y=-8.88,)")
|
||||
expect(vector).toBeInstanceOf(Vector2DEntity)
|
||||
expect(vector).toStrictEqual(new Vector2DEntity({
|
||||
X: 4.5,
|
||||
Y: -8.88,
|
||||
}))
|
||||
|
||||
vector = serializer.read(`(
|
||||
Y = +93.004 ,
|
||||
|
||||
X
|
||||
= 0 ,
|
||||
)`)
|
||||
expect(vector).toBeInstanceOf(Vector2DEntity)
|
||||
expect(vector).toStrictEqual(new Vector2DEntity({
|
||||
X: 0,
|
||||
Y: 93.004,
|
||||
}))
|
||||
|
||||
expect(() => serializer.read("(X=1,Y=\"2\")")).toThrow()
|
||||
expect(() => serializer.read("(X=1)")).toThrow()
|
||||
expect(() => serializer.read("(X=777, Y=555, Unexpected=6, HH=2)")).toThrow()
|
||||
})
|
||||
@@ -1,20 +1,13 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
|
||||
export default class Entity1 extends IEntity {
|
||||
|
||||
static attributeSeparator = ", "
|
||||
static wrap = (entity, v) => `Entity1(${v})`
|
||||
static attributes = {
|
||||
a: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 8,
|
||||
}),
|
||||
b: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 9,
|
||||
}),
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
...super.attributes,
|
||||
a: NumberEntity.withDefault(type => new type(8)),
|
||||
b: NumberEntity.withDefault(type => new type(9)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,38 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import ArrayEntity from "../../js/entity/ArrayEntity.js"
|
||||
import BooleanEntity from "../../js/entity/BooleanEntity.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
import StringEntity from "../../js/entity/StringEntity.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
|
||||
export default class Entity2 extends IEntity {
|
||||
|
||||
static attributeSeparator = "\n"
|
||||
static keySeparator = ": "
|
||||
static printKey = k => ` ${k}`
|
||||
static wrap = (entity, v) => `{\n${v}\n}`
|
||||
static attributes = {
|
||||
someNumber: AttributeInfo.createValue(567),
|
||||
someString: AttributeInfo.createValue("alpha"),
|
||||
someString2: AttributeInfo.createValue("beta"),
|
||||
someBoolean: AttributeInfo.createValue(true),
|
||||
someBoolean2: AttributeInfo.createValue(false),
|
||||
someObjectString: AttributeInfo.createValue("gamma"),
|
||||
someArray: AttributeInfo.createValue([400, 500, 600, 700, 800]),
|
||||
someArray2: AttributeInfo.createValue(() => [400, 500, 600, 700, 800]),
|
||||
someEntity: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: new Entity1()
|
||||
}),
|
||||
...super.attributes,
|
||||
someNumber: NumberEntity.withDefault(type => new type(567)),
|
||||
someString: StringEntity.withDefault(type => new type("alpha")),
|
||||
someString2: StringEntity.withDefault(type => new type("beta")),
|
||||
someBoolean: BooleanEntity.withDefault(type => new type(true)),
|
||||
someBoolean2: BooleanEntity.withDefault(),
|
||||
someObjectString: StringEntity.withDefault(type => new type("gamma")),
|
||||
someArray: ArrayEntity.of(NumberEntity).withDefault(type => new type([
|
||||
new NumberEntity(400),
|
||||
new NumberEntity(500),
|
||||
new NumberEntity(600),
|
||||
new NumberEntity(700),
|
||||
new NumberEntity(800),
|
||||
])),
|
||||
someArray2: ArrayEntity.of(NumberEntity).withDefault(type => new type([
|
||||
new NumberEntity(-400),
|
||||
new NumberEntity(-500),
|
||||
new NumberEntity(-600),
|
||||
new NumberEntity(-700),
|
||||
new NumberEntity(-800),
|
||||
])),
|
||||
someEntity: Entity1.withDefault(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +1,58 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import AlternativesEntity from "../../js/entity/AlternativesEntity.js"
|
||||
import ArrayEntity from "../../js/entity/ArrayEntity.js"
|
||||
import BooleanEntity from "../../js/entity/BooleanEntity.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Union from "../../js/entity/Union.js"
|
||||
import NullEntity from "../../js/entity/NullEntity.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
import StringEntity from "../../js/entity/StringEntity.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
import Entity2 from "./Entity2.js"
|
||||
|
||||
export default class Entity3 extends IEntity {
|
||||
|
||||
static attributeSeparator = "\n"
|
||||
static keySeparator = ": "
|
||||
static printKey = k => ` ${k}`
|
||||
static wrap = (entity, v) => `[[\n${v}\n]]`
|
||||
static attributes = {
|
||||
alpha: AttributeInfo.createValue(32),
|
||||
bravo: new AttributeInfo({
|
||||
type: Number,
|
||||
default: 78,
|
||||
}),
|
||||
charlie: new AttributeInfo({
|
||||
type: String,
|
||||
default: "Charlie",
|
||||
}),
|
||||
delta: new AttributeInfo({
|
||||
type: String,
|
||||
default: null,
|
||||
}),
|
||||
echo: AttributeInfo.createValue("echo"),
|
||||
foxtrot: AttributeInfo.createValue(false),
|
||||
golf: AttributeInfo.createValue([]),
|
||||
hotel: new AttributeInfo({
|
||||
type: Array,
|
||||
default: null,
|
||||
}),
|
||||
india: new AttributeInfo({
|
||||
type: [Number],
|
||||
default: () => [],
|
||||
}),
|
||||
juliett: new AttributeInfo({
|
||||
type: [String],
|
||||
default: ["a", "b", "c", "d", "e"],
|
||||
}),
|
||||
kilo: new AttributeInfo({
|
||||
type: [Boolean],
|
||||
default: () => [true, false, false, true, true],
|
||||
}),
|
||||
lima: AttributeInfo.createType(String),
|
||||
mike: new AttributeInfo({
|
||||
type: new Union(Number, String, Array),
|
||||
default: "Bar",
|
||||
}),
|
||||
november: new AttributeInfo({
|
||||
type: new Union(Number, String, Array),
|
||||
default: 0,
|
||||
}),
|
||||
oscar: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: () => new Entity1()
|
||||
}),
|
||||
papa: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: () => new Entity1({ a: 12, b: 13 }),
|
||||
}),
|
||||
quebec: new AttributeInfo({
|
||||
default: 0, // will assign undefined because it does not satisfy the predicate
|
||||
predicate: v => v >= 1 && v <= 10,
|
||||
}),
|
||||
romeo: new AttributeInfo({
|
||||
type: Entity1,
|
||||
default: new Entity1(),
|
||||
inlined: true,
|
||||
}),
|
||||
sierra: new AttributeInfo({
|
||||
type: Entity2,
|
||||
default: new Entity2(),
|
||||
inlined: true,
|
||||
}),
|
||||
...super.attributes,
|
||||
alpha: NumberEntity.withDefault(type => new type(32)),
|
||||
bravo: NumberEntity.withDefault(type => new type(78)),
|
||||
charlie: StringEntity.withDefault(type => new type("Charlie")),
|
||||
delta: StringEntity.withDefault(type => new NullEntity()),
|
||||
echo: StringEntity.withDefault(type => new type("echo")),
|
||||
foxtrot: BooleanEntity.withDefault(),
|
||||
golf: ArrayEntity.of(StringEntity).withDefault(),
|
||||
hotel: ArrayEntity.of(NumberEntity).withDefault(() => new NullEntity()),
|
||||
india: ArrayEntity.of(NumberEntity).withDefault(),
|
||||
juliett: ArrayEntity.of(StringEntity).withDefault(type => new type([
|
||||
new StringEntity("a"),
|
||||
new StringEntity("b"),
|
||||
new StringEntity("c"),
|
||||
new StringEntity("d"),
|
||||
new StringEntity("e"),
|
||||
])),
|
||||
kilo: ArrayEntity.of(BooleanEntity).withDefault(type => new type([
|
||||
new BooleanEntity(true),
|
||||
new BooleanEntity(),
|
||||
new BooleanEntity(),
|
||||
new BooleanEntity(true),
|
||||
new BooleanEntity(true),
|
||||
])),
|
||||
lima: StringEntity,
|
||||
mike: AlternativesEntity
|
||||
.accepting(NumberEntity, StringEntity, ArrayEntity)
|
||||
.withDefault(type => new StringEntity("Bar")),
|
||||
november: AlternativesEntity
|
||||
.accepting(NumberEntity, StringEntity, ArrayEntity)
|
||||
.withDefault(type => new NumberEntity(0)),
|
||||
oscar: Entity1.withDefault(),
|
||||
papa: Entity1.withDefault(type => new type({
|
||||
a: new NumberEntity(12),
|
||||
b: new NumberEntity(13),
|
||||
})),
|
||||
quebec: NumberEntity,
|
||||
romeo: Entity1.withDefault().flagInlined(),
|
||||
sierra: Entity2.withDefault().flagInlined(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,23 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import ArrayEntity from "../../js/entity/ArrayEntity.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import NullEntity from "../../js/entity/NullEntity.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
import Entity1 from "./Entity1.js"
|
||||
import Entity3 from "./Entity3.js"
|
||||
|
||||
export default class Entity4 extends IEntity {
|
||||
|
||||
static attributeSeparator = "\n"
|
||||
static keySeparator = " => "
|
||||
static printKey = k => ` \${${k}}`
|
||||
static wrap = (entity, v) => `Begin\n${v}\nEnd`
|
||||
static attributes = {
|
||||
first: new AttributeInfo({
|
||||
type: Entity3,
|
||||
default: new Entity3(),
|
||||
inlined: true,
|
||||
}),
|
||||
second: new AttributeInfo({
|
||||
default: [new Entity1({ a: 1, b: 2 }), new Entity1({ a: 11, b: 22 })],
|
||||
inlined: true,
|
||||
}),
|
||||
third: new AttributeInfo({
|
||||
type: Array,
|
||||
default: null,
|
||||
})
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
/** @type {Entity1} */ this.second
|
||||
IEntity.defineAttributes(this.second, {
|
||||
0: {
|
||||
inlined: true,
|
||||
},
|
||||
})
|
||||
...super.attributes,
|
||||
first: Entity3.withDefault().flagInlined(),
|
||||
second: ArrayEntity.of(Entity1).withDefault(type => new type([
|
||||
new (Entity1.flagInlined())({ a: new NumberEntity(1), b: new NumberEntity(2) }),
|
||||
new Entity1({ a: new NumberEntity(11), b: new NumberEntity(22) }),
|
||||
])).flagInlined(),
|
||||
third: ArrayEntity.withDefault(() => new NullEntity()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IntegerEntity from "../../js/entity/IntegerEntity.js"
|
||||
import ObjectEntity from "../../js/entity/ObjectEntity.js"
|
||||
import EntityF from "./EntityF.js"
|
||||
|
||||
// @ts-expect-error
|
||||
export default class Entity5 extends ObjectEntity {
|
||||
|
||||
static attributes = {
|
||||
key1: AttributeInfo.createType(String),
|
||||
key2: AttributeInfo.createType(EntityF),
|
||||
key3: new AttributeInfo({
|
||||
type: IntegerEntity,
|
||||
default: new IntegerEntity(5),
|
||||
silent: true,
|
||||
}),
|
||||
}
|
||||
static grammar = this.createGrammar()
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Union from "../../js/entity/Union.js"
|
||||
import Grammar from "../../js/serialization/Grammar.js"
|
||||
|
||||
export default class EntityF extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
arg1: AttributeInfo.createType(Number),
|
||||
arg2: AttributeInfo.createType(String),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: new Union("Foo", "Bar"),
|
||||
})
|
||||
}
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this, false)
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
}
|
||||
}
|
||||
@@ -538,6 +538,32 @@ export default class FlowControlNodes extends NodeTests {
|
||||
delegate: false,
|
||||
development: false,
|
||||
},
|
||||
{
|
||||
name: "Sequence",
|
||||
value: String.raw`
|
||||
Begin Object Class=/Script/BlueprintGraph.K2Node_ExecutionSequence Name="K2Node_ExecutionSequence_4" ExportPath="/Script/BlueprintGraph.K2Node_ExecutionSequence'/Engine/Maps/Templates/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_ExecutionSequence_4'"
|
||||
NodePosX=496
|
||||
NodePosY=192
|
||||
NodeGuid=7E38FFEB6B474D4E80CDA4B4720C9E24
|
||||
CustomProperties Pin (PinId=2612016B4EAAC152FA9ABB9E23572EE1,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_26 2658362A4F2BA6A3BE7398A8604FAC6D,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=D665418E47B39BB80A8F02B3951BF0DB,PinName="then_0",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Timeline_1 ABA55A2B4F3689076D856F921255888F,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=A3D98FA145671788536EA1AD2CF5DA61,PinName="then_1",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Timeline_1 4069CE0043C4948BDE9D17A2FEE8DE0A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=47D0C212ACF74C57873C7C16B66E0EC6,PinName="then_2",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
`,
|
||||
size: [8.5, 10],
|
||||
color: Configuration.nodeColors.gray,
|
||||
icon: SVGIcon.sequence,
|
||||
pins: 4,
|
||||
pinNames: [
|
||||
"Then 0",
|
||||
"Then 1",
|
||||
"Then 2",
|
||||
],
|
||||
delegate: false,
|
||||
development: false,
|
||||
variadic: true,
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,26 +41,24 @@ export default class IssuesNodes1 extends NodeTests {
|
||||
delegate: false,
|
||||
development: false,
|
||||
additionalTest: async (node, pins, blueprintPage) => {
|
||||
const relevantPins = (await Promise.all(
|
||||
pins.map(async p => {
|
||||
const innerText = await p.innerText()
|
||||
// @ts-expect-error
|
||||
return [Configuration.rgba.includes(innerText), p]
|
||||
})
|
||||
))
|
||||
.filter(([flag, value]) => flag)
|
||||
.map(([flag, value]) => /** @type {Locator<PinElement>} */(value))
|
||||
expect(await Promise.all(relevantPins.map(async pin => await pin.innerText()))).toStrictEqual(Configuration.rgba)
|
||||
for (const p of relevantPins) {
|
||||
const pinName = await p.innerText()
|
||||
expect(p.locator('input[type="checkbox"]')).toBeChecked({ checked: pinName === "R" })
|
||||
const relevantPins = []
|
||||
for (const pin of pins) {
|
||||
const innerText = await pin.innerText()
|
||||
if (Configuration.rgba.includes(innerText)) {
|
||||
relevantPins.push(pin)
|
||||
}
|
||||
}
|
||||
for (const pin of relevantPins) {
|
||||
const pinName = await pin.innerText()
|
||||
// Only pin R is checked
|
||||
await expect(pin.locator('input[type="checkbox"]')).toBeChecked({ checked: pinName === "R" })
|
||||
}
|
||||
await relevantPins[0].locator('input[type="checkbox"]').uncheck() // Uncheck "R"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').check() // Check "B"
|
||||
await relevantPins[3].locator('input[type="checkbox"]').check() // Check "A"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').uncheck() // Uncheck "B"
|
||||
await relevantPins[2].locator('input[type="checkbox"]').check() // Check "B"
|
||||
expect(node.locator(".ueb-node-name")).toHaveText("Mask ( B A )")
|
||||
await expect(node.locator(".ueb-node-name")).toHaveText("Mask ( B A )")
|
||||
const resultSerialization = await blueprintPage.blueprintLocator.evaluate(blueprint => {
|
||||
blueprint.selectAll()
|
||||
return blueprint.template.getCopyInputObject().getSerializedText()
|
||||
@@ -97,6 +95,49 @@ export default class IssuesNodes1 extends NodeTests {
|
||||
expect(resultSerialization).toMatch(Utility.getFirstWordOrder(words))
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Issue 21",
|
||||
title: "Subtract(1,1)",
|
||||
value: String.raw`
|
||||
Begin Object Class=/Script/UnrealEd.MaterialGraphNode Name="MaterialGraphNode_202" ExportPath=/Script/UnrealEd.MaterialGraphNode'/Engine/Transient.卡通:MaterialGraph_0.MaterialGraphNode_202'
|
||||
Begin Object Class=/Script/Engine.MaterialExpressionSubtract Name="MaterialExpressionSubtract_10" ExportPath=/Script/Engine.MaterialExpressionSubtract'/Engine/Transient.卡通:MaterialGraph_0.MaterialGraphNode_202.MaterialExpressionSubtract_10'
|
||||
End Object
|
||||
Begin Object Name="MaterialExpressionSubtract_10" ExportPath=/Script/Engine.MaterialExpressionSubtract'/Engine/Transient.卡通:MaterialGraph_0.MaterialGraphNode_202.MaterialExpressionSubtract_10'
|
||||
A=(Expression="/Script/Engine.MaterialExpressionSaturate'MaterialGraphNode_237.MaterialExpressionSaturate_3'")
|
||||
B=(Expression="/Script/Engine.MaterialExpressionSaturate'MaterialGraphNode_201.MaterialExpressionSaturate_7'")
|
||||
MaterialExpressionEditorX=0
|
||||
MaterialExpressionEditorY=0
|
||||
MaterialExpressionGuid=7202C13642DA1225C118CF867599387C
|
||||
Material="/Script/UnrealEd.PreviewMaterial'/Engine/Transient.卡通'"
|
||||
End Object
|
||||
MaterialExpression=/Script/Engine.MaterialExpressionSubtract'MaterialExpressionSubtract_10'
|
||||
NodePosX=0
|
||||
NodePosY=0
|
||||
NodeGuid=7008F5AC49E8F5BFD4C707819A58C021
|
||||
CustomProperties Pin (PinId=86D4DE5E48C71A576ED0519B982907B3,PinName="A",PinType.PinCategory="optional",PinType.PinSubCategory="red",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1",LinkedTo=(),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=5C75E1374E1E7436C72B9FA072875C04,PinName="B",PinType.PinCategory="optional",PinType.PinSubCategory="red",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="1",LinkedTo=(),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=528D346A49976B0854764CA755AF2F93,PinName="Output",PinFriendlyName=NSLOCTEXT("MaterialGraphNode", "Space", " "),Direction="EGPD_Output",PinType.PinCategory="",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object
|
||||
`,
|
||||
size: [8, 6],
|
||||
color: Configuration.nodeColors.green,
|
||||
icon: null,
|
||||
pins: 3,
|
||||
pinNames: ["A", "B"],
|
||||
delegate: false,
|
||||
development: false,
|
||||
additionalTest: async (node, pins, blueprintPage) => {
|
||||
await expect(pins[0].locator("ueb-input")).toHaveText("1.0")
|
||||
await expect(pins[1].locator("ueb-input")).toHaveText("1.0")
|
||||
let inputs = await node.locator("ueb-input").all()
|
||||
await inputs[0].fill("-8")
|
||||
await blueprintPage.blur()
|
||||
expect(await node.evaluate(n => n.nodeDisplayName)).toEqual("Subtract(-8,1)")
|
||||
await inputs[1].fill("9.2")
|
||||
await blueprintPage.blur()
|
||||
expect(await node.evaluate(n => n.nodeDisplayName)).toEqual("Subtract(-8,9.2)")
|
||||
}
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../../js/Configuration.js"
|
||||
import Utility from "../../js/Utility.js"
|
||||
import PinElement from "../../js/element/PinElement.js"
|
||||
import IntegerEntity from "../../js/entity/IntegerEntity.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
import RBSerializationVector2DEntity from "../../js/entity/RBSerializationVector2DEntity.js"
|
||||
import VectorEntity from "../../js/entity/VectorEntity.js"
|
||||
import { expect } from "../fixtures/test.js"
|
||||
@@ -70,10 +70,10 @@ export default class MaterialNodes extends NodeTests {
|
||||
development: false,
|
||||
additionalTest: async node => {
|
||||
const value = 10000.0
|
||||
/** @type {Locator<PinElement<Number>>} */
|
||||
/** @type {Locator<PinElement<NumberEntity>>} */
|
||||
const pin = node.locator("ueb-pin").first()
|
||||
expect(await pin.evaluate(pin => pin.getDefaultValue())).toBeCloseTo(value)
|
||||
await expect(node.locator("ueb-input")).toHaveText([Utility.printNumber(value)])
|
||||
expect(await pin.evaluate(pin => pin.getDefaultValue().valueOf())).toBeCloseTo(value)
|
||||
await expect(node.locator("ueb-input")).toHaveText([NumberEntity.printNumber(value)])
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -111,13 +111,13 @@ export default class MaterialNodes extends NodeTests {
|
||||
additionalTest: async node => {
|
||||
const x = 0.1
|
||||
const y = 23.88888
|
||||
/** @type {Locator<PinElement<Number>>} */
|
||||
/** @type {Locator<PinElement<NumberEntity>>} */
|
||||
const xPin = node.locator("ueb-pin").nth(0)
|
||||
/** @type {Locator<PinElement<Number>>} */
|
||||
/** @type {Locator<PinElement<NumberEntity>>} */
|
||||
const yPin = node.locator("ueb-pin").nth(1)
|
||||
expect(await xPin.evaluate(pin => pin.getDefaultValue())).toBeCloseTo(x)
|
||||
expect(await yPin.evaluate(pin => pin.getDefaultValue())).toBeCloseTo(y)
|
||||
await expect(node.locator("ueb-input")).toHaveText([Utility.printNumber(x), Utility.printNumber(y)])
|
||||
expect(await xPin.evaluate(pin => pin.getDefaultValue().valueOf())).toBeCloseTo(x)
|
||||
expect(await yPin.evaluate(pin => pin.getDefaultValue().valueOf())).toBeCloseTo(y)
|
||||
await expect(node.locator("ueb-input")).toHaveText([NumberEntity.printNumber(x), NumberEntity.printNumber(y)])
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -157,7 +157,7 @@ export default class MaterialNodes extends NodeTests {
|
||||
const values = await input.evaluate(pin => pin.getDefaultValue().toArray())
|
||||
const expected = [0.00432, 123.199997, 7657650176.0]
|
||||
expected.forEach((v, i) => expect(v).toBeCloseTo(values[i]))
|
||||
await expect(input.locator("ueb-input")).toHaveText(expected.map(v => Utility.printNumber(v)))
|
||||
await expect(input.locator("ueb-input")).toHaveText(expected.map(v => NumberEntity.printNumber(v)))
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -490,9 +490,7 @@ export default class MaterialNodes extends NodeTests {
|
||||
color: Configuration.nodeColors.red,
|
||||
icon: null,
|
||||
pins: 2,
|
||||
pinNames: [
|
||||
"Preview",
|
||||
],
|
||||
pinNames: ["Preview"],
|
||||
delegate: false,
|
||||
development: false,
|
||||
},
|
||||
@@ -520,9 +518,7 @@ export default class MaterialNodes extends NodeTests {
|
||||
color: Configuration.nodeColors.red,
|
||||
icon: null,
|
||||
pins: 2,
|
||||
pinNames: [
|
||||
"Preview",
|
||||
],
|
||||
pinNames: ["Preview"],
|
||||
delegate: false,
|
||||
development: false,
|
||||
},
|
||||
|
||||
@@ -193,11 +193,24 @@ export default class OperationsNodes extends NodeTests {
|
||||
delegate: false,
|
||||
development: false,
|
||||
variadic: true,
|
||||
additionalTest: async (node, pins) => {
|
||||
additionalTest: async (node, pins, blueprintPage) => {
|
||||
for (const pin of pins) {
|
||||
expect(await pin.evaluate(pin => pin.template.renderIcon().strings.join("")))
|
||||
.toStrictEqual(SVGIcon.operationPin.strings.join(""))
|
||||
}
|
||||
let inputs = await node.locator(".ueb-pin-input").all()
|
||||
for (const input of inputs) {
|
||||
expect(await input.isChecked()).toBeFalsy()
|
||||
}
|
||||
await inputs[inputs.length - 1].check()
|
||||
expect(await inputs[inputs.length - 1].isChecked()).toBeTruthy()
|
||||
const variadic = blueprintPage.node.getByText("Add pin")
|
||||
await variadic.click()
|
||||
inputs = await node.locator(".ueb-pin-input").all()
|
||||
await inputs[inputs.length - 2].uncheck()
|
||||
for (const input of inputs) {
|
||||
expect(await input.isChecked()).toBeFalsy()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -276,11 +289,21 @@ export default class OperationsNodes extends NodeTests {
|
||||
delegate: false,
|
||||
development: false,
|
||||
variadic: true,
|
||||
additionalTest: async (node, pins) => {
|
||||
additionalTest: async (node, pins, blueprintPage) => {
|
||||
for (const pin of pins) {
|
||||
expect(await pin.evaluate(pin => pin.template.renderIcon().strings.join("")))
|
||||
.toStrictEqual(SVGIcon.operationPin.strings.join(""))
|
||||
}
|
||||
expect(await pins[0].evaluate(pin => pin.entity.DefaultValue.constructor.serialized)).toBeTruthy()
|
||||
expect(await pins[1].evaluate(pin => pin.entity.DefaultValue.constructor.serialized)).toBeTruthy()
|
||||
await pins[0].locator("ueb-input").fill("54")
|
||||
await blueprintPage.blur()
|
||||
expect(await pins[0].evaluate(pin => pin.entity.DefaultValue.constructor.serialized)).toBeTruthy()
|
||||
expect(await pins[0].evaluate(pin => pin.entity.DefaultValue.serialize())).toEqual('"54"')
|
||||
await pins[1].locator("ueb-input").fill("771")
|
||||
await blueprintPage.blur()
|
||||
expect(await pins[1].evaluate(pin => pin.entity.DefaultValue.constructor.serialized)).toBeTruthy()
|
||||
expect(await pins[1].evaluate(pin => pin.entity.DefaultValue.serialize())).toEqual('"771"')
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -570,7 +570,7 @@ export default class OtherNodes extends NodeTests {
|
||||
await inputs[1].fill("-22.22")
|
||||
await inputs[2].fill("-33.33")
|
||||
await blueprintPage.blur()
|
||||
expect(await pins[2].evaluate(pin => pin.entity.DefaultValue.constructor.name))
|
||||
expect(await pins[2].evaluate(pin => pin.entity.DefaultValue.constructor.className()))
|
||||
.toBe("SimpleSerializationVectorEntity")
|
||||
await expect(pins[2].locator("ueb-input")).toHaveText(["-11.11", "-22.22", "-33.33"])
|
||||
inputs = await pins[3].locator("ueb-input").all()
|
||||
@@ -578,18 +578,18 @@ export default class OtherNodes extends NodeTests {
|
||||
await inputs[1].fill("77")
|
||||
await inputs[2].fill("66")
|
||||
await blueprintPage.blur()
|
||||
expect(await pins[3].evaluate(pin => pin.entity.DefaultValue.constructor.name))
|
||||
expect(await pins[3].evaluate(pin => pin.entity.DefaultValue.constructor.className()))
|
||||
.toBe("SimpleSerializationRotatorEntity")
|
||||
await expect(pins[3].locator("ueb-input")).toHaveText(["88.0", "77.0", "66.0"])
|
||||
await pins[4].locator("ueb-input").fill("35.814")
|
||||
await blueprintPage.blur()
|
||||
expect(await pins[4].evaluate(pin => pin.entity.DefaultValue.constructor.name))
|
||||
expect(await pins[4].evaluate(pin => pin.entity.DefaultValue.constructor.className()))
|
||||
.toBe("IntegerEntity")
|
||||
await expect(pins[4].locator("ueb-input")).toHaveText("35")
|
||||
await pins[6].locator("input").check()
|
||||
await expect(pins[6].locator("input")).toBeChecked()
|
||||
expect(await pins[6].evaluate(pin => pin.entity.DefaultValue.constructor.name))
|
||||
.toBe("Boolean")
|
||||
expect(await pins[6].evaluate(pin => pin.entity.DefaultValue.constructor.className()))
|
||||
.toBe("BooleanEntity")
|
||||
const serialization = await blueprintPage.getSerializedNodes()
|
||||
await blueprintPage.removeNodes()
|
||||
await blueprintPage.paste(serialization)
|
||||
|
||||
12
tests/resources/serializedEntity2-1.js
Normal file
12
tests/resources/serializedEntity2-1.js
Normal file
@@ -0,0 +1,12 @@
|
||||
export default `{
|
||||
someNumber: 567
|
||||
someString: "alpha"
|
||||
someString2: "beta"
|
||||
someBoolean: True
|
||||
someBoolean2: False
|
||||
someObjectString: "gamma"
|
||||
someArray: (400,500,600,700,800)
|
||||
someArray2: (-400,-500,-600,-700,-800)
|
||||
someEntity.a: 8
|
||||
someEntity.b: 9
|
||||
}`
|
||||
@@ -6,6 +6,6 @@ export default `{
|
||||
someBoolean2: False
|
||||
someObjectString: "gamma"
|
||||
someArray: (400,500,600,700,800)
|
||||
someArray2: (400,500,600,700,800)
|
||||
someArray2: (-400,-500,-600,-700,-800)
|
||||
someEntity: Entity1(a=8, b=9)
|
||||
}`
|
||||
|
||||
@@ -14,7 +14,6 @@ export default `[[
|
||||
november: 0
|
||||
oscar: Entity1(a=8, b=9)
|
||||
papa: Entity1(a=12, b=13)
|
||||
quebec: 6
|
||||
romeo.a: 8
|
||||
romeo.b: 9
|
||||
sierra.someNumber: 567
|
||||
@@ -24,6 +23,6 @@ export default `[[
|
||||
sierra.someBoolean2: False
|
||||
sierra.someObjectString: "gamma"
|
||||
sierra.someArray: (400,500,600,700,800)
|
||||
sierra.someArray2: (400,500,600,700,800)
|
||||
sierra.someArray2: (-400,-500,-600,-700,-800)
|
||||
sierra.someEntity: Entity1(a=8, b=9)
|
||||
]]`
|
||||
|
||||
@@ -23,7 +23,7 @@ export default `Begin
|
||||
\${first.sierra.someBoolean2} => False
|
||||
\${first.sierra.someObjectString} => "gamma"
|
||||
\${first.sierra.someArray} => (400,500,600,700,800)
|
||||
\${first.sierra.someArray2} => (400,500,600,700,800)
|
||||
\${first.sierra.someArray2} => (-400,-500,-600,-700,-800)
|
||||
\${first.sierra.someEntity} => E1[A:8 - B:9]
|
||||
\${second(0).a} => 1
|
||||
\${second(0).b} => 2
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export default `Begin Object
|
||||
key1="Value 1"
|
||||
key2=Foo(arg1=55,arg2="Argument 2")
|
||||
End Object
|
||||
`
|
||||
@@ -51,48 +51,6 @@ test("approximatelyEqual method test", () => {
|
||||
expect(Utility.approximatelyEqual(2, 3)).toBeFalsy()
|
||||
})
|
||||
|
||||
test("equals method test", () => {
|
||||
expect(Utility.equals(0.2, 0.2)).toBeTruthy()
|
||||
// @ts-expect-error
|
||||
expect(Utility.equals(new Number(0.7), 0.7)).toBeTruthy()
|
||||
// @ts-expect-error
|
||||
expect(Utility.equals(-40.3, new Number(-40.3))).toBeTruthy()
|
||||
// @ts-expect-error
|
||||
expect(Utility.equals(new Number(-40.3), new Number(-40.3))).toBeTruthy()
|
||||
expect(Utility.equals(0.2 + 0.1, 0.3)).toBeFalsy() // Strict equality
|
||||
expect(Utility.equals(null, undefined)).toBeFalsy()
|
||||
expect(Utility.equals(undefined, null)).toBeFalsy()
|
||||
expect(Utility.equals(0, false)).toBeFalsy()
|
||||
expect(Utility.equals(false, false)).toBeTruthy()
|
||||
expect(Utility.equals(2n, 2)).toBeTruthy()
|
||||
expect(Utility.equals(-6845, -6845n)).toBeTruthy()
|
||||
expect(Utility.equals(7735n, 7736)).toBeFalsy()
|
||||
expect(Utility.equals("abc", "abc")).toBeTruthy()
|
||||
// @ts-expect-error
|
||||
expect(Utility.equals(new String("abc"), new String("abc"))).toBeTruthy()
|
||||
expect(Utility.equals("abc", "aBc")).toBeFalsy()
|
||||
expect(Utility.equals([], [])).toBeTruthy()
|
||||
expect(Utility.equals(
|
||||
[-2, "alpha", new String("beta"), new Number(40), [1, 2, 3]],
|
||||
[new Number(-2), new String("alpha"), new String("beta"), new Number(40), new Array(1, 2, 3)]
|
||||
)).toBeTruthy()
|
||||
expect(Utility.equals(
|
||||
[-2.1, "alpha", new String("beta"), new Number(40), [1, 2, 3]],
|
||||
[new Number(-2), new String("alpha"), new String("beta"), new Number(40), new Array(1, 2, 3)]
|
||||
)).toBeFalsy() // First element is different
|
||||
expect(Utility.equals(
|
||||
[-2, "Alpha", new String("beta"), new Number(40), [1, 2, 3]],
|
||||
[new Number(-2), new String("alpha"), new String("beta"), new Number(40), new Array(1, 2, 3)]
|
||||
)).toBeFalsy() // Second element is different
|
||||
})
|
||||
|
||||
test("isValueOfType method test", () => {
|
||||
expect(Utility.isValueOfType(34, Number)).toBeTruthy()
|
||||
expect(Utility.isValueOfType(new Number(34), Number)).toBeTruthy()
|
||||
expect(Utility.isValueOfType("34", String)).toBeTruthy()
|
||||
expect(Utility.isValueOfType("34", Number)).toBeFalsy()
|
||||
})
|
||||
|
||||
test("mergeArrays method test", () => {
|
||||
expect(Utility.mergeArrays(
|
||||
[],
|
||||
|
||||
Reference in New Issue
Block a user