describe('sakuraCrowd.jsonId.refToObj', function() { | |
it("参照オブジェクトを参照先オブジェクトに変換する", function() { | |
var target = [ | |
{"id":"id1", "value":10}, | |
{"$ref":"id1"} | |
]; | |
sakuraCrowd.jsonId.refToObj(target); | |
expect(target.length).toEqual(2); | |
expect(target[0]).toBe(target[1]); | |
}); | |
it("循環参照を検出したら該当する JsonPath を返して警告する", function() { | |
var target = [ | |
{"id":"id1", "value":10, "other":{"$ref":"id2"}}, | |
{"id":"id2", "other":{"$ref":"id1"}} | |
]; | |
var path = "$[0].other.other"; | |
expect(sakuraCrowd.jsonId.refToObj.bind(null, target)).toThrow("循環参照です。" + path); | |
}); | |
it("指定したオブジェクトの下位の場所から変換する", function() { | |
var target = [ | |
{"id":"id1", "value":10, "other":{"$ref":"id2"}}, | |
{"id":"id2", | |
"other":[ | |
{"id":"id3", "value":30}, | |
{"$ref":"id3"} | |
] | |
}, | |
]; | |
var target2 = [ | |
{"id":"id1", "value":10, "other":{"$ref":"id2"}}, | |
{"id":"id2", | |
"other":[ | |
{"id":"id3", "value":30}, | |
{"$ref":"id3"} | |
] | |
}, | |
]; | |
target2[1].other[1] = target2[1].other[0]; | |
expect(sakuraCrowd.jsonId.refToObj.bind(null, target, "$[1]")).toEqual(target2); | |
}); | |
it("指定したオブジェクトの下位の場所から変換する。それより上位のオブジェクトの循環参照を検知する", function() { | |
var target = [ | |
{"id":"id1", "value":10}, | |
{"id":"id2", | |
"other":[ | |
{"id":"id3", "value":30}, | |
{"$ref":"id2"} | |
] | |
}, | |
]; | |
path = "$[1].other[1]"; | |
expect(sakuraCrowd.jsonId.refToObj.bind(null, target, "$[1].other")).toThrow("循環参照です。" + path); | |
}); | |
it("指定したオブジェクトの下位の場所から変換する。 info に設定した外部の参照にも対応する。", function() { | |
var target = [ | |
{"id":"id1", "value":10}, | |
{"id":"id2", | |
"other":[ | |
{"id":"id3", "value":30}, | |
{"$ref":"id1"} | |
] | |
}, | |
]; | |
var target2 = [ | |
{"id":"id1", "value":10}, | |
{"id":"id2", | |
"other":[ | |
{"id":"id3", "value":30}, | |
{"$ref":"id1"} | |
] | |
}, | |
]; | |
target2[1].other[1] = target[0]; | |
expect(sakuraCrowd.jsonId.refToObj.bind(null, target, "$[1].other")).toEqual(target2); | |
}); | |
}); |
JSON のオブジェクトを ID でリンクする(3) - SakuraCrowd’s blog の続きです。前回まではテストケースをクリアする実装までいけていたのですが、今回はテストケースを書いたまでで、それを満たす実装は勉強中です。
いつもどおり、仕様の説明は gist のコメントに書いてあります。
簡単に言うと、複数のオブジェクトが集まっている構造の中で一部だけを処理できるようにしました。
それだけならば、その一部のオブジェクトを引数にくわせりゃいいじゃんと思うんですが、 ID からデータに置換するには JSONPath の絶対パスを利用しています。
そのためルートが変わってしまうと ID からデータに置換できなくなってしまうのです。
JSONPath とか XPath とかパスもいろいろあるね(`・ω・´)
そんなかんなで jsonPath を使って処理を開始するノード要素を取得する処理を追加しました。
最初にはまったのはルートは "$" だから jsonPath.eval(target, "$") とすれば target の値が返されると思ったところでした。
実際は空の配列が返って来ます。
XPath の仕様などの説明を読んだところ、どうやらルートノードとルート要素というものは別物らしいです。
そして JSONPath でルート要素を表す場合は "$.*" とします。
これで target の値が取得できました。
eval だからって、えばる(eval)な!←いってみたかっただけです><
しかし、今度は ret = jsonPath.eval(target, "$.*") が ret == target ですが ret !== target になっています!
これでは、共通のオブジェクトへリンクする処理ではなく、同じ値を持つ別のオブジェクトへのリンクとなってしまいます。
どうすればいいのかなー。
現状はそんなところです。
コメント
コメントを投稿