--- a/devtools/client/webconsole/new-console-output/reducers/messages.js
+++ b/devtools/client/webconsole/new-console-output/reducers/messages.js
@@ -311,43 +311,46 @@ function limitTopLevelMessageCount(state
}
if (record.visibleMessages.length > visibleMessages.length) {
record.set("visibleMessages", visibleMessages);
}
const isInRemovedId = id => removedMessagesId.includes(id);
const mapHasRemovedIdKey = map => map.findKey((value, id) => isInRemovedId(id));
+ const objectHasRemovedIdKey = obj => Object.keys(obj).findIndex(isInRemovedId) !== -1;
const cleanUpCollection = map => removedMessagesId.forEach(id => map.remove(id));
+ const cleanUpList = list => list.filter(id => {
+ return isInRemovedId(id) === false;
+ });
const cleanUpObject = object => [...Object.entries(object)]
.reduce((res, [id, value]) => {
if (!isInRemovedId(id)) {
res[id] = value;
}
return res;
}, {});
record.set("messagesById", record.messagesById.withMutations(cleanUpCollection));
if (record.messagesUiById.find(isInRemovedId)) {
- record.set("messagesUiById", record.messagesUiById.withMutations(cleanUpCollection));
+ record.set("messagesUiById", cleanUpList(record.messagesUiById));
}
if (mapHasRemovedIdKey(record.messagesTableDataById)) {
record.set("messagesTableDataById",
record.messagesTableDataById.withMutations(cleanUpCollection));
}
if (mapHasRemovedIdKey(record.groupsById)) {
record.set("groupsById", record.groupsById.withMutations(cleanUpCollection));
}
-
- if (Object.keys(record.repeatById).includes(removedMessagesId)) {
+ if (objectHasRemovedIdKey(record.repeatById)) {
record.set("repeatById", cleanUpObject(record.repeatById));
}
- if (Object.keys(record.networkMessagesUpdateById).includes(removedMessagesId)) {
+ if (objectHasRemovedIdKey(record.networkMessagesUpdateById)) {
record.set("networkMessagesUpdateById",
cleanUpObject(record.networkMessagesUpdateById));
}
return record;
}
/**
--- a/devtools/client/webconsole/new-console-output/test/store/messages.test.js
+++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js
@@ -114,16 +114,17 @@ describe("Message reducer:", () => {
expect(messages.size).toBe(1);
expect(messages.first().parameters[0]).toBe("Console was cleared.");
});
it("clears the messages list in response to MESSAGES_CLEAR action", () => {
const { dispatch, getState } = setupStore([
"console.log('foobar', 'test')",
+ "console.log('foobar', 'test')",
"console.log(undefined)",
"console.table(['red', 'green', 'blue']);",
"console.group('bar')",
]);
dispatch(actions.messagesClear());
const state = getState();
@@ -131,16 +132,55 @@ describe("Message reducer:", () => {
expect(getVisibleMessages(state).length).toBe(0);
expect(getAllMessagesUiById(state).size).toBe(0);
expect(getAllGroupsById(state).size).toBe(0);
expect(getAllMessagesTableDataById(state).size).toBe(0);
expect(getCurrentGroup(state)).toBe(null);
expect(getAllRepeatById(state)).toEqual({});
});
+ it("cleans the repeatsById object when messages are pruned", () => {
+ const { dispatch, getState } = setupStore(
+ [
+ "console.log('foobar', 'test')",
+ "console.log('foobar', 'test')",
+ "console.log(undefined)",
+ "console.log(undefined)",
+ ],
+ null, {
+ logLimit: 2
+ }
+ );
+
+ // Check that we have the expected data.
+ let messages = getAllMessagesById(getState());
+ let repeats = getAllRepeatById(getState());
+ expect(Object.keys(repeats).length).toBe(2);
+ const lastMessageId = messages.last().id;
+
+ // This addition will prune the first message out of the store.
+ let packet = stubPackets.get("console.log('foobar', 'test')");
+ dispatch(actions.messageAdd(packet));
+
+ messages = getAllMessagesById(getState());
+ repeats = getAllRepeatById(getState());
+
+ // There should be only the data for the "undefined" message.
+ expect(Object.keys(repeats)).toEqual([lastMessageId]);
+ expect(Object.keys(repeats).length).toBe(1);
+ expect(repeats[lastMessageId]).toBe(2);
+
+ // This addition will prune the first message out of the store.
+ packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ // repeatById should now be empty.
+ expect(getAllRepeatById(getState())).toEqual({});
+ });
+
it("properly limits number of messages", () => {
const { dispatch, getState } = setupStore([]);
const logLimit = 1000;
const packet = clonePacket(stubPackets.get("console.log(undefined)"));
for (let i = 1; i <= logLimit + 2; i++) {
packet.message.arguments = [`message num ${i}`];
@@ -366,16 +406,53 @@ describe("Message reducer:", () => {
dispatch(actions.messageAdd(traceMessage));
dispatch(actions.messagesClear());
const messagesUi = getAllMessagesUiById(getState());
expect(messagesUi.size).toBe(0);
});
+ it("cleans the messages UI list when messages are pruned", () => {
+ const { dispatch, getState } = setupStore(
+ ["console.trace()", "console.log(undefined)", "console.trace()"],
+ null, {
+ logLimit: 3
+ }
+ );
+
+ // Check that we have the expected data.
+ let messages = getAllMessagesById(getState());
+ let messagesUi = getAllMessagesUiById(getState());
+ expect(messagesUi.size).toBe(2);
+ expect(messagesUi.first()).toBe(messages.first().id);
+ const lastMessageId = messages.last().id;
+ expect(messagesUi.last()).toBe(lastMessageId);
+
+ // This addition will prune the first message out of the store.
+ let packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ messages = getAllMessagesById(getState());
+ messagesUi = getAllMessagesUiById(getState());
+
+ // There should be only the id of the last console.trace message.
+ expect(messagesUi.size).toBe(1);
+ expect(messagesUi.first()).toBe(lastMessageId);
+
+ // These additions will prune the last console.trace message out of the store.
+ packet = stubPackets.get("console.log('foobar', 'test')");
+ dispatch(actions.messageAdd(packet));
+ packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ // messagesUiById should now be empty.
+ expect(getAllMessagesUiById(getState()).size).toBe(0);
+ });
+
it("opens console.group messages when they are added", () => {
const { dispatch, getState } = setupStore([]);
const message = stubPackets.get("console.group('bar')");
dispatch(actions.messageAdd(message));
const messages = getAllMessagesById(getState());
const messagesUi = getAllMessagesUiById(getState());
@@ -472,51 +549,210 @@ describe("Message reducer:", () => {
let groupsById = getAllGroupsById(getState());
expect(groupsById.size).toBe(2);
dispatch(actions.messagesClear());
groupsById = getAllGroupsById(getState());
expect(groupsById.size).toBe(0);
});
+
+ it("cleans the groupsById property when messages are pruned", () => {
+ const { dispatch, getState } = setupStore(
+ [
+ "console.group('bar')",
+ "console.group()",
+ "console.groupEnd()",
+ "console.groupEnd('bar')",
+ "console.group('bar')",
+ "console.groupEnd('bar')",
+ "console.log('foobar', 'test')",
+ ],
+ null, {
+ logLimit: 3
+ }
+ );
+
+ // Check that we have the expected data.
+ let groupsById = getAllGroupsById(getState());
+ expect(groupsById.size).toBe(3);
+
+ // This addition will prune the first group (and its child group) out of the store.
+ let packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ groupsById = getAllGroupsById(getState());
+
+ // There should be only the id of the last console.trace message.
+ expect(groupsById.size).toBe(1);
+
+ // This additions will prune the last group message out of the store.
+ packet = stubPackets.get("console.log('foobar', 'test')");
+ dispatch(actions.messageAdd(packet));
+
+ // groupsById should now be empty.
+ expect(getAllGroupsById(getState()).size).toBe(0);
+ });
});
describe("networkMessagesUpdateById", () => {
it("adds the network update message when network update action is called", () => {
- const { dispatch, getState } = setupStore([
- "GET request",
- "XHR GET request"
- ]);
+ const { dispatch, getState } = setupStore([]);
+
+ let packet = clonePacket(stubPackets.get("GET request"));
+ let updatePacket = clonePacket(stubPackets.get("GET request update"));
+
+ packet.actor = "message1";
+ updatePacket.networkInfo.actor = "message1";
+ dispatch(actions.messageAdd(packet));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
let networkUpdates = getAllNetworkMessagesUpdateById(getState());
- expect(Object.keys(networkUpdates).length).toBe(0);
+ expect(Object.keys(networkUpdates)).toEqual(["message1"]);
- let updatePacket = stubPackets.get("GET request update");
- dispatch(actions.networkMessageUpdate(updatePacket));
+ packet = clonePacket(stubPackets.get("GET request"));
+ updatePacket = stubPackets.get("XHR GET request update");
+ packet.actor = "message2";
+ updatePacket.networkInfo.actor = "message2";
+ dispatch(actions.messageAdd(packet));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
networkUpdates = getAllNetworkMessagesUpdateById(getState());
- expect(Object.keys(networkUpdates).length).toBe(1);
-
- let xhrUpdatePacket = stubPackets.get("XHR GET request update");
- dispatch(actions.networkMessageUpdate(xhrUpdatePacket));
-
- networkUpdates = getAllNetworkMessagesUpdateById(getState());
- expect(Object.keys(networkUpdates).length).toBe(2);
+ expect(Object.keys(networkUpdates)).toEqual(["message1", "message2"]);
});
it("resets networkMessagesUpdateById in response to MESSAGES_CLEAR action", () => {
const { dispatch, getState } = setupStore([
"XHR GET request"
]);
const updatePacket = stubPackets.get("XHR GET request update");
- dispatch(actions.networkMessageUpdate(updatePacket));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
let networkUpdates = getAllNetworkMessagesUpdateById(getState());
expect(Object.keys(networkUpdates).length).toBe(1);
dispatch(actions.messagesClear());
networkUpdates = getAllNetworkMessagesUpdateById(getState());
expect(Object.keys(networkUpdates).length).toBe(0);
});
+
+ it("cleans the networkMessagesUpdateById property when messages are pruned", () => {
+ const { dispatch, getState } = setupStore([], null, {
+ logLimit: 3
+ });
+
+ // Add 3 network messages and their updates
+ let packet = clonePacket(stubPackets.get("XHR GET request"));
+ let updatePacket = clonePacket(stubPackets.get("XHR GET request update"));
+ packet.actor = "message1";
+ updatePacket.networkInfo.actor = "message1";
+ dispatch(actions.messageAdd(packet));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
+
+ packet.actor = "message2";
+ updatePacket.networkInfo.actor = "message2";
+ dispatch(actions.messageAdd(packet));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
+
+ packet.actor = "message3";
+ updatePacket.networkInfo.actor = "message3";
+ dispatch(actions.messageAdd(packet));
+ dispatch(actions.networkMessageUpdate(updatePacket.networkInfo));
+
+ // Check that we have the expected data.
+ let messages = getAllMessagesById(getState());
+ const [
+ firstNetworkMessageId,
+ secondNetworkMessageId,
+ thirdNetworkMessageId
+ ] = [...messages.keys()];
+
+ let networkUpdates = getAllNetworkMessagesUpdateById(getState());
+ expect(Object.keys(networkUpdates)).toEqual([
+ firstNetworkMessageId,
+ secondNetworkMessageId,
+ thirdNetworkMessageId
+ ]);
+
+ // This addition will remove the first network message.
+ packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ networkUpdates = getAllNetworkMessagesUpdateById(getState());
+ expect(Object.keys(networkUpdates)).toEqual([
+ secondNetworkMessageId,
+ thirdNetworkMessageId
+ ]);
+
+ // This addition will remove the second network message.
+ packet = stubPackets.get("console.log('foobar', 'test')");
+ dispatch(actions.messageAdd(packet));
+
+ networkUpdates = getAllNetworkMessagesUpdateById(getState());
+ expect(Object.keys(networkUpdates)).toEqual([
+ thirdNetworkMessageId
+ ]);
+
+ // This addition will remove the last network message.
+ packet = stubPackets.get("console.log(undefined)");
+ dispatch(actions.messageAdd(packet));
+
+ // networkMessageUpdateById should now be empty.
+ networkUpdates = getAllNetworkMessagesUpdateById(getState());
+ expect(Object.keys(networkUpdates)).toEqual([]);
+ });
+ });
+
+ describe("messagesTableDataById", () => {
+ it("resets messagesTableDataById in response to MESSAGES_CLEAR action", () => {
+ const { dispatch, getState } = setupStore([
+ "console.table(['a', 'b', 'c'])"
+ ]);
+
+ let messages = getAllMessagesById(getState());
+ const data = Symbol("tableData");
+ dispatch(actions.messageTableDataReceive(messages.first().id, data));
+ let table = getAllMessagesTableDataById(getState());
+ expect(table.size).toBe(1);
+ expect(table.get(messages.first().id)).toBe(data);
+
+ dispatch(actions.messagesClear());
+
+ expect(getAllMessagesTableDataById(getState()).size).toBe(0);
+ });
+
+ it("cleans the messagesTableDataById property when messages are pruned", () => {
+ const { dispatch, getState } = setupStore([], null, {
+ logLimit: 2
+ });
+
+ // Add 2 table message and their data.
+ dispatch(actions.messageAdd(stubPackets.get("console.table(['a', 'b', 'c'])")));
+ dispatch(actions.messageAdd(
+ stubPackets.get("console.table(['red', 'green', 'blue']);")));
+
+ let messages = getAllMessagesById(getState());
+
+ const tableData1 = Symbol();
+ const tableData2 = Symbol();
+ const [id1, id2] = [...messages.keys()];
+ dispatch(actions.messageTableDataReceive(id1, tableData1));
+ dispatch(actions.messageTableDataReceive(id2, tableData2));
+
+ let table = getAllMessagesTableDataById(getState());
+ expect(table.size).toBe(2);
+
+ // This addition will remove the first table message.
+ dispatch(actions.messageAdd(stubPackets.get("console.log(undefined)")));
+
+ table = getAllMessagesTableDataById(getState());
+ expect(table.size).toBe(1);
+ expect(table.get(id2)).toBe(tableData2);
+
+ // This addition will remove the second table message.
+ dispatch(actions.messageAdd(stubPackets.get("console.log('foobar', 'test')")));
+
+ expect(getAllMessagesTableDataById(getState()).size).toBe(0);
+ });
});
});