Commit ea71f69c authored by Yuanle Song's avatar Yuanle Song
Browse files

add error handling for number input

parent 6721280e
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -216,6 +216,34 @@
	      console.assert(m.numberStack[0] === -9);
	      console.assert(m.numberStack[1] === 29 * 2);
	  };
	  const rpnTestNumberErrorHandling = function () {
	      var m = new fsm.RPNCalculator();
	      m.sendKey("num0");
	      m.sendKey("num0");
	      console.assert(m.currentNumber === "0");

	      m = new fsm.RPNCalculator();
	      m.sendKey("dot");
	      console.assert(m.currentNumber === "0.");
	      m.sendKey("backspace");
	      console.assert(m.currentNumber === "0");
	      m.sendKey("backspace");
	      console.assert(m.currentNumber === "");

	      m = new fsm.RPNCalculator();
	      m.sendKey("num1");
	      m.sendKey("dot");
	      m.sendKey("num2");
	      console.assert(m.currentNumber === "1.2");
	      m.sendKey("dot");    // future dot is ignored and show error.
	      console.assert(m.currentNumber === "1.2");
	      m.sendKey("num3");
	      console.assert(m.currentNumber === "1.23");
	      m.sendKey("dot");
	      console.assert(m.currentNumber === "1.23");
	      m.sendKey("return");
	      console.assert(m.numberStack[0] === 1.23);
	  };

	  /**
	   * run all tests.
@@ -236,6 +264,8 @@
	      rpnTestNumberHandling();
	      rpnTestAutoCommitNumber();
	      rpnTestOperator();

	      rpnTestNumberErrorHandling();
	  };

	  // page init
+66 −5
Original line number Diff line number Diff line
@@ -169,14 +169,66 @@ var fsm = function () {
		return keyName.substring(3);
	    }
	};
	/**
	 * press keyName when existing number string is oldNumberString.
	 * return [newNumberString, errMsg]
	 * errMsg will be null if there is no error.
	 */
	const changeNumberString = function (keyName, oldNumberString) {
	    if (oldNumberString === "0" && keyName === keyNames.num0) {
		return [oldNumberString, "more 0s are ignored"];
	    } else if (oldNumberString === "" && keyName === keyNames.dot) {
		return ["0.", null];
	    } else if (keyName === keyNames.dot && oldNumberString.indexOf(".") !== -1) {
		// Note: do not use indexOf(keyNames.dot) in if condition,
		// because the keyName is dot, not ".".
		return [oldNumberString, "more dots are ignored"];
	    } else {
		return [oldNumberString + numKeyToNumString(keyName), null];
	    }
	};
	const testChangeNumberString = function () {
	    var r = changeNumberString(keyNames.dot, "");
	    console.assert(r[0] === "0.");
	    console.assert(r[1] === null);

	    r = changeNumberString(keyNames.num1, "");
	    console.assert(r[0] === "1");
	    console.assert(r[1] === null);

	    r = changeNumberString(keyNames.num1, "2");
	    console.assert(r[0] === "21");
	    console.assert(r[1] === null);

	    r = changeNumberString(keyNames.num0, "0");
	    console.assert(r[0] === "0");
	    console.assert(r[1] !== null);

	    r = changeNumberString(keyNames.num0, "12");
	    console.assert(r[0] === "120");
	    console.assert(r[1] === null);

	    r = changeNumberString(keyNames.dot, "1.2");
	    console.assert(r[0] === "1.2");
	    console.assert(r[1] !== null);
	};
    	this.sendKey = function (keyName) {
	    var num, num1, num2;
	    var numString, errMsg;
	    var r;

    	    switch (this.currentState) {
    	    case stateIdle:
    		if (isNumberKey(keyName)) {
		    // TODO handle errors and special cases
		    this.currentNumber += numKeyToNumString(keyName);
		    r = changeNumberString(keyName, this.currentNumber);
		    numString = r[0];
		    errMsg = r[1];
		    if (errMsg === null) {
			this.currentNumber = numString;
		    } else {
			this.setErrorMsg(errMsg);
		    }
		    // change state
		    this.currentState = stateWaitingForNumberOrAction;
		} else {
		    switch (keyName) {
@@ -218,8 +270,14 @@ var fsm = function () {
    		break;
    	    case stateWaitingForNumberOrAction:
    		if (isNumberKey(keyName)) {
		    // TODO handle errors and special cases
		    this.currentNumber += numKeyToNumString(keyName);
		    r = changeNumberString(keyName, this.currentNumber);
		    numString = r[0];
		    errMsg = r[1];
		    if (errMsg === null) {
			this.currentNumber = numString;
		    } else {
			this.setErrorMsg(errMsg);
		    }
		    // keep current state
		} else if (keyName === keyNames['return']) {
		    this.numberStack.push(parseFloat(this.currentNumber));
@@ -229,7 +287,7 @@ var fsm = function () {
		    if (this.currentNumber.length > 0) {
			this.currentNumber = this.currentNumber.substring(0, this.currentNumber.length - 1);
		    } else {
			setErrorMsg("no digits to delete");
			this.setErrorMsg("no digits to delete");
		    }
		} else if (isOperator(keyName)) {
		    // commit number
@@ -253,6 +311,9 @@ var fsm = function () {
    	    debug("sendKey " + keyName + ", currentState is " + this.currentState);
    	    return this.currentState;
    	};

	// run all tests;
	testChangeNumberString();
    };

    return {