code: /*
   * Copyright (c) 2021 the Eclipse Milo Authors
   *
   * This program and the accompanying materials are made
   * available under the terms of the Eclipse Public License 2.0
   * which is available at https://www.eclipse.org/legal/epl-2.0/
   *
   * SPDX-License-Identifier: EPL-2.0
   */
  
  package org.eclipse.milo.opcua.stack.core.types.builtin;
  
  import java.util.Random;
  import java.util.UUID;
  import javax.xml.bind.DatatypeConverter;
  
  import org.eclipse.milo.opcua.stack.core.NamespaceTable;
  import org.eclipse.milo.opcua.stack.core.UaRuntimeException;
  import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte;
  import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
  import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
  import org.eclipse.milo.opcua.stack.core.util.Namespaces;
  import org.testng.annotations.Test;
  
  import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
  import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.ushort;
  import static org.testng.Assert.assertEquals;
  import static org.testng.Assert.assertFalse;
  import static org.testng.Assert.assertNotNull;
  import static org.testng.Assert.assertNull;
  import static org.testng.Assert.assertThrows;
  import static org.testng.Assert.assertTrue;
  
  public class NodeIdTest {
  
      @Test
      public void testParseLargerThanIntMax() {
          long i = Integer.MAX_VALUE + 1L;
          NodeId nodeId = NodeId.parse("ns=1;i=" + i);
  
          assertNotNull(nodeId);
          assertEquals(nodeId.getIdentifier(), uint(i));
      }
  
      @Test
      public void testParseInvalid() {
          assertNull(NodeId.parseOrNull(""));
          assertNull(NodeId.parseOrNull("n"));
          assertNull(NodeId.parseOrNull("ns"));
          assertNull(NodeId.parseOrNull("ns="));
          assertNull(NodeId.parseOrNull("ns=0"));
          assertNull(NodeId.parseOrNull("ns=0;"));
          assertNull(NodeId.parseOrNull("ns=0;s"));
      }
  
      @Test
      public void testParseInvalidInt() {
          assertThrows(UaRuntimeException.class, () -> NodeId.parse("ns=0;i=" + UInteger.MAX_VALUE + 1));
          assertThrows(UaRuntimeException.class, () -> NodeId.parse("ns=0;i=" + -1));
      }
  
      @Test
      public void testParseNamespaceIndex() {
          for (int i = 0; i < UShort.MAX_VALUE; i++) {
              NodeId nodeId = NodeId.parseOrNull("ns=" + i + ";i=" + i);
              assertNotNull(nodeId);
              assertEquals(nodeId.getNamespaceIndex(), ushort(i));
              assertEquals(nodeId.getIdentifier(), uint(i));
          }
      }
  
      @Test
      public void testParseInt() {
          long[] is = new long[]{0, UByte.MAX_VALUE, UShort.MAX_VALUE, UInteger.MAX_VALUE};
  
          for (long i : is) {
              assertNotNull(NodeId.parseOrNull("i=" + i));
              assertNotNull(NodeId.parseOrNull("ns=0;i=" + i));
          }
      }
  
      @Test
      public void testParseString() {
          assertNotNull(NodeId.parseOrNull("s="));
          assertNotNull(NodeId.parseOrNull("s=foo"));
          assertNotNull(NodeId.parseOrNull("ns=0;s="));
          assertNotNull(NodeId.parseOrNull("ns=0;s=foo"));
      }
  
      @Test
      public void testParseGuid() {
          for (int i = 0; i < 100; i++) {
              UUID uuid = UUID.randomUUID();
              {
                  NodeId nodeId = NodeId.parseOrNull("g=" + uuid.toString());
                  assertNotNull(nodeId);
                  assertEquals(nodeId.getIdentifier(), uuid);
              }
              {
                  NodeId nodeId = NodeId.parseOrNull("ns=0;g=" + uuid.toString());
                  assertNotNull(nodeId);
                  assertEquals(nodeId.getIdentifier(), uuid);
              }
          }
      }
  
      @Test
      public void testParseByteString() {
          Random r = new Random();
  
          for (int i = 0; i < 100; i++) {
              byte[] bs = new byte[r.nextInt(64) + 1];
              r.nextBytes(bs);
              String bss = DatatypeConverter.printBase64Binary(bs);
  
              {
                  NodeId nodeId = NodeId.parseOrNull("b=" + bss);
                  assertNotNull(nodeId);
                  assertEquals(nodeId.getIdentifier(), ByteString.of(bs));
              }
              {
                  NodeId nodeId = NodeId.parseOrNull("ns=0;b=" + bss);
                  assertNotNull(nodeId);
                  assertEquals(nodeId.getIdentifier(), ByteString.of(bs));
              }
          }
      }
  
      @Test
      public void testEqualityWithExpandedNodeId() {
          NodeId nodeId = new NodeId(0, "foo");
  
          {
              ExpandedNodeId xni = nodeId.expanded();
  
              assertTrue(nodeId.equalTo(xni));
          }
  
          {
              ExpandedNodeId xni = new ExpandedNodeId(ushort(0), Namespaces.OPC_UA, "foo");
  
              assertTrue(nodeId.equalTo(xni));
          }
  
          {
              ExpandedNodeId xni = new ExpandedNodeId(ushort(1), Namespaces.OPC_UA, "foo");
  
              assertTrue(nodeId.equalTo(xni));
          }
  
          {
              ExpandedNodeId xni = new ExpandedNodeId(ushort(0), Namespaces.OPC_UA, "foo", uint(1));
  
              assertFalse(nodeId.equalTo(xni));
          }
  
          {
              ExpandedNodeId xni = new ExpandedNodeId(ushort(0), "uri:foo:bar", "foo");
  
              assertFalse(nodeId.equalTo(xni));
          }
      }
  
      @Test
      public void testStringWithNewlineCharacters() {
          NodeId nodeId1 = NodeId.parse("s=foo\nbar\nbaz");
          assertNotNull(nodeId1);
          assertNotNull(NodeId.parse(nodeId1.toParseableString()));
  
          NodeId nodeId2 = NodeId.parse("ns=2;s=foo\n\bar\nbaz");
          assertNotNull(nodeId2);
          assertNotNull(NodeId.parse(nodeId2.toParseableString()));
      }
  
      @Test
      public void testExpandedWithNamespaceTable() {
          NamespaceTable namespaceTable = new NamespaceTable();
          namespaceTable.addUri("urn:test");
  
          NodeId nodeId = new NodeId(1, "foo");
          ExpandedNodeId xni = nodeId.expanded(namespaceTable);
  
          assertEquals(xni.getNamespaceUri(), "urn:test");
      }
  
      @Test
      public void parseIdentifierContainingSemiColons() {
          NodeId nodeId = NodeId.parse("ns=14;s=O=::/#pc;B=::/#pc;S=pc;");
  
          assertEquals(nodeId.getNamespaceIndex(), ushort(14));
          assertEquals(nodeId.getIdentifier(), "O=::/#pc;B=::/#pc;S=pc;");
      }
  
  }
  