tables_test.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package urn
  2. import (
  3. "strconv"
  4. "strings"
  5. )
  6. func ierror(index int) string {
  7. return "Test case num. " + strconv.Itoa(index+1)
  8. }
  9. func herror(index int, test testCase) string {
  10. return ierror(index) + ", input \"" + test.in + "\""
  11. }
  12. func rxpad(str string, lim int) string {
  13. str = str + strings.Repeat(" ", lim)
  14. return str[:lim]
  15. }
  16. type testCase struct {
  17. in string // the input
  18. ok bool // whether it is valid or not
  19. obj *URN // a pointer to the resulting urn.URN instance
  20. str string // string representation
  21. norm string // norm string representation
  22. }
  23. var tests = []testCase{
  24. // ok
  25. {"urn:simple:simple", true, &URN{prefix: "urn", ID: "simple", SS: "simple"}, "urn:simple:simple", "urn:simple:simple"},
  26. {"urn:ciao:%5D", true, &URN{prefix: "urn", ID: "ciao", SS: "%5D"}, "urn:ciao:%5D", "urn:ciao:%5d"},
  27. // ok - RFC examples
  28. {"URN:foo:a123,456", true, &URN{prefix: "URN", ID: "foo", SS: "a123,456"}, "URN:foo:a123,456", "urn:foo:a123,456"},
  29. {"urn:foo:a123,456", true, &URN{prefix: "urn", ID: "foo", SS: "a123,456"}, "urn:foo:a123,456", "urn:foo:a123,456"},
  30. {"urn:FOO:a123,456", true, &URN{prefix: "urn", ID: "FOO", SS: "a123,456"}, "urn:FOO:a123,456", "urn:foo:a123,456"},
  31. {"urn:foo:A123,456", true, &URN{prefix: "urn", ID: "foo", SS: "A123,456"}, "urn:foo:A123,456", "urn:foo:A123,456"},
  32. {"urn:foo:a123%2C456", true, &URN{prefix: "urn", ID: "foo", SS: "a123%2C456"}, "urn:foo:a123%2C456", "urn:foo:a123%2c456"},
  33. {"URN:FOO:a123%2c456", true, &URN{prefix: "URN", ID: "FOO", SS: "a123%2c456"}, "URN:FOO:a123%2c456", "urn:foo:a123%2c456"},
  34. {"URN:FOO:ABC%FFabc123%2c456", true, &URN{prefix: "URN", ID: "FOO", SS: "ABC%FFabc123%2c456"}, "URN:FOO:ABC%FFabc123%2c456", "urn:foo:ABC%ffabc123%2c456"},
  35. {"URN:FOO:ABC%FFabc123%2C456%9A", true, &URN{prefix: "URN", ID: "FOO", SS: "ABC%FFabc123%2C456%9A"}, "URN:FOO:ABC%FFabc123%2C456%9A", "urn:foo:ABC%ffabc123%2c456%9a"},
  36. // ok - SCIM v2
  37. {"urn:ietf:params:scim:schemas:core:2.0:User", true, &URN{prefix: "urn", ID: "ietf", SS: "params:scim:schemas:core:2.0:User"}, "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:core:2.0:User"},
  38. {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", true, &URN{prefix: "urn", ID: "ietf", SS: "params:scim:schemas:extension:enterprise:2.0:User"}, "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"},
  39. {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:userName", true, &URN{prefix: "urn", ID: "ietf", SS: "params:scim:schemas:extension:enterprise:2.0:User:userName"}, "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:userName", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:userName"},
  40. {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true, &URN{prefix: "urn", ID: "ietf", SS: "params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified"}, "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified"},
  41. // ok - minimum urn
  42. {"urn:a:b", true, &URN{prefix: "urn", ID: "a", SS: "b"}, "urn:a:b", "urn:a:b"},
  43. {"urn:a::", true, &URN{prefix: "urn", ID: "a", SS: ":"}, "urn:a::", "urn:a::"},
  44. {"urn:a:-", true, &URN{prefix: "urn", ID: "a", SS: "-"}, "urn:a:-", "urn:a:-"},
  45. // ok - URN prefix is case-insensitive
  46. {"URN:simple:simple", true, &URN{prefix: "URN", ID: "simple", SS: "simple"}, "URN:simple:simple", "urn:simple:simple"},
  47. {"Urn:simple:simple", true, &URN{prefix: "Urn", ID: "simple", SS: "simple"}, "Urn:simple:simple", "urn:simple:simple"},
  48. // ok - ID can contain the "urn" string but it can not be exactly equal to it
  49. {"urn:urna:simple", true, &URN{prefix: "urn", ID: "urna", SS: "simple"}, "urn:urna:simple", "urn:urna:simple"},
  50. {"urn:burnout:nss", true, &URN{prefix: "urn", ID: "burnout", SS: "nss"}, "urn:burnout:nss", "urn:burnout:nss"},
  51. {"urn:burn:nss", true, &URN{prefix: "urn", ID: "burn", SS: "nss"}, "urn:burn:nss", "urn:burn:nss"},
  52. {"urn:urnurnurn:x", true, &URN{prefix: "urn", ID: "urnurnurn", SS: "x"}, "urn:urnurnurn:x", "urn:urnurnurn:x"},
  53. // ok - ID can contains maximum 32 characters
  54. {"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true, &URN{prefix: "urn", ID: "abcdefghilmnopqrstuvzabcdefghilm", SS: "x"}, "urn:abcdefghilmnopqrstuvzabcdefghilm:x", "urn:abcdefghilmnopqrstuvzabcdefghilm:x"},
  55. // ok - ID can be alpha numeric
  56. {"URN:123:x", true, &URN{prefix: "URN", ID: "123", SS: "x"}, "URN:123:x", "urn:123:x"},
  57. {"URN:1ab:x", true, &URN{prefix: "URN", ID: "1ab", SS: "x"}, "URN:1ab:x", "urn:1ab:x"},
  58. {"URN:a1b:x", true, &URN{prefix: "URN", ID: "a1b", SS: "x"}, "URN:a1b:x", "urn:a1b:x"},
  59. {"URN:a12:x", true, &URN{prefix: "URN", ID: "a12", SS: "x"}, "URN:a12:x", "urn:a12:x"},
  60. {"URN:cd2:x", true, &URN{prefix: "URN", ID: "cd2", SS: "x"}, "URN:cd2:x", "urn:cd2:x"},
  61. // ok - ID can contain an hyphen (not in its first position, see below)
  62. {"URN:abcd-:x", true, &URN{prefix: "URN", ID: "abcd-", SS: "x"}, "URN:abcd-:x", "urn:abcd-:x"},
  63. {"URN:abcd-abcd:x", true, &URN{prefix: "URN", ID: "abcd-abcd", SS: "x"}, "URN:abcd-abcd:x", "urn:abcd-abcd:x"},
  64. {"URN:a123-456z:x", true, &URN{prefix: "URN", ID: "a123-456z", SS: "x"}, "URN:a123-456z:x", "urn:a123-456z:x"},
  65. // ok - SS can contain the "urn" string, also be exactly equal to it
  66. {"urn:urnx:urn", true, &URN{prefix: "urn", ID: "urnx", SS: "urn"}, "urn:urnx:urn", "urn:urnx:urn"},
  67. {"urn:urnurnurn:urn", true, &URN{prefix: "urn", ID: "urnurnurn", SS: "urn"}, "urn:urnurnurn:urn", "urn:urnurnurn:urn"},
  68. {"urn:hey:urnurnurn", true, &URN{prefix: "urn", ID: "hey", SS: "urnurnurn"}, "urn:hey:urnurnurn", "urn:hey:urnurnurn"},
  69. // ok - SS can contains and discerns multiple colons, also at the end
  70. {"urn:ciao:a:b:c", true, &URN{prefix: "urn", ID: "ciao", SS: "a:b:c"}, "urn:ciao:a:b:c", "urn:ciao:a:b:c"},
  71. {"urn:aaa:x:y:", true, &URN{prefix: "urn", ID: "aaa", SS: "x:y:"}, "urn:aaa:x:y:", "urn:aaa:x:y:"},
  72. {"urn:aaa:x:y:", true, &URN{prefix: "urn", ID: "aaa", SS: "x:y:"}, "urn:aaa:x:y:", "urn:aaa:x:y:"},
  73. // ok - SS can contain (and also start with) some non-alphabetical (ie., OTHER) characters
  74. {"urn:ciao:-", true, &URN{prefix: "urn", ID: "ciao", SS: "-"}, "urn:ciao:-", "urn:ciao:-"},
  75. {"urn:ciao::", true, &URN{prefix: "urn", ID: "ciao", SS: ":"}, "urn:ciao::", "urn:ciao::"},
  76. {"urn:colon:::::nss", true, &URN{prefix: "urn", ID: "colon", SS: "::::nss"}, "urn:colon:::::nss", "urn:colon:::::nss"},
  77. {"urn:ciao:!", true, &URN{prefix: "urn", ID: "ciao", SS: "!"}, "urn:ciao:!", "urn:ciao:!"},
  78. {"urn:ciao:!!*", true, &URN{prefix: "urn", ID: "ciao", SS: "!!*"}, "urn:ciao:!!*", "urn:ciao:!!*"},
  79. {"urn:ciao:-!:-,:x", true, &URN{prefix: "urn", ID: "ciao", SS: "-!:-,:x"}, "urn:ciao:-!:-,:x", "urn:ciao:-!:-,:x"},
  80. {"urn:ciao:=@", true, &URN{prefix: "urn", ID: "ciao", SS: "=@"}, "urn:ciao:=@", "urn:ciao:=@"},
  81. {"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true, &URN{prefix: "urn", ID: "ciao", SS: "@!=%2C(xyz)+a,b.*@g=$_'"}, "urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", "urn:ciao:@!=%2c(xyz)+a,b.*@g=$_'"},
  82. // ok - SS can contain (and also start with) hexadecimal representation of octets
  83. {"URN:hexes:%25", true, &URN{prefix: "URN", ID: "hexes", SS: "%25"}, "URN:hexes:%25", "urn:hexes:%25"}, // Literal use of the "%" character in a namespace must be encoded using "%25"
  84. {"URN:x:abc%1Dz%2F%3az", true, &URN{prefix: "URN", ID: "x", SS: "abc%1Dz%2F%3az"}, "URN:x:abc%1Dz%2F%3az", "urn:x:abc%1dz%2f%3az"}, // Literal use of the "%" character in a namespace must be encoded using "%25"
  85. // no - ID can not start with an hyphen
  86. {"URN:-xxx:x", false, nil, "", ""},
  87. {"URN:---xxx:x", false, nil, "", ""},
  88. // no - ID can not start with a colon
  89. {"urn::colon:nss", false, nil, "", ""},
  90. {"urn::::nss", false, nil, "", ""},
  91. // no - ID can not contains more than 32 characters
  92. {"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false, nil, "", ""},
  93. // no - ID can not contain special characters
  94. {"URN:a!?:x", false, nil, "", ""},
  95. {"URN:@,:x", false, nil, "", ""},
  96. {"URN:#,:x", false, nil, "", ""},
  97. {"URN:bc'.@:x", false, nil, "", ""},
  98. // no - ID can not be equal to "urn"
  99. {"urn:urn:NSS", false, nil, "", ""},
  100. // no - ID can not contain spaces
  101. {"urn:white space:NSS", false, nil, "", ""},
  102. // no - SS can not contain spaces
  103. {"urn:concat:no spaces", false, nil, "", ""},
  104. // no - SS can not contain reserved characters (can accept them only if %-escaped)
  105. {"urn:a:%", false, nil, "", ""}, // the presence of an "%" character in an URN MUST be followed by two characters from the <hex> character set
  106. {"urn:a:?", false, nil, "", ""},
  107. {"urn:a:#", false, nil, "", ""},
  108. {"urn:a:/", false, nil, "", ""},
  109. // no - Incomplete URNs
  110. {"urn:", false, nil, "", ""},
  111. {"urn::", false, nil, "", ""},
  112. {"urn:a", false, nil, "", ""},
  113. {"urn:a:", false, nil, "", ""},
  114. }
  115. var equivalenceTests = []struct {
  116. eq bool
  117. lx string
  118. rx string
  119. }{
  120. {true, "urn:foo:a123%2C456", "URN:FOO:a123%2c456"},
  121. {true, "urn:foo:AbC123%2C456", "URN:FOO:AbC123%2c456"},
  122. {true, "urn:foo:AbC123%2C456%1f", "URN:FOO:AbC123%2c456%1f"},
  123. {true, "URN:foo:a123,456", "urn:foo:a123,456"},
  124. {true, "URN:foo:a123,456", "urn:FOO:a123,456"},
  125. {true, "urn:foo:a123,456", "urn:FOO:a123,456"},
  126. {true, "urn:ciao:%2E", "urn:ciao:%2e"},
  127. {false, "urn:foo:A123,456", "URN:foo:a123,456"},
  128. {false, "urn:foo:A123,456", "urn:foo:a123,456"},
  129. {false, "urn:foo:A123,456", "urn:FOO:a123,456"},
  130. }