The reconcile package is used for DOM reconcilation in Isomorphic Go web applications.

if_test.go 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package webdav
  5. import (
  6. "reflect"
  7. "strings"
  8. "testing"
  9. )
  10. func TestParseIfHeader(t *testing.T) {
  11. // The "section x.y.z" test cases come from section x.y.z of the spec at
  12. // http://www.webdav.org/specs/rfc4918.html
  13. testCases := []struct {
  14. desc string
  15. input string
  16. want ifHeader
  17. }{{
  18. "bad: empty",
  19. ``,
  20. ifHeader{},
  21. }, {
  22. "bad: no parens",
  23. `foobar`,
  24. ifHeader{},
  25. }, {
  26. "bad: empty list #1",
  27. `()`,
  28. ifHeader{},
  29. }, {
  30. "bad: empty list #2",
  31. `(a) (b c) () (d)`,
  32. ifHeader{},
  33. }, {
  34. "bad: no list after resource #1",
  35. `<foo>`,
  36. ifHeader{},
  37. }, {
  38. "bad: no list after resource #2",
  39. `<foo> <bar> (a)`,
  40. ifHeader{},
  41. }, {
  42. "bad: no list after resource #3",
  43. `<foo> (a) (b) <bar>`,
  44. ifHeader{},
  45. }, {
  46. "bad: no-tag-list followed by tagged-list",
  47. `(a) (b) <foo> (c)`,
  48. ifHeader{},
  49. }, {
  50. "bad: unfinished list",
  51. `(a`,
  52. ifHeader{},
  53. }, {
  54. "bad: unfinished ETag",
  55. `([b`,
  56. ifHeader{},
  57. }, {
  58. "bad: unfinished Notted list",
  59. `(Not a`,
  60. ifHeader{},
  61. }, {
  62. "bad: double Not",
  63. `(Not Not a)`,
  64. ifHeader{},
  65. }, {
  66. "good: one list with a Token",
  67. `(a)`,
  68. ifHeader{
  69. lists: []ifList{{
  70. conditions: []Condition{{
  71. Token: `a`,
  72. }},
  73. }},
  74. },
  75. }, {
  76. "good: one list with an ETag",
  77. `([a])`,
  78. ifHeader{
  79. lists: []ifList{{
  80. conditions: []Condition{{
  81. ETag: `a`,
  82. }},
  83. }},
  84. },
  85. }, {
  86. "good: one list with three Nots",
  87. `(Not a Not b Not [d])`,
  88. ifHeader{
  89. lists: []ifList{{
  90. conditions: []Condition{{
  91. Not: true,
  92. Token: `a`,
  93. }, {
  94. Not: true,
  95. Token: `b`,
  96. }, {
  97. Not: true,
  98. ETag: `d`,
  99. }},
  100. }},
  101. },
  102. }, {
  103. "good: two lists",
  104. `(a) (b)`,
  105. ifHeader{
  106. lists: []ifList{{
  107. conditions: []Condition{{
  108. Token: `a`,
  109. }},
  110. }, {
  111. conditions: []Condition{{
  112. Token: `b`,
  113. }},
  114. }},
  115. },
  116. }, {
  117. "good: two Notted lists",
  118. `(Not a) (Not b)`,
  119. ifHeader{
  120. lists: []ifList{{
  121. conditions: []Condition{{
  122. Not: true,
  123. Token: `a`,
  124. }},
  125. }, {
  126. conditions: []Condition{{
  127. Not: true,
  128. Token: `b`,
  129. }},
  130. }},
  131. },
  132. }, {
  133. "section 7.5.1",
  134. `<http://www.example.com/users/f/fielding/index.html>
  135. (<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)`,
  136. ifHeader{
  137. lists: []ifList{{
  138. resourceTag: `http://www.example.com/users/f/fielding/index.html`,
  139. conditions: []Condition{{
  140. Token: `urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6`,
  141. }},
  142. }},
  143. },
  144. }, {
  145. "section 7.5.2 #1",
  146. `(<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`,
  147. ifHeader{
  148. lists: []ifList{{
  149. conditions: []Condition{{
  150. Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`,
  151. }},
  152. }},
  153. },
  154. }, {
  155. "section 7.5.2 #2",
  156. `<http://example.com/locked/>
  157. (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`,
  158. ifHeader{
  159. lists: []ifList{{
  160. resourceTag: `http://example.com/locked/`,
  161. conditions: []Condition{{
  162. Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`,
  163. }},
  164. }},
  165. },
  166. }, {
  167. "section 7.5.2 #3",
  168. `<http://example.com/locked/member>
  169. (<urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf>)`,
  170. ifHeader{
  171. lists: []ifList{{
  172. resourceTag: `http://example.com/locked/member`,
  173. conditions: []Condition{{
  174. Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`,
  175. }},
  176. }},
  177. },
  178. }, {
  179. "section 9.9.6",
  180. `(<urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4>)
  181. (<urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77>)`,
  182. ifHeader{
  183. lists: []ifList{{
  184. conditions: []Condition{{
  185. Token: `urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4`,
  186. }},
  187. }, {
  188. conditions: []Condition{{
  189. Token: `urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77`,
  190. }},
  191. }},
  192. },
  193. }, {
  194. "section 9.10.8",
  195. `(<urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>)`,
  196. ifHeader{
  197. lists: []ifList{{
  198. conditions: []Condition{{
  199. Token: `urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4`,
  200. }},
  201. }},
  202. },
  203. }, {
  204. "section 10.4.6",
  205. `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
  206. ["I am an ETag"])
  207. (["I am another ETag"])`,
  208. ifHeader{
  209. lists: []ifList{{
  210. conditions: []Condition{{
  211. Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`,
  212. }, {
  213. ETag: `"I am an ETag"`,
  214. }},
  215. }, {
  216. conditions: []Condition{{
  217. ETag: `"I am another ETag"`,
  218. }},
  219. }},
  220. },
  221. }, {
  222. "section 10.4.7",
  223. `(Not <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
  224. <urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092>)`,
  225. ifHeader{
  226. lists: []ifList{{
  227. conditions: []Condition{{
  228. Not: true,
  229. Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`,
  230. }, {
  231. Token: `urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092`,
  232. }},
  233. }},
  234. },
  235. }, {
  236. "section 10.4.8",
  237. `(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)
  238. (Not <DAV:no-lock>)`,
  239. ifHeader{
  240. lists: []ifList{{
  241. conditions: []Condition{{
  242. Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`,
  243. }},
  244. }, {
  245. conditions: []Condition{{
  246. Not: true,
  247. Token: `DAV:no-lock`,
  248. }},
  249. }},
  250. },
  251. }, {
  252. "section 10.4.9",
  253. `</resource1>
  254. (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
  255. [W/"A weak ETag"]) (["strong ETag"])`,
  256. ifHeader{
  257. lists: []ifList{{
  258. resourceTag: `/resource1`,
  259. conditions: []Condition{{
  260. Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`,
  261. }, {
  262. ETag: `W/"A weak ETag"`,
  263. }},
  264. }, {
  265. resourceTag: `/resource1`,
  266. conditions: []Condition{{
  267. ETag: `"strong ETag"`,
  268. }},
  269. }},
  270. },
  271. }, {
  272. "section 10.4.10",
  273. `<http://www.example.com/specs/>
  274. (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)`,
  275. ifHeader{
  276. lists: []ifList{{
  277. resourceTag: `http://www.example.com/specs/`,
  278. conditions: []Condition{{
  279. Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`,
  280. }},
  281. }},
  282. },
  283. }, {
  284. "section 10.4.11 #1",
  285. `</specs/rfc2518.doc> (["4217"])`,
  286. ifHeader{
  287. lists: []ifList{{
  288. resourceTag: `/specs/rfc2518.doc`,
  289. conditions: []Condition{{
  290. ETag: `"4217"`,
  291. }},
  292. }},
  293. },
  294. }, {
  295. "section 10.4.11 #2",
  296. `</specs/rfc2518.doc> (Not ["4217"])`,
  297. ifHeader{
  298. lists: []ifList{{
  299. resourceTag: `/specs/rfc2518.doc`,
  300. conditions: []Condition{{
  301. Not: true,
  302. ETag: `"4217"`,
  303. }},
  304. }},
  305. },
  306. }}
  307. for _, tc := range testCases {
  308. got, ok := parseIfHeader(strings.Replace(tc.input, "\n", "", -1))
  309. if gotEmpty := reflect.DeepEqual(got, ifHeader{}); gotEmpty == ok {
  310. t.Errorf("%s: should be different: empty header == %t, ok == %t", tc.desc, gotEmpty, ok)
  311. continue
  312. }
  313. if !reflect.DeepEqual(got, tc.want) {
  314. t.Errorf("%s:\ngot %v\nwant %v", tc.desc, got, tc.want)
  315. continue
  316. }
  317. }
  318. }