/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ _("Make sure Collection can correctly incrementally parse GET requests"); Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/service.js"); function run_test() { let base = "http://fake/"; let coll = new Collection("http://fake/uri/", WBORecord, Service); let stream = { _data: "" }; let called, recCount, sum; _("Not-JSON, string payloads are strings"); called = false; stream._data = '{"id":"hello","payload":"world"}\n'; coll.recordHandler = function(rec) { called = true; _("Got record:", JSON.stringify(rec)); rec.collection = "uri"; // This would be done by an engine, so do it here. do_check_eq(rec.collection, "uri"); do_check_eq(rec.id, "hello"); do_check_eq(rec.uri(base).spec, "http://fake/uri/hello"); do_check_eq(rec.payload, "world"); }; coll._onProgress.call(stream); do_check_eq(stream._data, ''); do_check_true(called); _("\n"); _("Parse record with payload"); called = false; stream._data = '{"payload":"{\\"value\\":123}"}\n'; coll.recordHandler = function(rec) { called = true; _("Got record:", JSON.stringify(rec)); do_check_eq(rec.payload.value, 123); }; coll._onProgress.call(stream); do_check_eq(stream._data, ''); do_check_true(called); _("\n"); _("Parse multiple records in one go"); called = false; recCount = 0; sum = 0; stream._data = '{"id":"hundred","payload":"{\\"value\\":100}"}\n{"id":"ten","payload":"{\\"value\\":10}"}\n{"id":"one","payload":"{\\"value\\":1}"}\n'; coll.recordHandler = function(rec) { called = true; _("Got record:", JSON.stringify(rec)); recCount++; sum += rec.payload.value; _("Incremental status: count", recCount, "sum", sum); rec.collection = "uri"; switch (recCount) { case 1: do_check_eq(rec.id, "hundred"); do_check_eq(rec.uri(base).spec, "http://fake/uri/hundred"); do_check_eq(rec.payload.value, 100); do_check_eq(sum, 100); break; case 2: do_check_eq(rec.id, "ten"); do_check_eq(rec.uri(base).spec, "http://fake/uri/ten"); do_check_eq(rec.payload.value, 10); do_check_eq(sum, 110); break; case 3: do_check_eq(rec.id, "one"); do_check_eq(rec.uri(base).spec, "http://fake/uri/one"); do_check_eq(rec.payload.value, 1); do_check_eq(sum, 111); break; default: do_throw("unexpected number of record counts", recCount); break; } }; coll._onProgress.call(stream); do_check_eq(recCount, 3); do_check_eq(sum, 111); do_check_eq(stream._data, ''); do_check_true(called); _("\n"); _("Handle incremental data incoming"); called = false; recCount = 0; sum = 0; stream._data = '{"payl'; coll.recordHandler = function(rec) { called = true; do_throw("shouldn't have gotten a record.."); }; coll._onProgress.call(stream); _("shouldn't have gotten anything yet"); do_check_eq(recCount, 0); do_check_eq(sum, 0); _("leading array bracket should have been trimmed"); do_check_eq(stream._data, '{"payl'); do_check_false(called); _(); _("adding more data enough for one record.."); called = false; stream._data += 'oad":"{\\"value\\":100}"}\n'; coll.recordHandler = function(rec) { called = true; _("Got record:", JSON.stringify(rec)); recCount++; sum += rec.payload.value; }; coll._onProgress.call(stream); _("should have 1 record with sum 100"); do_check_eq(recCount, 1); do_check_eq(sum, 100); _("all data should have been consumed including trailing comma"); do_check_eq(stream._data, ''); do_check_true(called); _(); _("adding more data.."); called = false; stream._data += '{"payload":"{\\"value\\":10}"'; coll.recordHandler = function(rec) { called = true; do_throw("shouldn't have gotten a record.."); }; coll._onProgress.call(stream); _("should still have 1 record with sum 100"); do_check_eq(recCount, 1); do_check_eq(sum, 100); _("should almost have a record"); do_check_eq(stream._data, '{"payload":"{\\"value\\":10}"'); do_check_false(called); _(); _("add data for two records.."); called = false; stream._data += '}\n{"payload":"{\\"value\\":1}"}\n'; coll.recordHandler = function(rec) { called = true; _("Got record:", JSON.stringify(rec)); recCount++; sum += rec.payload.value; switch (recCount) { case 2: do_check_eq(rec.payload.value, 10); do_check_eq(sum, 110); break; case 3: do_check_eq(rec.payload.value, 1); do_check_eq(sum, 111); break; default: do_throw("unexpected number of record counts", recCount); break; } }; coll._onProgress.call(stream); _("should have gotten all 3 records with sum 111"); do_check_eq(recCount, 3); do_check_eq(sum, 111); _("should have consumed all data"); do_check_eq(stream._data, ''); do_check_true(called); _(); _("add no extra data"); called = false; stream._data += ''; coll.recordHandler = function(rec) { called = true; do_throw("shouldn't have gotten a record.."); }; coll._onProgress.call(stream); _("should still have 3 records with sum 111"); do_check_eq(recCount, 3); do_check_eq(sum, 111); _("should have consumed nothing but still have nothing"); do_check_eq(stream._data, ""); do_check_false(called); _("\n"); }