Bug 1299668 - Clear all messages data in state when clearing messagesById;r=linclark
authorNicolas Chevobbe <chevobbe.nicolas@gmail.com>
Tue, 20 Sep 2016 11:37:00 -0700
changeset 314475 38578ce36098
parent 314474 557768ed3b54
child 314476 b231938859d7
push id20575
push userbgrinstead@mozilla.com
push dateTue, 20 Sep 2016 18:49:35 +0000
treeherderfx-team@94032319b5df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslinclark
bugs1299668
milestone52.0a1
Bug 1299668 - Clear all messages data in state when clearing messagesById;r=linclark MozReview-Commit-ID: kOMl0KiUkG
devtools/client/webconsole/new-console-output/actions/messages.js
devtools/client/webconsole/new-console-output/reducers/messages.js
devtools/client/webconsole/new-console-output/store.js
devtools/client/webconsole/new-console-output/test/actions/messages.test.js
devtools/client/webconsole/new-console-output/test/store/messages.test.js
devtools/client/webconsole/package.json
--- a/devtools/client/webconsole/new-console-output/actions/messages.js
+++ b/devtools/client/webconsole/new-console-output/actions/messages.js
@@ -11,29 +11,36 @@ const {
 } = require("devtools/client/webconsole/new-console-output/utils/messages");
 const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
 
 const {
   MESSAGE_ADD,
   MESSAGES_CLEAR,
   MESSAGE_OPEN,
   MESSAGE_CLOSE,
+  MESSAGE_TYPE,
 } = require("../constants");
 
 const defaultIdGenerator = new IdGenerator();
 
 function messageAdd(packet, idGenerator = null) {
-  if (idGenerator == null) {
-    idGenerator = defaultIdGenerator;
-  }
-  let message = prepareMessage(packet, idGenerator);
+  return (dispatch) => {
+    if (idGenerator == null) {
+      idGenerator = defaultIdGenerator;
+    }
+    let message = prepareMessage(packet, idGenerator);
 
-  return {
-    type: MESSAGE_ADD,
-    message
+    if (message.type === MESSAGE_TYPE.CLEAR) {
+      dispatch(messagesClear());
+    }
+
+    dispatch({
+      type: MESSAGE_ADD,
+      message
+    });
   };
 }
 
 function messagesClear() {
   return {
     type: MESSAGES_CLEAR
   };
 }
--- a/devtools/client/webconsole/new-console-output/reducers/messages.js
+++ b/devtools/client/webconsole/new-console-output/reducers/messages.js
@@ -20,20 +20,16 @@ function messages(state = new MessageSta
   switch (action.type) {
     case constants.MESSAGE_ADD:
       let newMessage = action.message;
 
       if (newMessage.type === constants.MESSAGE_TYPE.NULL_MESSAGE) {
         return state;
       }
 
-      if (newMessage.type === constants.MESSAGE_TYPE.CLEAR) {
-        return state.set("messagesById", Immutable.List([newMessage]));
-      }
-
       if (newMessage.allowRepeating && messagesById.size > 0) {
         let lastMessage = messagesById.last();
         if (lastMessage.repeatId === newMessage.repeatId) {
           return state.withMutations(function (record) {
             record.set("messagesById", messagesById.pop().push(
               newMessage.set("repeat", lastMessage.repeat + 1)
             ));
           });
@@ -42,17 +38,20 @@ function messages(state = new MessageSta
 
       return state.withMutations(function (record) {
         record.set("messagesById", messagesById.push(newMessage));
         if (newMessage.type === "trace") {
           record.set("messagesUiById", messagesUiById.push(newMessage.id));
         }
       });
     case constants.MESSAGES_CLEAR:
-      return state.set("messagesById", Immutable.List());
+      return state.withMutations(function (record) {
+        record.set("messagesById", Immutable.List());
+        record.set("messagesUiById", Immutable.List());
+      });
     case constants.MESSAGE_OPEN:
       return state.set("messagesUiById", messagesUiById.push(action.id));
     case constants.MESSAGE_CLOSE:
       let index = state.messagesUiById.indexOf(action.id);
       return state.deleteIn(["messagesUiById", index]);
   }
 
   return state;
--- a/devtools/client/webconsole/new-console-output/store.js
+++ b/devtools/client/webconsole/new-console-output/store.js
@@ -1,31 +1,36 @@
 /* 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/. */
 "use strict";
 
 const {FilterState} = require("devtools/client/webconsole/new-console-output/reducers/filters");
 const {PrefState} = require("devtools/client/webconsole/new-console-output/reducers/prefs");
-const { combineReducers, createStore } = require("devtools/client/shared/vendor/redux");
+const { applyMiddleware, combineReducers, createStore } = require("devtools/client/shared/vendor/redux");
+const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
 const { reducers } = require("./reducers/index");
 const Services = require("Services");
 
 function configureStore() {
   const initialState = {
     prefs: new PrefState({
       logLimit: Math.max(Services.prefs.getIntPref("devtools.hud.loglimit"), 1),
     }),
     filters: new FilterState({
       error: Services.prefs.getBoolPref("devtools.webconsole.filter.error"),
       warn: Services.prefs.getBoolPref("devtools.webconsole.filter.warn"),
       info: Services.prefs.getBoolPref("devtools.webconsole.filter.info"),
       log: Services.prefs.getBoolPref("devtools.webconsole.filter.log"),
     })
   };
 
-  return createStore(combineReducers(reducers), initialState);
+  return createStore(
+    combineReducers(reducers),
+    initialState,
+    applyMiddleware(thunk)
+  );
 }
 
 // Provide the store factory for test code so that each test is working with
 // its own instance.
 module.exports.configureStore = configureStore;
 
--- a/devtools/client/webconsole/new-console-output/test/actions/messages.test.js
+++ b/devtools/client/webconsole/new-console-output/test/actions/messages.test.js
@@ -1,58 +1,66 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
+const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
+const configureStore = require("redux-mock-store");
 const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages");
-const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
+const { stubPackets, stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");
 const { setupActions } = require("devtools/client/webconsole/new-console-output/test/helpers");
 const constants = require("devtools/client/webconsole/new-console-output/constants");
 
+const mockStore = configureStore([ thunk ]);
+
 const expect = require("expect");
 
 let actions;
 
 describe("Message actions:", () => {
-  before(()=>{
+  beforeEach(()=>{
     actions = setupActions();
   });
 
   describe("messageAdd", () => {
-    it("creates expected action given a packet", () => {
-      const packet = {
-        "from": "server1.conn4.child1/consoleActor2",
-        "type": "consoleAPICall",
-        "message": {
-          "arguments": [
-            "foobar",
-            "test"
-          ],
-          "columnNumber": 27,
-          "counter": null,
-          "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js",
-          "functionName": "",
-          "groupName": "",
-          "level": "log",
-          "lineNumber": 1,
-          "private": false,
-          "styles": [],
-          "timeStamp": 1455064271115,
-          "timer": null,
-          "workerType": "none",
-          "category": "webdev"
-        }
-      };
-      const action = actions.messageAdd(packet);
+    it("dispatches expected action given a packet", () => {
+      const packet = stubPackets.get("console.log('foobar', 'test')");
+      const store = mockStore({});
+      store.dispatch(actions.messageAdd(packet));
+
+      const expectedActions = store.getActions();
+      expect(expectedActions.length).toEqual(1);
+
+      const addAction = expectedActions[0];
+      const {message} = addAction;
       const expected = {
         type: constants.MESSAGE_ADD,
         message: stubPreparedMessages.get("console.log('foobar', 'test')")
       };
+      expect(message.toJS()).toEqual(expected.message.toJS());
+    });
 
-      expect(action.message.toJS()).toEqual(expected.message.toJS());
+    it("dispatches expected actions given a console.clear packet", () => {
+      const packet = stubPackets.get("console.clear()");
+      const store = mockStore({});
+      store.dispatch(actions.messageAdd(packet));
+
+      const expectedActions = store.getActions();
+      expect(expectedActions.length).toEqual(2);
+
+      const [clearAction, addAction] = expectedActions;
+      expect(clearAction.type).toEqual(constants.MESSAGES_CLEAR);
+
+      const {message} = addAction;
+      const expected = {
+        type: constants.MESSAGE_ADD,
+        message: stubPreparedMessages.get("console.clear()")
+      };
+      expect(addAction.type).toEqual(constants.MESSAGE_ADD);
+      expect(message.toJS()).toEqual(expected.message.toJS());
     });
   });
 
   describe("messagesClear", () => {
     it("creates expected action", () => {
       const action = actions.messagesClear();
       const expected = {
         type: constants.MESSAGES_CLEAR,
--- a/devtools/client/webconsole/new-console-output/test/store/messages.test.js
+++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js
@@ -64,30 +64,39 @@ describe("Message reducer:", () => {
 
       const messages = getAllMessages(getState());
 
       expect(messages.size).toBe(2);
       expect(messages.first().repeat).toBe(3);
       expect(messages.last().repeat).toBe(1);
     });
 
-    it("clears the store in response to console.clear()", () => {
-      const { dispatch, getState } = setupStore([
-        "console.log('foobar', 'test')",
-        "console.log(undefined)"
-      ]);
+    it("adds a message in response to console.clear()", () => {
+      const { dispatch, getState } = setupStore([]);
 
       dispatch(actions.messageAdd(stubPackets.get("console.clear()")));
 
       const messages = getAllMessages(getState());
 
       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(undefined)"
+      ]);
+
+      dispatch(actions.messagesClear());
+
+      const messages = getAllMessages(getState());
+      expect(messages.size).toBe(0);
+    });
+
     it("limits the number of messages displayed", () => {
       const { dispatch, getState } = setupStore([]);
 
       const logLimit = 1000;
       const packet = stubPackets.get("console.log(undefined)");
       for (let i = 1; i <= logLimit + 1; i++) {
         packet.message.arguments = [`message num ${i}`];
         dispatch(actions.messageAdd(packet));
@@ -117,10 +126,25 @@ describe("Message reducer:", () => {
       const message = stubPackets.get("console.trace()");
       dispatch(actions.messageAdd(message));
 
       const messages = getAllMessages(getState());
       const messagesUi = getAllMessagesUiById(getState());
       expect(messagesUi.size).toBe(1);
       expect(messagesUi.first()).toBe(messages.first().id);
     });
+
+    it("clears the messages UI list in response to MESSAGES_CLEAR action", () => {
+      const { dispatch, getState } = setupStore([
+        "console.log('foobar', 'test')",
+        "console.log(undefined)"
+      ]);
+
+      const traceMessage = stubPackets.get("console.trace()");
+      dispatch(actions.messageAdd(traceMessage));
+
+      dispatch(actions.messagesClear());
+
+      const messagesUi = getAllMessagesUiById(getState());
+      expect(messagesUi.size).toBe(0);
+    });
   });
 });
--- a/devtools/client/webconsole/package.json
+++ b/devtools/client/webconsole/package.json
@@ -5,15 +5,16 @@
     "amd-loader": "0.0.5",
     "babel-preset-es2015": "^6.6.0",
     "babel-register": "^6.7.2",
     "enzyme": "^2.4.1",
     "expect": "^1.16.0",
     "jsdom": "^9.4.1",
     "jsdom-global": "^2.0.0",
     "mocha": "^2.5.3",
+    "redux-mock-store": "^1.1.4",
     "require-hacker": "^2.1.4",
     "sinon": "^1.17.5"
   },
   "scripts": {
     "test": "NODE_PATH=`pwd`/../../../:`pwd`/../../../devtools/client/shared/vendor/ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/requireHelper.js"
   }
 }