Reputation: 126
I have this strange behavior of node.js. Basically the title says it all, I would only like to add, that this wasn't the case before, with the exactly the same code.
I suspect that this started to happen after I ran sudo chown -R $USER /usr/local/lib/node_modules
because I wanted to install typescript and got writing permissions error, however I cannot be 100% sure. Interestingly enough my test passes, and eventually everything works fine and the result is correct, but I don't know why my console.log()
outputs are different. What I get when I put code in node shell and console.log
it is a concatenated string from recursive calls. When I run code from a file, I only get the string from the first call.
Here's my code:
const fields = {
0: "D:0:0:0:1:20:9",
1: "D:1:0:22:1:95:9",
2: "D:2:0:117:1:27:9"
};
function getRequiredFields(key, trailing=false) {
// key is a number
if (typeof trailing !== "boolean") {
throw new Error("<trailing> must be of type 'boolean'. Default is false");
}
if (typeof key === "number" && !fields[key]) {
throw new Error("Field is not defined: <key> must be in range [0, 9]");
}
if (typeof key !== "number") {
throw new Error("<key> must be a number");
}
const lastByte = trailing ? "\r" : "";
if (key === 0) {
return fields[key] + lastByte;
} else {
return getRequiredFields(key-1) + "\r" + fields[key] + lastByte;
}
};
console.log(getRequiredKeys(2, true));
and here's my test (mocha+chai):
describe("Expects a positive number to build required fields, the optional 2nd argument puts a trailing carriage return if true, default is false", () => {
it("Returns a combined string for required fields", () => {
expect(getRequiredFields(2)).to.be.a("string");
expect(getRequiredFields(2, true)).to.equal("D:0:0:0:1:20:9\rD:1:0:22:1:95:9\rD:2:0:117:1:27:9\r");
expect(getRequiredFields(2, false)).to.equal("D:0:0:0:1:20:9\rD:1:0:22:1:95:9\rD:2:0:117:1:27:9");
});
it("Throws an error if <trailing> is not a boolean", () => {
expect(getRequiredFields.bind(this, 10, "foo")).to.throw("<trailing> must be of type 'boolean'");
});
it("Throws an error if <key> is higher than 9", () => {
expect(getRequiredFields.bind(this, 10, true)).to.throw("Field is not defined: <key> must be in range [0, 9]");
});
it("Throws an error if <key> is NaN", () => {
expect(getRequiredFields.bind(this, "f", false)).to.throw("<key> must be a number");
});
});
Upvotes: 1
Views: 74
Reputation: 10604
The reason is the control character \r
(carriage return), which move the cursor to the leftmost point, so the further characters overwrite existing ones. Since this only effect output, the real content of the string
is not effected, so all thing should be fine.
If you intended to use newline, you should use \n
instead (or require('os').EOL
for OS-specific one).
You can also try out the following, which would output 789456
or 123456789
depend on the enviroment.
console.log('123456\r789')
Upvotes: 1