<!DOCTYPE html>
<select id="test" size="3" multiple="multiple">
</select>
<div id="console"></div>
<script src="../../../resources/js-test-pre.js"></script>
<script>
function reset(mySelect) {
    mySelect.length = 0;
    mySelect.multiple = true;
    mySelect.options[mySelect.length] = new Option("one", "value", false);
    mySelect.options[mySelect.length] = new Option("two", "value", false);
}

function deepCopy(array)
{
    var copy=[];
    for(var i=0;i<array.length;i++)
        copy.push(array[i]);
    return copy;
 }

var mySelect = document.getElementById("test");
reset(mySelect);
var i = 0;

// We use this local variable as shouldBe will modify the dom tree version. Any dom tree version update invalidates
// the caches therefore we need to make sure that we store the values before calling shouldBe.
var selectedOptions;
var optionsLength = 0;

debug((++i) + ") Initial there is no selected options.");
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "0");

debug((++i) + ") Select an option should update the selected options collection.");
mySelect.options[0].selected = true;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'one'");

debug((++i) + ") Select two options should update the selected options collection.");
mySelect.options[1].selected = true;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "2");
shouldBe("selectedOptions[0].text", "'one'");
shouldBe("selectedOptions[1].text", "'two'");

mySelect.options[1].selected = false;
debug((++i) + ") Adding a non selected option should not change the selected options collection.");
mySelect.options[mySelect.length] = new Option("three", "value", false);
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "3");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'one'");

debug((++i) + ") Adding a selected option should change the selected options collection.");
mySelect.options[mySelect.length] = new Option("five", "value", true, true);
selectedOptionsLength = mySelect.selectedOptions.length;
optionsLength = mySelect.options.length;
selectedOptions = mySelect.selectedOptions;
shouldBe("optionsLength", "4");
shouldBe("selectedOptions.length", "2");
shouldBe("selectedOptions[0].text", "'one'");
shouldBe("selectedOptions[1].text", "'five'");

debug((++i) + ") Unselect an option should update the selected options collection.");
mySelect.options[0].selected = false;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "4");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'five'");

debug((++i) + ") Remove an option unselected should not update the selected options collection.");
mySelect.remove(0);
selectedOptionsLength = mySelect.selectedOptions.length;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "3");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'five'");

debug((++i) + ") Remove an option selected should update the selected options collection.");
mySelect.remove(2);
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "0");

mySelect.options[0].selected = true;
mySelect.options[1].selected = true;
debug((++i) + ") Change multiple attribute to false should update selectedOptions.");
mySelect.multiple = false;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'two'");

reset(mySelect);
debug((++i) + ") Even with an option disabled selectedOptions should be updated.");
mySelect.options[0].disabled = true;
mySelect.options[0].selected = true;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "1");
shouldBe("selectedOptions[0].text", "'one'");

debug((++i) + ") Even with select element disabled, the selectedOptions should be updated.");
mySelect.disabled = true;
mySelect.options[1].selected = true;
optionsLength = mySelect.options.length;
selectedOptions = deepCopy(mySelect.selectedOptions);
shouldBe("optionsLength", "2");
shouldBe("selectedOptions.length", "2");
shouldBe("selectedOptions[0].text", "'one'");
shouldBe("selectedOptions[1].text", "'two'");

debug("");
</script>
<script src="../../../resources/js-test-post.js"></script>
