Skip to content

Commit

Permalink
fix enum default value issue
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Jul 11, 2023
1 parent df5c916 commit 83bca12
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 61 deletions.
@@ -1,8 +1,8 @@
import "should";
import should from "should";
import { DataTypeFactory } from "node-opcua-factory";
import { resolveNodeId } from "node-opcua-nodeid";
import { parseBinaryXSDAsync } from "node-opcua-schemas";
import { NodeId, resolveNodeId } from "node-opcua-nodeid";
import { DataTypeAndEncodingId, parseBinaryXSDAsync } from "node-opcua-schemas";
import { MockProvider } from "node-opcua-schemas/test/mock_id_provider";
import { StructureType } from "node-opcua-types";
import { DataType } from "node-opcua-variant";
Expand Down Expand Up @@ -66,7 +66,6 @@ describe("test convertStructureTypeSchemaToStructureDefinition", function () {
const ss = convertStructureTypeSchemaToStructureDefinition(f.schema);
}


// --------------------------------------------------------------------------
const a = dataTypeFactory.getStructureInfoByTypeName("CustomUnionType");
const customUnionType = convertStructureTypeSchemaToStructureDefinition(a.schema);
Expand All @@ -76,21 +75,20 @@ describe("test convertStructureTypeSchemaToStructureDefinition", function () {
customUnionType.baseDataType.toString().should.eql("ns=0;i=0");

customUnionType.fields!.length.should.eql(2);

customUnionType.fields![0].name!.should.eql("foo");
customUnionType.fields![0].dataType.toString().should.eql(resolveNodeId(DataType.UInt32).toString());
customUnionType.fields![0].valueRank.should.eql(-1);
customUnionType.fields![0].arrayDimensions!.should.eql([]);
customUnionType.fields![1].isOptional.should.eql(false);
should(customUnionType.fields![0].description.text).eql(null);

customUnionType.fields![1].name!.should.eql("bar");
customUnionType.fields![1].dataType.toString().should.eql(resolveNodeId(DataType.String).toString());
customUnionType.fields![1].valueRank.should.eql(-1);
customUnionType.fields![1].arrayDimensions!.should.eql([]);
customUnionType.fields![1].isOptional.should.eql(false);
customUnionType.fields![1].isOptional.should.eql(false);
should(customUnionType.fields![1].description.text).eql(null);


// ----------------------------------------------------------------------- CustomStructType
const b = dataTypeFactory.getStructureInfoByTypeName("CustomStructType");
Expand All @@ -101,7 +99,7 @@ describe("test convertStructureTypeSchemaToStructureDefinition", function () {
customStructType.baseDataType.toString().should.eql("ns=0;i=0");

customStructType.fields!.length.should.eql(5);

customStructType.fields![0].name!.should.eql("foo");
customStructType.fields![0].dataType.toString().should.eql(resolveNodeId("String").toString());
customStructType.fields![1].name!.should.eql("bar");
Expand All @@ -112,6 +110,59 @@ describe("test convertStructureTypeSchemaToStructureDefinition", function () {
customStructType.fields![3].dataType.toString().should.eql("ns=0;i=0".toString());
customStructType.fields![4].name!.should.eql("poc");
customStructType.fields![4].dataType.toString().should.eql("ns=1;i=1".toString());

});

it("should convert a enumeration with unicode characters", async () => {
/**
*
*/
const schema1 = `
<?xml version="1.0" encoding="utf-8"?>
<opc:TypeDictionary xmlns:opc="http://opcfoundation.org/BinarySchema/" TargetNamespace="urn:eclipse:milo:opcua:server:demo" DefaultByteOrder="LittleEndian">
<opc:Import Namespace="http://opcfoundation.org/BinarySchema/"/>
<opc:EnumeratedType LengthInBits="32" Name="MyEnumeration">
<opc:EnumeratedValue Name="丸" Value="1"/>
<opc:EnumeratedValue Name="角" Value="2"/>
<opc:EnumeratedValue Name="板" Value="3"/>
<opc:EnumeratedValue Name="丸パイプ" Value="4"/>
<opc:EnumeratedValue Name="角パイプ" Value="5"/>
<opc:EnumeratedValue Name="丸パイプ材2本束ね" Value="6"/>
<opc:EnumeratedValue Name="角パイプ材2本束ね" Value="7"/>
<opc:EnumeratedValue Name="六角" Value="8"/>
<opc:EnumeratedValue Name="束ね切り" Value="9"/>
</opc:EnumeratedType>
<opc:StructuredType BaseType="ua:ExtensionObject" Name="MyStruct">
<opc:Field TypeName="opc:CharArray" Name="Name"/>
<opc:Field TypeName="tns:MyEnumeration" Name="Shape"/>
</opc:StructuredType>
</opc:TypeDictionary>
`;

const binaryEncodingNodeId = resolveNodeId("ns=1;i=1");

const idProvider = {
getDataTypeAndEncodingId(key: string): DataTypeAndEncodingId | null {
switch (key) {
case "MyStruct": {
return {
binaryEncodingNodeId: binaryEncodingNodeId,
dataTypeNodeId: resolveNodeId("ns=1;i=2"),
xmlEncodingNodeId: NodeId.nullNodeId,
jsonEncodingNodeId: NodeId.nullNodeId
};
}
}
throw new Error("Not implemented");
}
};
const dataTypeFactory = new DataTypeFactory([]);
await parseBinaryXSDAsync(schema1, idProvider, dataTypeFactory);

const e = dataTypeFactory.getEnumeration("MyEnumeration");

const s = dataTypeFactory.constructObject(binaryEncodingNodeId) as any;
s.shape.should.eql(1);
console.log(s.toString());
// console.log(s.toString());
});
});
10 changes: 3 additions & 7 deletions packages/node-opcua-enum/source/enum.ts
Expand Up @@ -120,6 +120,7 @@ export function adaptTypescriptEnum(map: _TypescriptEnum | string[]) {
return map as _TypescriptEnum;
}

const regexpSignedNumber = /^[-+]?[0-9]+$/;
/**
* @class Enum
* @constructor
Expand All @@ -141,16 +142,11 @@ export class Enum {
mm = map;
}

for (const key of Object.keys(mm)) {
if (typeof key !== "string") {
continue;
}
const val = mm[key] as number;
if (undefined === val) {
for (const [key, val] of Object.entries(mm)) {
if (typeof val !== "number") {
continue;
}
const kv = new EnumItem(key, val);

const pThis = this as any;
pThis[key] = kv;
pThis[val] = kv;
Expand Down
85 changes: 40 additions & 45 deletions packages/node-opcua-enum/test/test_enum.js
Expand Up @@ -3,12 +3,11 @@
const should = require("should");
const EnumSlow = require("enum");
const { Benchmarker } = require("node-opcua-benchmarker");
const { Enum } = require("..");
const EnumFast = Enum;
const { Enum } = require("..");
const EnumFast = Enum;

describe("Test Enum", function() {

it("should create flaggable enum from string array", function() {
describe("Test Enum", function () {
it("should create flaggable enum from string array", function () {
const e = new Enum(["e1", "e2", "e3"]);
e.get("e1").value.should.equal(1);
e.get("e2").value.should.equal(2);
Expand All @@ -20,8 +19,8 @@ describe("Test Enum", function() {
should(e.get(0)).equal(null);
});

it("should create flaggable enum from flaggable map", function() {
const e = new Enum({ "e1": 1, "e2": 2, "e3": 4 });
it("should create flaggable enum from flaggable map", function () {
const e = new Enum({ e1: 1, e2: 2, e3: 4 });
e.get("e1").value.should.equal(1);
e.get("e2").value.should.equal(2);
e.get("e3").value.should.equal(4);
Expand All @@ -32,8 +31,8 @@ describe("Test Enum", function() {
should(e.get(0)).equal(null);
});

it("should create non-flaggable enum from non-flaggable map", function() {
const e = new Enum({ "e1": 1, "e2": 2, "e3": 3 });
it("should create non-flaggable enum from non-flaggable map", function () {
const e = new Enum({ e1: 1, e2: 2, e3: 3 });
e.get("e1").value.should.equal(1);
e.get("e2").value.should.equal(2);
e.get("e3").value.should.equal(3);
Expand All @@ -45,8 +44,8 @@ describe("Test Enum", function() {
e.enumItems[0].key.should.equal("e1");
});

it("should access enum from enum item name", function() {
const e = new Enum({ "e1": 1, "e2": 2, "e3": 4 });
it("should access enum from enum item name", function () {
const e = new Enum({ e1: 1, e2: 2, e3: 4 });
e.e1.value.should.equal(1);
e.e1.key.should.equal("e1");
e.e2.value.should.equal(2);
Expand All @@ -55,8 +54,20 @@ describe("Test Enum", function() {
e.e3.key.should.equal("e3");
});

it("EnumItem should function properly", function() {
const e = new Enum({ "e1": 1, "e2": 2, "e3": 4 });
it("should handle enum with typescript type enum , value starting at 1 and unicode names", function () {
const e = new Enum({
1: "丸",
2: "角",
3: "板",
: 1,
: 2,
: 3
});
e.getDefaultValue().value.should.equal(1);
});

it("EnumItem should function properly", function () {
const e = new Enum({ e1: 1, e2: 2, e3: 4 });
const e1ore2 = e.get("e2 | e1");
e1ore2.value.should.equal(3);
e1ore2.is(e.get(3)).should.equal(true);
Expand All @@ -81,21 +92,15 @@ describe("Test Enum", function() {
e.e1.valueOf().should.equal(1);
e.e1.toJSON().should.equal("e1");
});

});


describe("Benchmarking Enums", function() {


describe("Benchmarking Enums", function () {
function perform_benchmark(params, checks, done) {

const bench = new Benchmarker();

const keys = Array.isArray(params) ? params : Object.keys(params);

function test_iteration(en) {

const e1 = en.SOMEDATA;
should.not.exist(e1);
const e2 = en.get("OTHERDATA");
Expand All @@ -106,29 +111,25 @@ describe("Benchmarking Enums", function() {
const item = en[keys[0]];
en.get(item).value.should.eql(item.value);


checks.forEach(function(p) {
checks.forEach(function (p) {
p.value.should.eql(en.get(p.key).value);
p.value.should.eql(en.get(p.value).value);
});
}

bench.add("slowEnum", function() {

const en = new EnumSlow(params);
test_iteration(en);

})
.add("fastEnum", function() {

bench
.add("slowEnum", function () {
const en = new EnumSlow(params);
test_iteration(en);
})
.add("fastEnum", function () {
const en = new EnumFast(params);
test_iteration(en);
})
.on("cycle", function(message) {
.on("cycle", function (message) {
console.log(message);
})
.on("complete", function() {

.on("complete", function () {
console.log(" Fastest is " + this.fastest.name);
console.log(" Speed Up : x", this.speedUp);
if (this.speedUp > 1.5) {
Expand All @@ -139,12 +140,9 @@ describe("Benchmarking Enums", function() {
done();
})
.run();

}


it("should verify that our enums are faster than Enum 2.1.0 (flaggable enum)", function(done) {

it("should verify that our enums are faster than Enum 2.1.0 (flaggable enum)", function (done) {
const AccessLevelFlag = {
CurrentRead: 0x01,
CurrentWrite: 0x02,
Expand All @@ -154,24 +152,24 @@ describe("Benchmarking Enums", function() {
};

const checks = [
{ key: "CurrentWrite | HistoryWrite", value: 0x0A },
{ key: "HistoryWrite | CurrentWrite", value: 0x0A },
{ key: "CurrentWrite | HistoryWrite", value: 0x0a },
{ key: "HistoryWrite | CurrentWrite", value: 0x0a },
{ key: "CurrentWrite", value: 0x02 },
{ key: "CurrentWrite | CurrentWrite", value: 0x02 },
{ key: "CurrentRead | CurrentWrite | HistoryRead | HistoryWrite | SemanticChange", value: 0x1F },
{ key: "CurrentRead | CurrentWrite | HistoryRead | HistoryWrite | SemanticChange", value: 0x1f },
{ key: "CurrentRead", value: 0x01 },
{ key: "HistoryRead", value: 0x04 },
{ key: "HistoryWrite", value: 0x08 }
];
perform_benchmark(AccessLevelFlag, checks, done);
});

it("should verify that our enums are faster than Enum 2.1.0 ( simple enum )", function(done) {
it("should verify that our enums are faster than Enum 2.1.0 ( simple enum )", function (done) {
const ApplicationType = {
SERVER: 0, // The application is a Server
CLIENT: 1, // The application is a Client
CLIENTANDSERVER: 2, // The application is a Client and a Server
DISCOVERYSERVER: 3 // The application is a DiscoveryServer
DISCOVERYSERVER: 3 // The application is a DiscoveryServer
};
const checks = [
{ key: "SERVER", value: 0 },
Expand All @@ -180,8 +178,5 @@ describe("Benchmarking Enums", function() {
{ key: "DISCOVERYSERVER", value: 3 }
];
perform_benchmark(ApplicationType, checks, done);

});


});

0 comments on commit 83bca12

Please sign in to comment.