path_spec.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. var Path = require('src/parsers/path')
  2. var _ = require('src/util')
  3. function assertPath (str, expected) {
  4. var path = Path.parsePath(str)
  5. var res = pathMatch(path, expected)
  6. expect(res).toBe(true)
  7. if (!res) {
  8. console.log('Path parse failed: ', str, path)
  9. }
  10. }
  11. function assertInvalidPath (str) {
  12. var path = Path.parsePath(str)
  13. expect(path).toBeUndefined()
  14. }
  15. function pathMatch (a, b) {
  16. if (a.length !== b.length) {
  17. return false
  18. }
  19. for (var i = 0; i < a.length; i++) {
  20. if (a[i] !== b[i]) {
  21. return false
  22. }
  23. }
  24. return true
  25. }
  26. describe('Path Parser', function () {
  27. it('parse simple paths', function () {
  28. assertPath('', [])
  29. assertPath(' ', [])
  30. assertPath('a', ['a'])
  31. assertPath('a.b', ['a', 'b'])
  32. assertPath('a. b', ['a', 'b'])
  33. assertPath('a .b', ['a', 'b'])
  34. assertPath('a . b', ['a', 'b'])
  35. assertPath(' a . b ', ['a', 'b'])
  36. assertPath('a[0]', ['a', '0'])
  37. assertPath('a [0]', ['a', '0'])
  38. assertPath('a[0][1]', ['a', '0', '1'])
  39. assertPath('a [ 0 ] [ 1 ] ', ['a', '0', '1'])
  40. assertPath('[1234567890] ', ['1234567890'])
  41. assertPath(' [1234567890] ', ['1234567890'])
  42. assertPath('opt0', ['opt0'])
  43. assertPath('$foo.$bar._baz', ['$foo', '$bar', '_baz'])
  44. assertPath('foo["baz"]', ['foo', 'baz'])
  45. })
  46. it('parse dynamic paths', function () {
  47. assertPath('foo["b\\"az"]', ['foo', '*"b\\"az"'])
  48. assertPath("foo['b\\'az']", ['foo', "*'b\\'az'"])
  49. assertPath('a[b][c]', ['a', '*b', '*c'])
  50. assertPath('a[ b ][ c ]', ['a', '*b', '*c'])
  51. assertPath('a[b.c]', ['a', '*b.c'])
  52. assertPath('a[b + "c"]', ['a', '*b + "c"'])
  53. assertPath('a[b[c]]', ['a', '*b[c]'])
  54. assertPath('a["c" + b]', ['a', '*"c" + b'])
  55. })
  56. it('handle invalid paths', function () {
  57. assertInvalidPath('.')
  58. assertInvalidPath(' . ')
  59. assertInvalidPath('..')
  60. assertInvalidPath('a[4')
  61. assertInvalidPath('a.b.')
  62. assertInvalidPath('a,b')
  63. assertInvalidPath('a["foo]')
  64. assertInvalidPath('[0foo]')
  65. assertInvalidPath('foo-bar')
  66. assertInvalidPath('42')
  67. assertInvalidPath(' 42 ')
  68. assertInvalidPath('foo["bar]')
  69. assertInvalidPath("foo['bar]")
  70. assertInvalidPath('a]')
  71. })
  72. it('caching', function () {
  73. var path1 = Path.parsePath('a.b.c')
  74. var path2 = Path.parsePath('a.b.c')
  75. expect(path1).toBe(path2)
  76. })
  77. it('get', function () {
  78. var path = 'a[\'b"b"c\'][0]'
  79. var obj = {
  80. a: {
  81. 'b"b"c': [12345]
  82. }
  83. }
  84. expect(Path.getPath(obj, path)).toBe(12345)
  85. expect(Path.getPath(obj, 'a.c')).toBeUndefined()
  86. })
  87. it('get dynamic', function () {
  88. var path = 'a[b]'
  89. var obj = {
  90. a: {
  91. key: 123
  92. },
  93. b: 'key'
  94. }
  95. expect(Path.getPath(obj, path)).toBe(123)
  96. })
  97. it('set', function () {
  98. var path = 'a.b.c'
  99. var obj = {
  100. a: {
  101. b: {
  102. c: null
  103. }
  104. }
  105. }
  106. var res = Path.setPath(obj, path, 12345)
  107. expect(res).toBe(true)
  108. expect(obj.a.b.c).toBe(12345)
  109. })
  110. it('set non-existent', function () {
  111. var target = {}
  112. var res = Path.setPath(target, 'a.b.c', 123)
  113. expect(res).toBe(true)
  114. expect(target.a.b.c).toBe(123)
  115. })
  116. it('set dynamic non-existent', function () {
  117. var target = {
  118. key: 'what',
  119. obj: {}
  120. }
  121. var res = Path.setPath(target, 'obj[key]', 123)
  122. expect(res).toBe(true)
  123. expect(target.obj.what).toBe(123)
  124. // sub expressions
  125. res = Path.setPath(target, 'obj["yo" + key]', 234)
  126. expect(res).toBe(true)
  127. expect(target.obj.yowhat).toBe(234)
  128. })
  129. it('set on prototype chain', function () {
  130. var parent = { a: {} }
  131. var target = Object.create(parent)
  132. var res = Path.setPath(target, 'a.b.c', 123)
  133. expect(res).toBe(true)
  134. expect(_.hasOwn(target, 'a')).toBe(false)
  135. expect(parent.a.b.c).toBe(123)
  136. })
  137. it('set array', function () {
  138. var target = {
  139. a: []
  140. }
  141. target.a.$set = jasmine.createSpy('Array.$set')
  142. var res = Path.setPath(target, 'a[1]', 123)
  143. expect(res).toBe(true)
  144. expect(target.a.$set).toHaveBeenCalledWith('1', 123)
  145. })
  146. it('set invalid', function () {
  147. var res = Path.setPath({}, 'ab[c]d', 123)
  148. expect(res).toBe(false)
  149. })
  150. })