/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var { cal } = ChromeUtils.import("resource:///modules/calendar/calHashedArray.jsm"); var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs"); XPCOMUtils.defineLazyModuleGetters(this, { CalEvent: "resource:///modules/CalEvent.jsm", }); function run_test() { test_array_base(); test_array_sorted(); test_hashAccessor(); } /** * Helper function to create an item that has a sensible hash id, with the given * title identification. * * @param ident The title to identify the item. * @returns The created item. */ function hashedCreateItem(ident) { let item = new CalEvent(); item.calendar = { id: "test" }; item.id = cal.getUUID(); item.title = ident; return item; } /** * Comparator function to sort the items by their title * * @param a Object to compare. * @param b Object to compare with. * @returns 0, -1, or 1 (usual comptor meanings) */ function titleComptor(a, b) { if (a.title > b.title) { return 1; } else if (a.title < b.title) { return -1; } return 0; } /** * Checks if the hashed array accessor functions work for the status of the * items array. * * @param har The Hashed Array * @param testItems The array of test items * @param itemAccessor The accessor func to retrieve the items * @throws Exception If the arrays are not the same. */ function checkConsistancy(har, testItems, itemAccessor) { itemAccessor = itemAccessor || function (item) { return item; }; for (let idx in testItems) { let testItem = itemAccessor(testItems[idx]); equal(itemAccessor(har.itemByIndex(idx)).title, testItem.title); equal(itemAccessor(har.itemById(testItem.hashId)).title, testItem.title); equal(har.indexOf(testItems[idx]), idx); } } /** * Man, this function is really hard to keep general enough, I'm almost tempted * to duplicate the code. It checks if the remove and modify operations work for * the given hashed array. * * @param har The Hashed Array * @param testItems The js array with the items * @param postprocessFunc (optional) The function to call after each * operation, but before checking consistency. * @param itemAccessor (optional) The function to access the item for an * array element. * @param itemCreator (optional) Function to create a new item for the * array. */ function testRemoveModify(har, testItems, postprocessFunc, itemAccessor, itemCreator) { postprocessFunc = postprocessFunc || function (a, b) { return [a, b]; }; itemCreator = itemCreator || (title => hashedCreateItem(title)); itemAccessor = itemAccessor || function (item) { return item; }; // Now, delete the second item and check again har.removeById(itemAccessor(testItems[1]).hashId); testItems.splice(1, 1); [har, testItems] = postprocessFunc(har, testItems); checkConsistancy(har, testItems, itemAccessor); // Try the same by index har.removeByIndex(2); testItems.splice(2, 1); [har, testItems] = postprocessFunc(har, testItems); checkConsistancy(har, testItems, itemAccessor); // Try modifying an item let newInstance = itemCreator("z-changed"); itemAccessor(newInstance).id = itemAccessor(testItems[0]).id; testItems[0] = newInstance; har.modifyItem(newInstance); [har, testItems] = postprocessFunc(har, testItems); checkConsistancy(har, testItems, itemAccessor); } /** * Tests the basic cal.HashedArray */ function test_array_base() { let har, testItems; // Test normal additions har = new cal.HashedArray(); testItems = ["a", "b", "c", "d"].map(hashedCreateItem); testItems.forEach(har.addItem, har); checkConsistancy(har, testItems); testRemoveModify(har, testItems); // Test adding in batch mode har = new cal.HashedArray(); testItems = ["e", "f", "g", "h"].map(hashedCreateItem); har.startBatch(); testItems.forEach(har.addItem, har); har.endBatch(); checkConsistancy(har, testItems); testRemoveModify(har, testItems); } /** * Tests the sorted cal.SortedHashedArray */ function test_array_sorted() { let har, testItems, testItemsSorted; function sortedPostProcess(harParam, tiParam) { tiParam = tiParam.sort(titleComptor); return [harParam, tiParam]; } // Test normal additions har = new cal.SortedHashedArray(titleComptor); testItems = ["d", "c", "a", "b"].map(hashedCreateItem); testItemsSorted = testItems.sort(titleComptor); testItems.forEach(har.addItem, har); checkConsistancy(har, testItemsSorted); testRemoveModify(har, testItemsSorted, sortedPostProcess); // Test adding in batch mode har = new cal.SortedHashedArray(titleComptor); testItems = ["e", "f", "g", "h"].map(hashedCreateItem); testItemsSorted = testItems.sort(titleComptor); har.startBatch(); testItems.forEach(har.addItem, har); har.endBatch(); checkConsistancy(har, testItemsSorted); testRemoveModify(har, testItemsSorted, sortedPostProcess); } /** * Tests cal.SortedHashedArray with a custom hashAccessor. */ function test_hashAccessor() { let har, testItems, testItemsSorted; let comptor = (a, b) => titleComptor(a.item, b.item); har = new cal.SortedHashedArray(comptor); har.hashAccessor = function (obj) { return obj.item.hashId; }; function itemAccessor(obj) { if (!obj) { do_throw("WTF?"); } return obj.item; } function itemCreator(title) { return { item: hashedCreateItem(title) }; } function sortedPostProcess(harParam, tiParam) { tiParam = tiParam.sort(comptor); return [harParam, tiParam]; } testItems = ["d", "c", "a", "b"].map(itemCreator); testItemsSorted = testItems.sort(comptor); testItems.forEach(har.addItem, har); checkConsistancy(har, testItemsSorted, itemAccessor); testRemoveModify(har, testItemsSorted, sortedPostProcess, itemAccessor, itemCreator); }