With the recent test a lot of setup takes place. We need to move out to a separate helper function.
A createSelect helper function
function createSelect() {
const select = document.createElement("select");
const option = document.createElement("option");
option.value = 20;
option.text = "20 dollars";
select.add(option);
return select;
}
...
it("has no data-prices attribute on an option, gives an empty array", function () {
// const select = document.createElement("select");
// const option = document.createElement("option");
// option.value = 20;
// option.text = "20 dollars";
// select.add(option);
const select = createSelect();
expect(getPrices(select)).to.be.an('array').that.is.empty;
});
No options
I also want to use that createSelect function with the other test that has no option, so I want the function to do different things:
describe("createSelect helper", function () {
it("with no options, creates a select element with no options", function () {
const select = createSelect();
expect(select.options).to.be.empty;
});
it("with one set of option params, creates a select with one option", function () {
});
it("with multiple option params, creates a select with multiple options", function () {
});
});
To get the first test just means checking if we have option params:
// function createSelect() {
function createSelect(optionParams) {
const select = document.createElement("select");
if (!optionParams) {
return select;
}
const option = document.createElement("option");
option.value = 20;
option.text = "20 dollars";
select.add(option);
return select;
}
One option
The second test is for giving one option:
it("creates a select with one option", function () {
const select = createSelect([
{value: 30, text: "30 dollars"}
]);
expect(select.options[0].value).to.equal(30);
expect(select.options[0].text).to.equal("30 dollars");
});
Which we get going by assigning those values:
function createSelect(optionParams) {
const select = document.createElement("select");
if (!optionParams) {
return select;
}
const params = optionParams[0];
const option = document.createElement("option");
// option.value = 20;
option.value = params.value;
// option.text = "20 dollars";
option.text = params.text;
select.add(option);
return select;
}
And we learn from the test error of "AssertionError: expected '30' to equal 30"
that we cannot get numbers back. They are converted to strings when assigned to an element attribute.
// expect(select.options[0].value).to.equal(30);
expect(select.options[0].value).to.equal("30");
expect(select.options[0].text).to.equal("30 dollars");
Many options
The last createSelect test checks that many options can be created:
it("with multiple option params, creates a select with multiple options", function () {
const select = createSelect([
{value: 20, text: "20 dollars"},
{value: 30, text: "30 dollars"}
]);
expect(select.options[0].value).to.equal("20");
expect(select.options[0].text).to.equal("20 dollars");
expect(select.options[1].value).to.equal("30");
expect(select.options[1].text).to.equal("30 dollars");
});
And we can easily use a forEach method to achieve that:
function createSelect(optionParams) {
...
optionParams.forEach(function (params) {
// const params = optionParams[0];
const option = document.createElement("option");
option.value = params.value;
option.text = params.text;
select.add(option);
});
return select;
}
Refactoring
The createSelect helper function now does many things that we’ll want it to do, but some of it can be improved.
Instead of using an if statement to check if optionParams exists, we can just tell the function that it’s to default to an empty array if the function isn’t given anything. That lets us remove the if statement, and everything still works fine.
// function createSelect(optionParams) {
function createSelect(optionParams = []) {
const select = document.createElement("select");
// if (!optionParams) {
// return select;
// }
optionParams.forEach(function (params) {
const option = document.createElement("option");
option.value = params.value;
option.text = params.text;
select.add(option);
});
return select;
}
Using createSelect for good
We can now update the no options test, replacing document.createElement with the createSelect function instead, and be assured that it reliably behaves properly.
it("has no options on select, gives an empty array", function () {
// const select = document.createElement("select");
const select = createSelect();
expect(getPrices(select)).to.be.an('array').that.is.empty;
});
And the no data-price test can be updated too:
it("has no data-prices attribute on an option, gives an empty array", function () {
// const select = document.createElement("select");
// const option = document.createElement("option");
// option.value = 20;
// option.text = "20 dollars";
// select.add(option);
const select = createSelect([
{value: 20, text: "20 dollars"}
]);
expect(getPrices(select)).to.be.an('array').that.is.empty;
});
With the commented code removed, we now have much nicer and usable tests.
Next steps
no function parameter
select with no options
select with one option
- select option with valid price
- select option with multiple prices
- select option with invalid price
Right now the getPrices() function just does return [];
which isn’t currently all that much. That’s all going to change in the next post.