path_spec.js 3.8 KB

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