PageRenderTime 58ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/node_modules/mpath/test/index.js

https://bitbucket.org/coleman333/smartsite
JavaScript | 1831 lines | 1561 code | 252 blank | 18 comment | 22 complexity | 479d715117a038be8538334a15cbe494 MD5 | raw file
Possible License(s): Apache-2.0, JSON, BSD-3-Clause, 0BSD, MIT, CC-BY-SA-3.0
  1. /**
  2. * Test dependencies.
  3. */
  4. var mpath = require('../')
  5. var assert = require('assert')
  6. /**
  7. * logging helper
  8. */
  9. function log (o) {
  10. console.log();
  11. console.log(require('util').inspect(o, false, 1000));
  12. }
  13. /**
  14. * special path for override tests
  15. */
  16. var special = '_doc';
  17. /**
  18. * Tests
  19. */
  20. describe('mpath', function(){
  21. /**
  22. * test doc creator
  23. */
  24. function doc () {
  25. var o = { first: { second: { third: [3,{ name: 'aaron' }, 9] }}};
  26. o.comments = [
  27. { name: 'one' }
  28. , { name: 'two', _doc: { name: '2' }}
  29. , { name: 'three'
  30. , comments: [{},{ comments: [{val: 'twoo'}]}]
  31. , _doc: { name: '3', comments: [{},{ _doc: { comments: [{ val: 2 }] }}] }}
  32. ];
  33. o.name = 'jiro';
  34. o.array = [
  35. { o: { array: [{x: {b: [4,6,8]}}, { y: 10} ] }}
  36. , { o: { array: [{x: {b: [1,2,3]}}, { x: {z: 10 }}, { x: {b: 'hi'}}] }}
  37. , { o: { array: [{x: {b: null }}, { x: { b: [null, 1]}}] }}
  38. , { o: { array: [{x: null }] }}
  39. , { o: { array: [{y: 3 }] }}
  40. , { o: { array: [3, 0, null] }}
  41. , { o: { name: 'ha' }}
  42. ];
  43. o.arr = [
  44. { arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  45. , { yep: true }
  46. ]
  47. return o;
  48. }
  49. describe('get', function(){
  50. var o = doc();
  51. it('`path` must be a string or array', function(done){
  52. assert.throws(function () {
  53. mpath.get({}, o);
  54. }, /Must be either string or array/);
  55. assert.throws(function () {
  56. mpath.get(4, o);
  57. }, /Must be either string or array/);
  58. assert.throws(function () {
  59. mpath.get(function(){}, o);
  60. }, /Must be either string or array/);
  61. assert.throws(function () {
  62. mpath.get(/asdf/, o);
  63. }, /Must be either string or array/);
  64. assert.throws(function () {
  65. mpath.get(Math, o);
  66. }, /Must be either string or array/);
  67. assert.throws(function () {
  68. mpath.get(Buffer, o);
  69. }, /Must be either string or array/);
  70. assert.doesNotThrow(function () {
  71. mpath.get('string', o);
  72. });
  73. assert.doesNotThrow(function () {
  74. mpath.get([], o);
  75. });
  76. done();
  77. })
  78. describe('without `special`', function(){
  79. it('works', function(done){
  80. assert.equal('jiro', mpath.get('name', o));
  81. assert.deepEqual(
  82. { second: { third: [3,{ name: 'aaron' }, 9] }}
  83. , mpath.get('first', o)
  84. );
  85. assert.deepEqual(
  86. { third: [3,{ name: 'aaron' }, 9] }
  87. , mpath.get('first.second', o)
  88. );
  89. assert.deepEqual(
  90. [3,{ name: 'aaron' }, 9]
  91. , mpath.get('first.second.third', o)
  92. );
  93. assert.deepEqual(
  94. 3
  95. , mpath.get('first.second.third.0', o)
  96. );
  97. assert.deepEqual(
  98. 9
  99. , mpath.get('first.second.third.2', o)
  100. );
  101. assert.deepEqual(
  102. { name: 'aaron' }
  103. , mpath.get('first.second.third.1', o)
  104. );
  105. assert.deepEqual(
  106. 'aaron'
  107. , mpath.get('first.second.third.1.name', o)
  108. );
  109. assert.deepEqual([
  110. { name: 'one' }
  111. , { name: 'two', _doc: { name: '2' }}
  112. , { name: 'three'
  113. , comments: [{},{ comments: [{val: 'twoo'}]}]
  114. , _doc: { name: '3', comments: [{},{ _doc: { comments: [{ val: 2 }] }}]}}],
  115. mpath.get('comments', o));
  116. assert.deepEqual({ name: 'one' }, mpath.get('comments.0', o));
  117. assert.deepEqual('one', mpath.get('comments.0.name', o));
  118. assert.deepEqual('two', mpath.get('comments.1.name', o));
  119. assert.deepEqual('three', mpath.get('comments.2.name', o));
  120. assert.deepEqual([{},{ comments: [{val: 'twoo'}]}]
  121. , mpath.get('comments.2.comments', o));
  122. assert.deepEqual({ comments: [{val: 'twoo'}]}
  123. , mpath.get('comments.2.comments.1', o));
  124. assert.deepEqual('twoo', mpath.get('comments.2.comments.1.comments.0.val', o));
  125. done();
  126. })
  127. it('handles array.property dot-notation', function(done){
  128. assert.deepEqual(
  129. ['one', 'two', 'three']
  130. , mpath.get('comments.name', o)
  131. );
  132. done();
  133. })
  134. it('handles array.array notation', function(done){
  135. assert.deepEqual(
  136. [undefined, undefined, [{}, {comments:[{val:'twoo'}]}]]
  137. , mpath.get('comments.comments', o)
  138. );
  139. done();
  140. })
  141. it('handles prop.prop.prop.arrayProperty notation', function(done){
  142. assert.deepEqual(
  143. [undefined, 'aaron', undefined]
  144. , mpath.get('first.second.third.name', o)
  145. );
  146. assert.deepEqual(
  147. [1, 'aaron', 1]
  148. , mpath.get('first.second.third.name', o, function (v) {
  149. return undefined === v ? 1 : v;
  150. })
  151. );
  152. done();
  153. })
  154. it('handles array.prop.array', function(done){
  155. assert.deepEqual(
  156. [ [{x: {b: [4,6,8]}}, { y: 10} ]
  157. , [{x: {b: [1,2,3]}}, { x: {z: 10 }}, { x: {b: 'hi'}}]
  158. , [{x: {b: null }}, { x: { b: [null, 1]}}]
  159. , [{x: null }]
  160. , [{y: 3 }]
  161. , [3, 0, null]
  162. , undefined
  163. ]
  164. , mpath.get('array.o.array', o)
  165. );
  166. done();
  167. })
  168. it('handles array.prop.array.index', function(done){
  169. assert.deepEqual(
  170. [ {x: {b: [4,6,8]}}
  171. , {x: {b: [1,2,3]}}
  172. , {x: {b: null }}
  173. , {x: null }
  174. , {y: 3 }
  175. , 3
  176. , undefined
  177. ]
  178. , mpath.get('array.o.array.0', o)
  179. );
  180. done();
  181. })
  182. it('handles array.prop.array.index.prop', function(done){
  183. assert.deepEqual(
  184. [ {b: [4,6,8]}
  185. , {b: [1,2,3]}
  186. , {b: null }
  187. , null
  188. , undefined
  189. , undefined
  190. , undefined
  191. ]
  192. , mpath.get('array.o.array.0.x', o)
  193. );
  194. done();
  195. })
  196. it('handles array.prop.array.prop', function(done){
  197. assert.deepEqual(
  198. [ [undefined, 10 ]
  199. , [undefined, undefined, undefined]
  200. , [undefined, undefined]
  201. , [undefined]
  202. , [3]
  203. , [undefined, undefined, undefined]
  204. , undefined
  205. ]
  206. , mpath.get('array.o.array.y', o)
  207. );
  208. assert.deepEqual(
  209. [ [{b: [4,6,8]}, undefined]
  210. , [{b: [1,2,3]}, {z: 10 }, {b: 'hi'}]
  211. , [{b: null }, { b: [null, 1]}]
  212. , [null]
  213. , [undefined]
  214. , [undefined, undefined, undefined]
  215. , undefined
  216. ]
  217. , mpath.get('array.o.array.x', o)
  218. );
  219. done();
  220. })
  221. it('handles array.prop.array.prop.prop', function(done){
  222. assert.deepEqual(
  223. [ [[4,6,8], undefined]
  224. , [[1,2,3], undefined, 'hi']
  225. , [null, [null, 1]]
  226. , [null]
  227. , [undefined]
  228. , [undefined, undefined, undefined]
  229. , undefined
  230. ]
  231. , mpath.get('array.o.array.x.b', o)
  232. );
  233. done();
  234. })
  235. it('handles array.prop.array.prop.prop.index', function(done){
  236. assert.deepEqual(
  237. [ [6, undefined]
  238. , [2, undefined, 'i'] // undocumented feature (string indexing)
  239. , [null, 1]
  240. , [null]
  241. , [undefined]
  242. , [undefined, undefined, undefined]
  243. , undefined
  244. ]
  245. , mpath.get('array.o.array.x.b.1', o)
  246. );
  247. assert.deepEqual(
  248. [ [6, 0]
  249. , [2, 0, 'i'] // undocumented feature (string indexing)
  250. , [null, 1]
  251. , [null]
  252. , [0]
  253. , [0, 0, 0]
  254. , 0
  255. ]
  256. , mpath.get('array.o.array.x.b.1', o, function (v) {
  257. return undefined === v ? 0 : v;
  258. })
  259. );
  260. done();
  261. })
  262. it('handles array.index.prop.prop', function(done){
  263. assert.deepEqual(
  264. [{x: {b: [1,2,3]}}, { x: {z: 10 }}, { x: {b: 'hi'}}]
  265. , mpath.get('array.1.o.array', o)
  266. );
  267. assert.deepEqual(
  268. ['hi','hi','hi']
  269. , mpath.get('array.1.o.array', o, function (v) {
  270. if (Array.isArray(v)) {
  271. return v.map(function (val) {
  272. return 'hi';
  273. })
  274. }
  275. return v;
  276. })
  277. );
  278. done();
  279. })
  280. it('handles array.array.index', function(done){
  281. assert.deepEqual(
  282. [{ a: { c: 48 }}, undefined]
  283. , mpath.get('arr.arr.1', o)
  284. );
  285. assert.deepEqual(
  286. ['woot', undefined]
  287. , mpath.get('arr.arr.1', o, function (v) {
  288. if (v && v.a && v.a.c) return 'woot';
  289. return v;
  290. })
  291. );
  292. done();
  293. })
  294. it('handles array.array.index.prop', function(done){
  295. assert.deepEqual(
  296. [{ c: 48 }, 'woot']
  297. , mpath.get('arr.arr.1.a', o, function (v) {
  298. if (undefined === v) return 'woot';
  299. return v;
  300. })
  301. );
  302. assert.deepEqual(
  303. [{ c: 48 }, undefined]
  304. , mpath.get('arr.arr.1.a', o)
  305. );
  306. mpath.set('arr.arr.1.a', [{c:49},undefined], o)
  307. assert.deepEqual(
  308. [{ c: 49 }, undefined]
  309. , mpath.get('arr.arr.1.a', o)
  310. );
  311. mpath.set('arr.arr.1.a', [{c:48},undefined], o)
  312. done();
  313. })
  314. it('handles array.array.index.prop.prop', function(done){
  315. assert.deepEqual(
  316. [48, undefined]
  317. , mpath.get('arr.arr.1.a.c', o)
  318. );
  319. assert.deepEqual(
  320. [48, 'woot']
  321. , mpath.get('arr.arr.1.a.c', o, function (v) {
  322. if (undefined === v) return 'woot';
  323. return v;
  324. })
  325. );
  326. done();
  327. })
  328. })
  329. describe('with `special`', function(){
  330. describe('that is a string', function(){
  331. it('works', function(done){
  332. assert.equal('jiro', mpath.get('name', o, special));
  333. assert.deepEqual(
  334. { second: { third: [3,{ name: 'aaron' }, 9] }}
  335. , mpath.get('first', o, special)
  336. );
  337. assert.deepEqual(
  338. { third: [3,{ name: 'aaron' }, 9] }
  339. , mpath.get('first.second', o, special)
  340. );
  341. assert.deepEqual(
  342. [3,{ name: 'aaron' }, 9]
  343. , mpath.get('first.second.third', o, special)
  344. );
  345. assert.deepEqual(
  346. 3
  347. , mpath.get('first.second.third.0', o, special)
  348. );
  349. assert.deepEqual(
  350. 4
  351. , mpath.get('first.second.third.0', o, special, function (v) {
  352. return 3 === v ? 4 : v;
  353. })
  354. );
  355. assert.deepEqual(
  356. 9
  357. , mpath.get('first.second.third.2', o, special)
  358. );
  359. assert.deepEqual(
  360. { name: 'aaron' }
  361. , mpath.get('first.second.third.1', o, special)
  362. );
  363. assert.deepEqual(
  364. 'aaron'
  365. , mpath.get('first.second.third.1.name', o, special)
  366. );
  367. assert.deepEqual([
  368. { name: 'one' }
  369. , { name: 'two', _doc: { name: '2' }}
  370. , { name: 'three'
  371. , comments: [{},{ comments: [{val: 'twoo'}]}]
  372. , _doc: { name: '3', comments: [{},{ _doc: { comments: [{ val: 2 }] }}]}}],
  373. mpath.get('comments', o, special));
  374. assert.deepEqual({ name: 'one' }, mpath.get('comments.0', o, special));
  375. assert.deepEqual('one', mpath.get('comments.0.name', o, special));
  376. assert.deepEqual('2', mpath.get('comments.1.name', o, special));
  377. assert.deepEqual('3', mpath.get('comments.2.name', o, special));
  378. assert.deepEqual('nice', mpath.get('comments.2.name', o, special, function (v) {
  379. return '3' === v ? 'nice' : v;
  380. }));
  381. assert.deepEqual([{},{ _doc: { comments: [{ val: 2 }] }}]
  382. , mpath.get('comments.2.comments', o, special));
  383. assert.deepEqual({ _doc: { comments: [{val: 2}]}}
  384. , mpath.get('comments.2.comments.1', o, special));
  385. assert.deepEqual(2, mpath.get('comments.2.comments.1.comments.0.val', o, special));
  386. done();
  387. })
  388. it('handles array.property dot-notation', function(done){
  389. assert.deepEqual(
  390. ['one', '2', '3']
  391. , mpath.get('comments.name', o, special)
  392. );
  393. assert.deepEqual(
  394. ['one', 2, '3']
  395. , mpath.get('comments.name', o, special, function (v) {
  396. return '2' === v ? 2 : v
  397. })
  398. );
  399. done();
  400. })
  401. it('handles array.array notation', function(done){
  402. assert.deepEqual(
  403. [undefined, undefined, [{}, {_doc: { comments:[{val:2}]}}]]
  404. , mpath.get('comments.comments', o, special)
  405. );
  406. done();
  407. })
  408. it('handles array.array.index.array', function(done){
  409. assert.deepEqual(
  410. [undefined, undefined, [{val:2}]]
  411. , mpath.get('comments.comments.1.comments', o, special)
  412. );
  413. done();
  414. })
  415. it('handles array.array.index.array.prop', function(done){
  416. assert.deepEqual(
  417. [undefined, undefined, [2]]
  418. , mpath.get('comments.comments.1.comments.val', o, special)
  419. );
  420. assert.deepEqual(
  421. ['nil', 'nil', [2]]
  422. , mpath.get('comments.comments.1.comments.val', o, special, function (v) {
  423. return undefined === v ? 'nil' : v;
  424. })
  425. );
  426. done();
  427. })
  428. })
  429. describe('that is a function', function(){
  430. var special = function (obj, key) {
  431. return obj[key]
  432. }
  433. it('works', function(done){
  434. assert.equal('jiro', mpath.get('name', o, special));
  435. assert.deepEqual(
  436. { second: { third: [3,{ name: 'aaron' }, 9] }}
  437. , mpath.get('first', o, special)
  438. );
  439. assert.deepEqual(
  440. { third: [3,{ name: 'aaron' }, 9] }
  441. , mpath.get('first.second', o, special)
  442. );
  443. assert.deepEqual(
  444. [3,{ name: 'aaron' }, 9]
  445. , mpath.get('first.second.third', o, special)
  446. );
  447. assert.deepEqual(
  448. 3
  449. , mpath.get('first.second.third.0', o, special)
  450. );
  451. assert.deepEqual(
  452. 4
  453. , mpath.get('first.second.third.0', o, special, function (v) {
  454. return 3 === v ? 4 : v;
  455. })
  456. );
  457. assert.deepEqual(
  458. 9
  459. , mpath.get('first.second.third.2', o, special)
  460. );
  461. assert.deepEqual(
  462. { name: 'aaron' }
  463. , mpath.get('first.second.third.1', o, special)
  464. );
  465. assert.deepEqual(
  466. 'aaron'
  467. , mpath.get('first.second.third.1.name', o, special)
  468. );
  469. assert.deepEqual([
  470. { name: 'one' }
  471. , { name: 'two', _doc: { name: '2' }}
  472. , { name: 'three'
  473. , comments: [{},{ comments: [{val: 'twoo'}]}]
  474. , _doc: { name: '3', comments: [{},{ _doc: { comments: [{ val: 2 }] }}]}}],
  475. mpath.get('comments', o, special));
  476. assert.deepEqual({ name: 'one' }, mpath.get('comments.0', o, special));
  477. assert.deepEqual('one', mpath.get('comments.0.name', o, special));
  478. assert.deepEqual('two', mpath.get('comments.1.name', o, special));
  479. assert.deepEqual('three', mpath.get('comments.2.name', o, special));
  480. assert.deepEqual('nice', mpath.get('comments.2.name', o, special, function (v) {
  481. return 'three' === v ? 'nice' : v;
  482. }));
  483. assert.deepEqual([{},{ comments: [{ val: 'twoo' }] }]
  484. , mpath.get('comments.2.comments', o, special));
  485. assert.deepEqual({ comments: [{val: 'twoo'}]}
  486. , mpath.get('comments.2.comments.1', o, special));
  487. assert.deepEqual('twoo', mpath.get('comments.2.comments.1.comments.0.val', o, special));
  488. var overide = false;
  489. assert.deepEqual('twoo', mpath.get('comments.8.comments.1.comments.0.val', o, function (obj, path) {
  490. if (Array.isArray(obj) && 8 == path) {
  491. overide = true;
  492. return obj[2];
  493. }
  494. return obj[path];
  495. }));
  496. assert.ok(overide);
  497. done();
  498. })
  499. it('in combination with map', function(done){
  500. var special = function (obj, key) {
  501. if (Array.isArray(obj)) return obj[key];
  502. return obj.mpath;
  503. }
  504. var map = function (val) {
  505. return 'convert' == val
  506. ? 'mpath'
  507. : val;
  508. }
  509. var o = { mpath: [{ mpath: 'converse' }, { mpath: 'convert' }] }
  510. assert.equal('mpath', mpath.get('something.1.kewl', o, special, map));
  511. done();
  512. })
  513. })
  514. })
  515. })
  516. describe('set', function(){
  517. describe('without `special`', function(){
  518. var o = doc();
  519. it('works', function(done){
  520. mpath.set('name', 'a new val', o, function (v) {
  521. return 'a new val' === v ? 'changed' : v;
  522. });
  523. assert.deepEqual('changed', o.name);
  524. mpath.set('name', 'changed', o);
  525. assert.deepEqual('changed', o.name);
  526. mpath.set('first.second.third', [1,{name:'x'},9], o);
  527. assert.deepEqual([1,{name:'x'},9], o.first.second.third);
  528. mpath.set('first.second.third.1.name', 'y', o)
  529. assert.deepEqual([1,{name:'y'},9], o.first.second.third);
  530. mpath.set('comments.1.name', 'ttwwoo', o);
  531. assert.deepEqual({ name: 'ttwwoo', _doc: { name: '2' }}, o.comments[1]);
  532. mpath.set('comments.2.comments.1.comments.0.expand', 'added', o);
  533. assert.deepEqual(
  534. { val: 'twoo', expand: 'added'}
  535. , o.comments[2].comments[1].comments[0]);
  536. mpath.set('comments.2.comments.1.comments.2', 'added', o);
  537. assert.equal(3, o.comments[2].comments[1].comments.length);
  538. assert.deepEqual(
  539. { val: 'twoo', expand: 'added'}
  540. , o.comments[2].comments[1].comments[0]);
  541. assert.deepEqual(
  542. undefined
  543. , o.comments[2].comments[1].comments[1]);
  544. assert.deepEqual(
  545. 'added'
  546. , o.comments[2].comments[1].comments[2]);
  547. done();
  548. })
  549. describe('array.path', function(){
  550. describe('with single non-array value', function(){
  551. it('works', function(done){
  552. mpath.set('arr.yep', false, o, function (v) {
  553. return false === v ? true: v;
  554. });
  555. assert.deepEqual([
  556. { yep: true, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  557. , { yep: true }
  558. ], o.arr);
  559. mpath.set('arr.yep', false, o);
  560. assert.deepEqual([
  561. { yep: false, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  562. , { yep: false }
  563. ], o.arr);
  564. done();
  565. })
  566. })
  567. describe('with array of values', function(){
  568. it('that are equal in length', function(done){
  569. mpath.set('arr.yep', ['one',2], o, function (v) {
  570. return 'one' === v ? 1 : v;
  571. });
  572. assert.deepEqual([
  573. { yep: 1, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  574. , { yep: 2 }
  575. ], o.arr);
  576. mpath.set('arr.yep', ['one',2], o);
  577. assert.deepEqual([
  578. { yep: 'one', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  579. , { yep: 2 }
  580. ], o.arr);
  581. done();
  582. })
  583. it('that is less than length', function(done){
  584. mpath.set('arr.yep', [47], o, function (v) {
  585. return 47 === v ? 4 : v;
  586. });
  587. assert.deepEqual([
  588. { yep: 4, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  589. , { yep: 2 }
  590. ], o.arr);
  591. mpath.set('arr.yep', [47], o);
  592. assert.deepEqual([
  593. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  594. , { yep: 2 }
  595. ], o.arr);
  596. done();
  597. })
  598. it('that is greater than length', function(done){
  599. mpath.set('arr.yep', [5,6,7], o, function (v) {
  600. return 5 === v ? 'five' : v;
  601. });
  602. assert.deepEqual([
  603. { yep: 'five', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  604. , { yep: 6 }
  605. ], o.arr);
  606. mpath.set('arr.yep', [5,6,7], o);
  607. assert.deepEqual([
  608. { yep: 5, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  609. , { yep: 6 }
  610. ], o.arr);
  611. done();
  612. })
  613. })
  614. })
  615. describe('array.$.path', function(){
  616. describe('with single non-array value', function(){
  617. it('copies the value to each item in array', function(done){
  618. mpath.set('arr.$.yep', {xtra: 'double good'}, o, function (v) {
  619. return v && v.xtra ? 'hi' : v;
  620. });
  621. assert.deepEqual([
  622. { yep: 'hi', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  623. , { yep: 'hi'}
  624. ], o.arr);
  625. mpath.set('arr.$.yep', {xtra: 'double good'}, o);
  626. assert.deepEqual([
  627. { yep: {xtra:'double good'}, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  628. , { yep: {xtra:'double good'}}
  629. ], o.arr);
  630. done();
  631. })
  632. })
  633. describe('with array of values', function(){
  634. it('copies the value to each item in array', function(done){
  635. mpath.set('arr.$.yep', [15], o, function (v) {
  636. return v.length === 1 ? [] : v;
  637. });
  638. assert.deepEqual([
  639. { yep: [], arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  640. , { yep: []}
  641. ], o.arr);
  642. mpath.set('arr.$.yep', [15], o);
  643. assert.deepEqual([
  644. { yep: [15], arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  645. , { yep: [15]}
  646. ], o.arr);
  647. done();
  648. })
  649. })
  650. })
  651. describe('array.index.path', function(){
  652. it('works', function(done){
  653. mpath.set('arr.1.yep', 0, o, function (v) {
  654. return 0 === v ? 'zero' : v;
  655. });
  656. assert.deepEqual([
  657. { yep: [15] , arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  658. , { yep: 'zero' }
  659. ], o.arr);
  660. mpath.set('arr.1.yep', 0, o);
  661. assert.deepEqual([
  662. { yep: [15] , arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  663. , { yep: 0 }
  664. ], o.arr);
  665. done();
  666. })
  667. })
  668. describe('array.index.array.path', function(){
  669. it('with single value', function(done){
  670. mpath.set('arr.0.arr.e', 35, o, function (v) {
  671. return 35 === v ? 3 : v;
  672. });
  673. assert.deepEqual([
  674. { yep: [15], arr: [{ a: { b: 47 }, e: 3}, { a: { c: 48 }, e: 3}, { d: 'yep', e: 3 }] }
  675. , { yep: 0 }
  676. ], o.arr);
  677. mpath.set('arr.0.arr.e', 35, o);
  678. assert.deepEqual([
  679. { yep: [15], arr: [{ a: { b: 47 }, e: 35}, { a: { c: 48 }, e: 35}, { d: 'yep', e: 35 }] }
  680. , { yep: 0 }
  681. ], o.arr);
  682. done();
  683. })
  684. it('with array', function(done){
  685. mpath.set('arr.0.arr.e', ['a','b'], o, function (v) {
  686. return 'a' === v ? 'x' : v;
  687. });
  688. assert.deepEqual([
  689. { yep: [15], arr: [{ a: { b: 47 }, e: 'x'}, { a: { c: 48 }, e: 'b'}, { d: 'yep', e: 35 }] }
  690. , { yep: 0 }
  691. ], o.arr);
  692. mpath.set('arr.0.arr.e', ['a','b'], o);
  693. assert.deepEqual([
  694. { yep: [15], arr: [{ a: { b: 47 }, e: 'a'}, { a: { c: 48 }, e: 'b'}, { d: 'yep', e: 35 }] }
  695. , { yep: 0 }
  696. ], o.arr);
  697. done();
  698. })
  699. })
  700. describe('array.index.array.path.path', function(){
  701. it('with single value', function(done){
  702. mpath.set('arr.0.arr.a.b', 36, o, function (v) {
  703. return 36 === v ? 3 : v;
  704. });
  705. assert.deepEqual([
  706. { yep: [15], arr: [{ a: { b: 3 }, e: 'a'}, { a: { c: 48, b: 3 }, e: 'b'}, { d: 'yep', e: 35 }] }
  707. , { yep: 0 }
  708. ], o.arr);
  709. mpath.set('arr.0.arr.a.b', 36, o);
  710. assert.deepEqual([
  711. { yep: [15], arr: [{ a: { b: 36 }, e: 'a'}, { a: { c: 48, b: 36 }, e: 'b'}, { d: 'yep', e: 35 }] }
  712. , { yep: 0 }
  713. ], o.arr);
  714. done();
  715. })
  716. it('with array', function(done){
  717. mpath.set('arr.0.arr.a.b', [1,2,3,4], o, function (v) {
  718. return 2 === v ? 'two' : v;
  719. });
  720. assert.deepEqual([
  721. { yep: [15], arr: [{ a: { b: 1 }, e: 'a'}, { a: { c: 48, b: 'two' }, e: 'b'}, { d: 'yep', e: 35 }] }
  722. , { yep: 0 }
  723. ], o.arr);
  724. mpath.set('arr.0.arr.a.b', [1,2,3,4], o);
  725. assert.deepEqual([
  726. { yep: [15], arr: [{ a: { b: 1 }, e: 'a'}, { a: { c: 48, b: 2 }, e: 'b'}, { d: 'yep', e: 35 }] }
  727. , { yep: 0 }
  728. ], o.arr);
  729. done();
  730. })
  731. })
  732. describe('array.index.array.$.path.path', function(){
  733. it('with single value', function(done){
  734. mpath.set('arr.0.arr.$.a.b', '$', o, function (v) {
  735. return '$' === v ? 'dolla billz' : v;
  736. });
  737. assert.deepEqual([
  738. { yep: [15], arr: [{ a: { b: 'dolla billz' }, e: 'a'}, { a: { c: 48, b: 'dolla billz' }, e: 'b'}, { d: 'yep', e: 35 }] }
  739. , { yep: 0 }
  740. ], o.arr);
  741. mpath.set('arr.0.arr.$.a.b', '$', o);
  742. assert.deepEqual([
  743. { yep: [15], arr: [{ a: { b: '$' }, e: 'a'}, { a: { c: 48, b: '$' }, e: 'b'}, { d: 'yep', e: 35 }] }
  744. , { yep: 0 }
  745. ], o.arr);
  746. done();
  747. })
  748. it('with array', function(done){
  749. mpath.set('arr.0.arr.$.a.b', [1], o, function (v) {
  750. return Array.isArray(v) ? {} : v;
  751. });
  752. assert.deepEqual([
  753. { yep: [15], arr: [{ a: { b: {} }, e: 'a'}, { a: { c: 48, b: {} }, e: 'b'}, { d: 'yep', e: 35 }] }
  754. , { yep: 0 }
  755. ], o.arr);
  756. mpath.set('arr.0.arr.$.a.b', [1], o);
  757. assert.deepEqual([
  758. { yep: [15], arr: [{ a: { b: [1] }, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  759. , { yep: 0 }
  760. ], o.arr);
  761. done();
  762. })
  763. })
  764. describe('array.array.index.path', function(){
  765. it('with single value', function(done){
  766. mpath.set('arr.arr.0.a', 'single', o, function (v) {
  767. return 'single' === v ? 'double' : v;
  768. });
  769. assert.deepEqual([
  770. { yep: [15], arr: [{ a: 'double', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  771. , { yep: 0 }
  772. ], o.arr);
  773. mpath.set('arr.arr.0.a', 'single', o);
  774. assert.deepEqual([
  775. { yep: [15], arr: [{ a: 'single', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  776. , { yep: 0 }
  777. ], o.arr);
  778. done();
  779. })
  780. it('with array', function(done){
  781. mpath.set('arr.arr.0.a', [4,8,15,16,23,42], o, function (v) {
  782. return 4 === v ? 3 : v;
  783. });
  784. assert.deepEqual([
  785. { yep: [15], arr: [{ a: 3, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  786. , { yep: false }
  787. ], o.arr);
  788. mpath.set('arr.arr.0.a', [4,8,15,16,23,42], o);
  789. assert.deepEqual([
  790. { yep: [15], arr: [{ a: 4, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  791. , { yep: false }
  792. ], o.arr);
  793. done();
  794. })
  795. })
  796. describe('array.array.$.index.path', function(){
  797. it('with single value', function(done){
  798. mpath.set('arr.arr.$.0.a', 'singles', o, function (v) {
  799. return 0;
  800. });
  801. assert.deepEqual([
  802. { yep: [15], arr: [{ a: 0, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  803. , { yep: 0 }
  804. ], o.arr);
  805. mpath.set('arr.arr.$.0.a', 'singles', o);
  806. assert.deepEqual([
  807. { yep: [15], arr: [{ a: 'singles', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  808. , { yep: 0 }
  809. ], o.arr);
  810. mpath.set('$.arr.arr.0.a', 'single', o);
  811. assert.deepEqual([
  812. { yep: [15], arr: [{ a: 'single', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  813. , { yep: 0 }
  814. ], o.arr);
  815. done();
  816. })
  817. it('with array', function(done){
  818. mpath.set('arr.arr.$.0.a', [4,8,15,16,23,42], o, function (v) {
  819. return 'nope'
  820. });
  821. assert.deepEqual([
  822. { yep: [15], arr: [{ a: 'nope', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  823. , { yep: 0}
  824. ], o.arr);
  825. mpath.set('arr.arr.$.0.a', [4,8,15,16,23,42], o);
  826. assert.deepEqual([
  827. { yep: [15], arr: [{ a: [4,8,15,16,23,42], e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  828. , { yep: 0}
  829. ], o.arr);
  830. mpath.set('arr.$.arr.0.a', [4,8,15,16,23,42,108], o);
  831. assert.deepEqual([
  832. { yep: [15], arr: [{ a: [4,8,15,16,23,42,108], e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] }
  833. , { yep: 0}
  834. ], o.arr);
  835. done();
  836. })
  837. })
  838. describe('array.array.path.index', function(){
  839. it('with single value', function(done){
  840. mpath.set('arr.arr.a.7', 47, o, function (v) {
  841. return 1
  842. });
  843. assert.deepEqual([
  844. { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,1], e: 'a'}, { a: { c: 48, b: [1], '7': 1 }, e: 'b'}, { d: 'yep', e: 35 }] }
  845. , { yep: 0}
  846. ], o.arr);
  847. mpath.set('arr.arr.a.7', 47, o);
  848. assert.deepEqual([
  849. { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,47], e: 'a'}, { a: { c: 48, b: [1], '7': 47 }, e: 'b'}, { d: 'yep', e: 35 }] }
  850. , { yep: 0}
  851. ], o.arr);
  852. done();
  853. })
  854. it('with array', function(done){
  855. o.arr[1].arr = [{ a: [] }, { a: [] }, { a: null }];
  856. mpath.set('arr.arr.a.7', [[null,46], [undefined, 'woot']], o);
  857. var a1 = [];
  858. var a2 = [];
  859. a1[7] = undefined;
  860. a2[7] = 'woot';
  861. assert.deepEqual([
  862. { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,null], e: 'a'}, { a: { c: 48, b: [1], '7': 46 }, e: 'b'}, { d: 'yep', e: 35 }] }
  863. , { yep: 0, arr: [{a:a1},{a:a2},{a:null}] }
  864. ], o.arr);
  865. done();
  866. })
  867. })
  868. describe('handles array.array.path', function(){
  869. it('with single', function(done){
  870. o.arr[1].arr = [{},{}];
  871. assert.deepEqual([{},{}], o.arr[1].arr);
  872. o.arr.push({ arr: 'something else' });
  873. o.arr.push({ arr: ['something else'] });
  874. o.arr.push({ arr: [[]] });
  875. o.arr.push({ arr: [5] });
  876. var weird = [];
  877. weird.e = 'xmas';
  878. // test
  879. mpath.set('arr.arr.e', 47, o, function (v) {
  880. return 'xmas'
  881. });
  882. assert.deepEqual([
  883. { yep: [15], arr: [
  884. { a: [4,8,15,16,23,42,108,null], e: 'xmas'}
  885. , { a: { c: 48, b: [1], '7': 46 }, e: 'xmas'}
  886. , { d: 'yep', e: 'xmas' }
  887. ]
  888. }
  889. , { yep: 0, arr: [{e: 'xmas'}, {e:'xmas'}] }
  890. , { arr: 'something else' }
  891. , { arr: ['something else'] }
  892. , { arr: [weird] }
  893. , { arr: [5] }
  894. ]
  895. , o.arr);
  896. weird.e = 47;
  897. mpath.set('arr.arr.e', 47, o);
  898. assert.deepEqual([
  899. { yep: [15], arr: [
  900. { a: [4,8,15,16,23,42,108,null], e: 47}
  901. , { a: { c: 48, b: [1], '7': 46 }, e: 47}
  902. , { d: 'yep', e: 47 }
  903. ]
  904. }
  905. , { yep: 0, arr: [{e: 47}, {e:47}] }
  906. , { arr: 'something else' }
  907. , { arr: ['something else'] }
  908. , { arr: [weird] }
  909. , { arr: [5] }
  910. ]
  911. , o.arr);
  912. done();
  913. })
  914. it('with arrays', function(done){
  915. mpath.set('arr.arr.e', [[1,2,3],[4,5],null,[],[6], [7,8,9]], o, function (v) {
  916. return 10;
  917. });
  918. var weird = [];
  919. weird.e = 10;
  920. assert.deepEqual([
  921. { yep: [15], arr: [
  922. { a: [4,8,15,16,23,42,108,null], e: 10}
  923. , { a: { c: 48, b: [1], '7': 46 }, e: 10}
  924. , { d: 'yep', e: 10 }
  925. ]
  926. }
  927. , { yep: 0, arr: [{e: 10}, {e:10}] }
  928. , { arr: 'something else' }
  929. , { arr: ['something else'] }
  930. , { arr: [weird] }
  931. , { arr: [5] }
  932. ]
  933. , o.arr);
  934. mpath.set('arr.arr.e', [[1,2,3],[4,5],null,[],[6], [7,8,9]], o);
  935. weird.e = 6;
  936. assert.deepEqual([
  937. { yep: [15], arr: [
  938. { a: [4,8,15,16,23,42,108,null], e: 1}
  939. , { a: { c: 48, b: [1], '7': 46 }, e: 2}
  940. , { d: 'yep', e: 3 }
  941. ]
  942. }
  943. , { yep: 0, arr: [{e: 4}, {e:5}] }
  944. , { arr: 'something else' }
  945. , { arr: ['something else'] }
  946. , { arr: [weird] }
  947. , { arr: [5] }
  948. ]
  949. , o.arr);
  950. done();
  951. })
  952. })
  953. })
  954. describe('with `special`', function(){
  955. var o = doc();
  956. it('works', function(done){
  957. mpath.set('name', 'chan', o, special, function (v) {
  958. return 'hi';
  959. });
  960. assert.deepEqual('hi', o.name);
  961. mpath.set('name', 'changer', o, special);
  962. assert.deepEqual('changer', o.name);
  963. mpath.set('first.second.third', [1,{name:'y'},9], o, special);
  964. assert.deepEqual([1,{name:'y'},9], o.first.second.third);
  965. mpath.set('first.second.third.1.name', 'z', o, special)
  966. assert.deepEqual([1,{name:'z'},9], o.first.second.third);
  967. mpath.set('comments.1.name', 'ttwwoo', o, special);
  968. assert.deepEqual({ name: 'two', _doc: { name: 'ttwwoo' }}, o.comments[1]);
  969. mpath.set('comments.2.comments.1.comments.0.expander', 'adder', o, special, function (v) {
  970. return 'super'
  971. });
  972. assert.deepEqual(
  973. { val: 2, expander: 'super'}
  974. , o.comments[2]._doc.comments[1]._doc.comments[0]);
  975. mpath.set('comments.2.comments.1.comments.0.expander', 'adder', o, special);
  976. assert.deepEqual(
  977. { val: 2, expander: 'adder'}
  978. , o.comments[2]._doc.comments[1]._doc.comments[0]);
  979. mpath.set('comments.2.comments.1.comments.2', 'set', o, special);
  980. assert.equal(3, o.comments[2]._doc.comments[1]._doc.comments.length);
  981. assert.deepEqual(
  982. { val: 2, expander: 'adder'}
  983. , o.comments[2]._doc.comments[1]._doc.comments[0]);
  984. assert.deepEqual(
  985. undefined
  986. , o.comments[2]._doc.comments[1]._doc.comments[1]);
  987. assert.deepEqual(
  988. 'set'
  989. , o.comments[2]._doc.comments[1]._doc.comments[2]);
  990. done();
  991. })
  992. describe('array.path', function(){
  993. describe('with single non-array value', function(){
  994. it('works', function(done){
  995. o.arr[1]._doc = { special: true }
  996. mpath.set('arr.yep', false, o, special, function (v) {
  997. return 'yes';
  998. });
  999. assert.deepEqual([
  1000. { yep: 'yes', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1001. , { yep: true, _doc: { special: true, yep: 'yes'}}
  1002. ], o.arr);
  1003. mpath.set('arr.yep', false, o, special);
  1004. assert.deepEqual([
  1005. { yep: false, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1006. , { yep: true, _doc: { special: true, yep: false }}
  1007. ], o.arr);
  1008. done();
  1009. })
  1010. })
  1011. describe('with array of values', function(){
  1012. it('that are equal in length', function(done){
  1013. mpath.set('arr.yep', ['one',2], o, special, function (v) {
  1014. return 2 === v ? 20 : v;
  1015. });
  1016. assert.deepEqual([
  1017. { yep: 'one', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1018. , { yep: true, _doc: { special: true, yep: 20}}
  1019. ], o.arr);
  1020. mpath.set('arr.yep', ['one',2], o, special);
  1021. assert.deepEqual([
  1022. { yep: 'one', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1023. , { yep: true, _doc: { special: true, yep: 2}}
  1024. ], o.arr);
  1025. done();
  1026. })
  1027. it('that is less than length', function(done){
  1028. mpath.set('arr.yep', [47], o, special, function (v) {
  1029. return 80;
  1030. });
  1031. assert.deepEqual([
  1032. { yep: 80, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1033. , { yep: true, _doc: { special: true, yep: 2}}
  1034. ], o.arr);
  1035. mpath.set('arr.yep', [47], o, special);
  1036. assert.deepEqual([
  1037. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1038. , { yep: true, _doc: { special: true, yep: 2}}
  1039. ], o.arr);
  1040. // add _doc to first element
  1041. o.arr[0]._doc = { yep: 46, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] }
  1042. mpath.set('arr.yep', [20], o, special);
  1043. assert.deepEqual([
  1044. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }], _doc: { yep: 20, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1045. , { yep: true, _doc: { special: true, yep: 2}}
  1046. ], o.arr);
  1047. done();
  1048. })
  1049. it('that is greater than length', function(done){
  1050. mpath.set('arr.yep', [5,6,7], o, special, function () {
  1051. return 'x';
  1052. });
  1053. assert.deepEqual([
  1054. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }], _doc: { yep: 'x', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1055. , { yep: true, _doc: { special: true, yep: 'x'}}
  1056. ], o.arr);
  1057. mpath.set('arr.yep', [5,6,7], o, special);
  1058. assert.deepEqual([
  1059. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }], _doc: { yep: 5, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1060. , { yep: true, _doc: { special: true, yep: 6}}
  1061. ], o.arr);
  1062. done();
  1063. })
  1064. })
  1065. })
  1066. describe('array.$.path', function(){
  1067. describe('with single non-array value', function(){
  1068. it('copies the value to each item in array', function(done){
  1069. mpath.set('arr.$.yep', {xtra: 'double good'}, o, special, function (v) {
  1070. return 9;
  1071. });
  1072. assert.deepEqual([
  1073. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1074. , _doc: { yep: 9, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1075. , { yep: true, _doc: { special: true, yep: 9}}
  1076. ], o.arr);
  1077. mpath.set('arr.$.yep', {xtra: 'double good'}, o, special);
  1078. assert.deepEqual([
  1079. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1080. , _doc: { yep: {xtra:'double good'}, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1081. , { yep: true, _doc: { special: true, yep: {xtra:'double good'}}}
  1082. ], o.arr);
  1083. done();
  1084. })
  1085. })
  1086. describe('with array of values', function(){
  1087. it('copies the value to each item in array', function(done){
  1088. mpath.set('arr.$.yep', [15], o, special, function (v) {
  1089. return 'array'
  1090. });
  1091. assert.deepEqual([
  1092. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1093. , _doc: { yep: 'array', arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1094. , { yep: true, _doc: { special: true, yep: 'array'}}
  1095. ], o.arr);
  1096. mpath.set('arr.$.yep', [15], o, special);
  1097. assert.deepEqual([
  1098. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1099. , _doc: { yep: [15], arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1100. , { yep: true, _doc: { special: true, yep: [15]}}
  1101. ], o.arr);
  1102. done();
  1103. })
  1104. })
  1105. })
  1106. describe('array.index.path', function(){
  1107. it('works', function(done){
  1108. mpath.set('arr.1.yep', 0, o, special, function (v) {
  1109. return 1;
  1110. });
  1111. assert.deepEqual([
  1112. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1113. , _doc: { yep: [15], arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1114. , { yep: true, _doc: { special: true, yep: 1}}
  1115. ], o.arr);
  1116. mpath.set('arr.1.yep', 0, o, special);
  1117. assert.deepEqual([
  1118. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1119. , _doc: { yep: [15], arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }] } }
  1120. , { yep: true, _doc: { special: true, yep: 0}}
  1121. ], o.arr);
  1122. done();
  1123. })
  1124. })
  1125. describe('array.index.array.path', function(){
  1126. it('with single value', function(done){
  1127. mpath.set('arr.0.arr.e', 35, o, special, function (v) {
  1128. return 30
  1129. });
  1130. assert.deepEqual([
  1131. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1132. , _doc: { yep: [15], arr: [{ a: { b: 47 }, e: 30}, { a: { c: 48 }, e: 30}, { d: 'yep', e: 30 }] } }
  1133. , { yep: true, _doc: { special: true, yep: 0}}
  1134. ], o.arr);
  1135. mpath.set('arr.0.arr.e', 35, o, special);
  1136. assert.deepEqual([
  1137. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1138. , _doc: { yep: [15], arr: [{ a: { b: 47 }, e: 35}, { a: { c: 48 }, e: 35}, { d: 'yep', e: 35 }] } }
  1139. , { yep: true, _doc: { special: true, yep: 0}}
  1140. ], o.arr);
  1141. done();
  1142. })
  1143. it('with array', function(done){
  1144. mpath.set('arr.0.arr.e', ['a','b'], o, special, function (v) {
  1145. return 'a' === v ? 'A' : v;
  1146. });
  1147. assert.deepEqual([
  1148. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1149. , _doc: { yep: [15], arr: [{ a: { b: 47 }, e: 'A'}, { a: { c: 48 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1150. , { yep: true, _doc: { special: true, yep: 0}}
  1151. ], o.arr);
  1152. mpath.set('arr.0.arr.e', ['a','b'], o, special);
  1153. assert.deepEqual([
  1154. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1155. , _doc: { yep: [15], arr: [{ a: { b: 47 }, e: 'a'}, { a: { c: 48 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1156. , { yep: true, _doc: { special: true, yep: 0}}
  1157. ], o.arr);
  1158. done();
  1159. })
  1160. })
  1161. describe('array.index.array.path.path', function(){
  1162. it('with single value', function(done){
  1163. mpath.set('arr.0.arr.a.b', 36, o, special, function (v) {
  1164. return 20
  1165. });
  1166. assert.deepEqual([
  1167. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1168. , _doc: { yep: [15], arr: [{ a: { b: 20 }, e: 'a'}, { a: { c: 48, b: 20 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1169. , { yep: true, _doc: { special: true, yep: 0}}
  1170. ], o.arr);
  1171. mpath.set('arr.0.arr.a.b', 36, o, special);
  1172. assert.deepEqual([
  1173. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1174. , _doc: { yep: [15], arr: [{ a: { b: 36 }, e: 'a'}, { a: { c: 48, b: 36 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1175. , { yep: true, _doc: { special: true, yep: 0}}
  1176. ], o.arr);
  1177. done();
  1178. })
  1179. it('with array', function(done){
  1180. mpath.set('arr.0.arr.a.b', [1,2,3,4], o, special, function (v) {
  1181. return v*2;
  1182. });
  1183. assert.deepEqual([
  1184. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1185. , _doc: { yep: [15], arr: [{ a: { b: 2 }, e: 'a'}, { a: { c: 48, b: 4 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1186. , { yep: true, _doc: { special: true, yep: 0}}
  1187. ], o.arr);
  1188. mpath.set('arr.0.arr.a.b', [1,2,3,4], o, special);
  1189. assert.deepEqual([
  1190. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1191. , _doc: { yep: [15], arr: [{ a: { b: 1 }, e: 'a'}, { a: { c: 48, b: 2 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1192. , { yep: true, _doc: { special: true, yep: 0}}
  1193. ], o.arr);
  1194. done();
  1195. })
  1196. })
  1197. describe('array.index.array.$.path.path', function(){
  1198. it('with single value', function(done){
  1199. mpath.set('arr.0.arr.$.a.b', '$', o, special, function (v) {
  1200. return 'dollaz'
  1201. });
  1202. assert.deepEqual([
  1203. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1204. , _doc: { yep: [15], arr: [{ a: { b: 'dollaz' }, e: 'a'}, { a: { c: 48, b: 'dollaz' }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1205. , { yep: true, _doc: { special: true, yep: 0}}
  1206. ], o.arr);
  1207. mpath.set('arr.0.arr.$.a.b', '$', o, special);
  1208. assert.deepEqual([
  1209. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1210. , _doc: { yep: [15], arr: [{ a: { b: '$' }, e: 'a'}, { a: { c: 48, b: '$' }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1211. , { yep: true, _doc: { special: true, yep: 0}}
  1212. ], o.arr);
  1213. done();
  1214. })
  1215. it('with array', function(done){
  1216. mpath.set('arr.0.arr.$.a.b', [1], o, special, function (v) {
  1217. return {};
  1218. });
  1219. assert.deepEqual([
  1220. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1221. , _doc: { yep: [15], arr: [{ a: { b: {} }, e: 'a'}, { a: { c: 48, b: {} }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1222. , { yep: true, _doc: { special: true, yep: 0}}
  1223. ], o.arr);
  1224. mpath.set('arr.0.arr.$.a.b', [1], o, special);
  1225. assert.deepEqual([
  1226. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1227. , _doc: { yep: [15], arr: [{ a: { b: [1] }, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1228. , { yep: true, _doc: { special: true, yep: 0}}
  1229. ], o.arr);
  1230. done();
  1231. })
  1232. })
  1233. describe('array.array.index.path', function(){
  1234. it('with single value', function(done){
  1235. mpath.set('arr.arr.0.a', 'single', o, special, function (v) {
  1236. return 88;
  1237. });
  1238. assert.deepEqual([
  1239. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1240. , _doc: { yep: [15], arr: [{ a: 88, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1241. , { yep: true, _doc: { special: true, yep: 0}}
  1242. ], o.arr);
  1243. mpath.set('arr.arr.0.a', 'single', o, special);
  1244. assert.deepEqual([
  1245. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1246. , _doc: { yep: [15], arr: [{ a: 'single', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1247. , { yep: true, _doc: { special: true, yep: 0}}
  1248. ], o.arr);
  1249. done();
  1250. })
  1251. it('with array', function(done){
  1252. mpath.set('arr.arr.0.a', [4,8,15,16,23,42], o, special, function (v) {
  1253. return v*2;
  1254. });
  1255. assert.deepEqual([
  1256. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1257. , _doc: { yep: [15], arr: [{ a: 8, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1258. , { yep: true, _doc: { special: true, yep: 0}}
  1259. ], o.arr);
  1260. mpath.set('arr.arr.0.a', [4,8,15,16,23,42], o, special);
  1261. assert.deepEqual([
  1262. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1263. , _doc: { yep: [15], arr: [{ a: 4, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1264. , { yep: true, _doc: { special: true, yep: 0}}
  1265. ], o.arr);
  1266. done();
  1267. })
  1268. })
  1269. describe('array.array.$.index.path', function(){
  1270. it('with single value', function(done){
  1271. mpath.set('arr.arr.$.0.a', 'singles', o, special, function (v) {
  1272. return v.toUpperCase();
  1273. });
  1274. assert.deepEqual([
  1275. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1276. , _doc: { yep: [15], arr: [{ a: 'SINGLES', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1277. , { yep: true, _doc: { special: true, yep: 0}}
  1278. ], o.arr);
  1279. mpath.set('arr.arr.$.0.a', 'singles', o, special);
  1280. assert.deepEqual([
  1281. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1282. , _doc: { yep: [15], arr: [{ a: 'singles', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1283. , { yep: true, _doc: { special: true, yep: 0}}
  1284. ], o.arr);
  1285. mpath.set('$.arr.arr.0.a', 'single', o, special);
  1286. assert.deepEqual([
  1287. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1288. , _doc: { yep: [15], arr: [{ a: 'single', e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1289. , { yep: true, _doc: { special: true, yep: 0}}
  1290. ], o.arr);
  1291. done();
  1292. })
  1293. it('with array', function(done){
  1294. mpath.set('arr.arr.$.0.a', [4,8,15,16,23,42], o, special, function (v) {
  1295. return Array
  1296. });
  1297. assert.deepEqual([
  1298. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1299. , _doc: { yep: [15], arr: [{ a: Array, e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1300. , { yep: true, _doc: { special: true, yep: 0}}
  1301. ], o.arr);
  1302. mpath.set('arr.arr.$.0.a', [4,8,15,16,23,42], o, special);
  1303. assert.deepEqual([
  1304. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1305. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42], e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1306. , { yep: true, _doc: { special: true, yep: 0}}
  1307. ], o.arr);
  1308. mpath.set('arr.$.arr.0.a', [4,8,15,16,23,42,108], o, special);
  1309. assert.deepEqual([
  1310. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1311. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42,108], e: 'a'}, { a: { c: 48, b: [1] }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1312. , { yep: true, _doc: { special: true, yep: 0}}
  1313. ], o.arr);
  1314. done();
  1315. })
  1316. })
  1317. describe('array.array.path.index', function(){
  1318. it('with single value', function(done){
  1319. mpath.set('arr.arr.a.7', 47, o, special, function (v) {
  1320. return Object;
  1321. });
  1322. assert.deepEqual([
  1323. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1324. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,Object], e: 'a'}, { a: { c: 48, b: [1], '7': Object }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1325. , { yep: true, _doc: { special: true, yep: 0}}
  1326. ], o.arr);
  1327. mpath.set('arr.arr.a.7', 47, o, special);
  1328. assert.deepEqual([
  1329. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1330. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,47], e: 'a'}, { a: { c: 48, b: [1], '7': 47 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1331. , { yep: true, _doc: { special: true, yep: 0}}
  1332. ], o.arr);
  1333. done();
  1334. })
  1335. it('with array', function(done){
  1336. o.arr[1]._doc.arr = [{ a: [] }, { a: [] }, { a: null }];
  1337. mpath.set('arr.arr.a.7', [[null,46], [undefined, 'woot']], o, special, function (v) {
  1338. return undefined === v ? 'nope' : v;
  1339. });
  1340. var a1 = [];
  1341. var a2 = [];
  1342. a1[7] = 'nope';
  1343. a2[7] = 'woot';
  1344. assert.deepEqual([
  1345. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1346. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,null], e: 'a'}, { a: { c: 48, b: [1], '7': 46 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1347. , { yep: true, _doc: { arr: [{a:a1},{a:a2},{a:null}], special: true, yep: 0}}
  1348. ], o.arr);
  1349. mpath.set('arr.arr.a.7', [[null,46], [undefined, 'woot']], o, special);
  1350. a1[7] = undefined;
  1351. assert.deepEqual([
  1352. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1353. , _doc: { yep: [15], arr: [{ a: [4,8,15,16,23,42,108,null], e: 'a'}, { a: { c: 48, b: [1], '7': 46 }, e: 'b'}, { d: 'yep', e: 35 }] } }
  1354. , { yep: true, _doc: { arr: [{a:a1},{a:a2},{a:null}], special: true, yep: 0}}
  1355. ], o.arr);
  1356. done();
  1357. })
  1358. })
  1359. describe('handles array.array.path', function(){
  1360. it('with single', function(done){
  1361. o.arr[1]._doc.arr = [{},{}];
  1362. assert.deepEqual([{},{}], o.arr[1]._doc.arr);
  1363. o.arr.push({ _doc: { arr: 'something else' }});
  1364. o.arr.push({ _doc: { arr: ['something else'] }});
  1365. o.arr.push({ _doc: { arr: [[]] }});
  1366. o.arr.push({ _doc: { arr: [5] }});
  1367. // test
  1368. mpath.set('arr.arr.e', 47, o, special);
  1369. var weird = [];
  1370. weird.e = 47;
  1371. assert.deepEqual([
  1372. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1373. , _doc: {
  1374. yep: [15]
  1375. , arr: [
  1376. { a: [4,8,15,16,23,42,108,null], e: 47}
  1377. , { a: { c: 48, b: [1], '7': 46 }, e: 47}
  1378. , { d: 'yep', e: 47 }
  1379. ]
  1380. }
  1381. }
  1382. , { yep: true
  1383. , _doc: {
  1384. arr: [
  1385. {e:47}
  1386. , {e:47}
  1387. ]
  1388. , special: true
  1389. , yep: 0
  1390. }
  1391. }
  1392. , { _doc: { arr: 'something else' }}
  1393. , { _doc: { arr: ['something else'] }}
  1394. , { _doc: { arr: [weird] }}
  1395. , { _doc: { arr: [5] }}
  1396. ]
  1397. , o.arr);
  1398. done();
  1399. })
  1400. it('with arrays', function(done){
  1401. mpath.set('arr.arr.e', [[1,2,3],[4,5],null,[],[6], [7,8,9]], o, special);
  1402. var weird = [];
  1403. weird.e = 6;
  1404. assert.deepEqual([
  1405. { yep: 47, arr: [{ a: { b: 47 }}, { a: { c: 48 }}, { d: 'yep' }]
  1406. , _doc: {
  1407. yep: [15]
  1408. , arr: [
  1409. { a: [4,8,15,16,23,42,108,null], e: 1}
  1410. , { a: { c: 48, b: [1], '7': 46 }, e: 2}
  1411. , { d: 'yep', e: 3 }
  1412. ]
  1413. }
  1414. }
  1415. , { yep: true
  1416. , _doc: {
  1417. arr: [
  1418. {e:4}
  1419. , {e:5}
  1420. ]
  1421. , special: true
  1422. , yep: 0
  1423. }
  1424. }
  1425. , { _doc: { arr: 'something else' }}
  1426. , { _doc: { arr: ['something else'] }}
  1427. , { _doc: { arr: [weird] }}
  1428. , { _doc: { arr: [5] }}
  1429. ]
  1430. , o.arr);
  1431. done();
  1432. })
  1433. })
  1434. describe('that is a function', function(){
  1435. describe('without map', function(){
  1436. it('works on array value', function(done){
  1437. var o = { hello: { world: [{ how: 'are' }, { you: '?' }] }};
  1438. var special = function (obj, key, val) {
  1439. if (val) {
  1440. obj[key] = val;
  1441. } else {
  1442. return 'thing' == key
  1443. ? obj.world
  1444. : obj[key]
  1445. }
  1446. }
  1447. mpath.set('hello.thing.how', 'arrrr', o, special);
  1448. assert.deepEqual(o, { hello: { world: [{ how: 'arrrr' }, { you: '?', how: 'arrrr' }] }});
  1449. done();
  1450. })
  1451. it('works on non-array value', function(done){
  1452. var o = { hello: { world: { how: 'are you' }}};
  1453. var special = function (obj, key, val) {
  1454. if (val) {
  1455. obj[key] = val;
  1456. } else {
  1457. return 'thing' == key
  1458. ? obj.world
  1459. : obj[key]
  1460. }
  1461. }
  1462. mpath.set('hello.thing.how', 'RU', o, special);
  1463. assert.deepEqual(o, { hello: { world: { how: 'RU' }}});
  1464. done();
  1465. })
  1466. })
  1467. it('works with map', function(done){
  1468. var o = { hello: { world: [{ how: 'are' }, { you: '?' }] }};
  1469. var special = function (obj, key, val) {
  1470. if (val) {
  1471. obj[key] = val;
  1472. } else {
  1473. return 'thing' == key
  1474. ? obj.world
  1475. : obj[key]
  1476. }
  1477. }
  1478. var map = function (val) {
  1479. return 'convert' == val
  1480. ? 'ºº'
  1481. : val
  1482. }
  1483. mpath.set('hello.thing.how', 'convert', o, special, map);
  1484. assert.deepEqual(o, { hello: { world: [{ how: 'ºº' }, { you: '?', how: 'ºº' }] }});
  1485. done();
  1486. })
  1487. })
  1488. })
  1489. describe('get/set integration', function(){
  1490. var o = doc();
  1491. it('works', function(done){
  1492. var vals = mpath.get('array.o.array.x.b', o);
  1493. vals[0][0][2] = 10;
  1494. vals[1][0][1] = 0;
  1495. vals[1][1] = 'Rambaldi';
  1496. vals[1][2] = [12,14];
  1497. vals[2] = [{changed:true}, [null, ['changed','to','array']]];
  1498. mpath.set('array.o.array.x.b', vals, o);
  1499. var t = [
  1500. { o: { array: [{x: {b: [4,6,10]}}, { y: 10} ] }}
  1501. , { o: { array: [{x: {b: [1,0,3]}}, { x: {b:'Rambaldi',z: 10 }}, { x: {b: [12,14]}}] }}
  1502. , { o: { array: [{x: {b: {changed:true}}}, { x: { b: [null, ['changed','to','array']]}}]}}
  1503. , { o: { array: [{x: null }] }}
  1504. , { o: { array: [{y: 3 }] }}
  1505. , { o: { array: [3, 0, null] }}
  1506. , { o: { name: 'ha' }}
  1507. ];
  1508. assert.deepEqual(t, o.array);
  1509. done();
  1510. })
  1511. it('array.prop', function(done){
  1512. mpath.set('comments.name', ['this', 'was', 'changed'], o);
  1513. assert.deepEqual([
  1514. { name: 'this' }
  1515. , { name: 'was', _doc: { name: '2' }}
  1516. , { name: 'changed'
  1517. , comments: [{},{ comments: [{val: 'twoo'}]}]
  1518. , _doc: { name: '3', comments: [{},{ _doc: { comments: [{ val: 2 }] }}] }}
  1519. ], o.comments);
  1520. mpath.set('comments.name', ['also', 'changed', 'this'], o, special);
  1521. assert.deepEqual([
  1522. { name: 'also' }
  1523. , { name: 'was', _doc: { name: 'changed' }}
  1524. , { name: 'changed'
  1525. , comments: [{},{ comments: [{val: 'twoo'}]}]
  1526. , _doc: { name: 'this', comments: [{},{ _doc: { comments: [{ val: 2 }] }}] }}
  1527. ], o.comments);
  1528. done();
  1529. })
  1530. })
  1531. describe('multiple $ use', function(){
  1532. var o = doc();
  1533. it('is ok', function(done){
  1534. assert.doesNotThrow(function () {
  1535. mpath.set('arr.$.arr.$.a', 35, o);
  1536. });
  1537. done();
  1538. })
  1539. })
  1540. it('has', function(done) {
  1541. assert.ok(mpath.has('a', { a: 1 }));
  1542. assert.ok(mpath.has('a', { a: undefined }));
  1543. assert.ok(!mpath.has('a', {}));
  1544. assert.ok(!mpath.has('a', null));
  1545. assert.ok(mpath.has('a.b', { a: { b: 1 } }));
  1546. assert.ok(mpath.has('a.b', { a: { b: undefined } }));
  1547. assert.ok(!mpath.has('a.b', { a: 1 }));
  1548. assert.ok(!mpath.has('a.b', { a: null }));
  1549. done();
  1550. });
  1551. it('underneath a map', function(done) {
  1552. assert.equal(mpath.get('a.b', { a: new Map([['b', 1]]) }), 1);
  1553. var m = new Map([['b', 1]]);
  1554. var obj = { a: m };
  1555. mpath.set('a.c', 2, obj);
  1556. assert.equal(m.get('c'), 2);
  1557. done();
  1558. });
  1559. it('unset', function(done) {
  1560. var o = { a: 1 };
  1561. mpath.unset('a', o);
  1562. assert.deepEqual(o, {});
  1563. o = { a: { b: 1 } };
  1564. mpath.unset('a.b', o);
  1565. assert.deepEqual(o, { a: {} });
  1566. o = { a: null };
  1567. mpath.unset('a.b', o);
  1568. assert.deepEqual(o, { a: null });
  1569. done();
  1570. });
  1571. it('ignores setting a nested path that doesnt exist', function(done){
  1572. var o = doc();
  1573. assert.doesNotThrow(function(){
  1574. mpath.set('thing.that.is.new', 10, o);
  1575. })
  1576. done();
  1577. })
  1578. })
  1579. })