Jump to Table of Contents

Example: Array Processing

This example shows how to use the ArrayAssert object, which contains assertions designed to be used specifically with JavaScript Arrays and array-like objects.

Array Assertions

This example uses the Y.ArrayAssert object to test methods on JavaScript's built-in Array object. The intent of this example is to introduce Y.ArrayAssert and its methods as an alternative to the generic methods available on Y.Assert.

The example begins by creating an example namespace and Y.Test.Case:

Y.namespace("example.test");
Y.example.test.ArrayTestCase = new Y.Test.Case({

    name: "Array Tests",

    //-------------------------------------------------------------------------
    // Setup and teardown
    //-------------------------------------------------------------------------

    /*
     * The setUp() method is used to setup data that necessary for a test to
     * run. This method is called immediately before each test method is run,
     * so it is run as many times as there are test methods.
     */
    setUp : function () {
        this.data = new Array (0,1,2,3,4,5);
    },

    /*
     * The tearDown() method is used to clean up the initialization that was done
     * in the setUp() method. Ideally, it should free up all memory allocated in
     * setUp(), anticipating any possible changes to the data. This method is called
     * immediately after each test method is run.
     */
    tearDown : function () {
        delete this.data;
    },

    ...
});

This TestCase has a setUp() method that creates an array for all the tests to use, as well as a tearDown() method that deletes the array after each test has been executed. This array is used throughout the tests as a base for array manipulations.

Testing push()

The first test is testPush(), which tests the functionality of the Array object's push() method (other methods hidden for simpicity):

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testPush : function() {

        //shortcut variables
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        this.data.push(6);

        //array-specific assertions
        ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");
        ArrayAssert.contains(6, this.data, "Array should contain 6.");
        ArrayAssert.indexOf(6, this.data, 6, "The value in position 6 should be 6.");

        //check that all the values are there
        ArrayAssert.itemsAreEqual([0,1,2,3,4,5,6], this.data, "Arrays should be equal.");

    },

    ...
});

The test begins by setting up a shortcut variables for Y.ArrayAssert, then pushes the value 6 onto the data array (which was created by setUp()). Next, Y.ArrayAssert.isNotEmpty() determines if the array has at least one item; this should definitely pass because the push() operation only adds values to the array. To determine that the new value, 6, is in the array, Y.ArrayAssert.contains() is used. The first argument is the value to look for and the second is the array to look in. To find out if the new value ended up where it should have (the last position, index 6), Y.ArrayAssert.indexOf() is used, passing in the value to search for as the first argument, the array to search in as the second, and the index at which the value should occur as the final argument. Since 6 was pushed onto the end of an array that already had 6 items, it should end up at index 6 (the length of the array minus one). As a final test, Y.ArrayAssert.itemsAreEqual() is used to determine that all of the items in the array are in the correct place. The first argument of this method is an array that has all of the values that should be in the array you're testing. This assertion passes only when the values in both arrays match up (the values are equal and the positions are the same).

Testing pop()

The next test is testPop(), which tests the functionality of the Array object's pop() method:

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testPop : function() {

        //shortcut variables
        var Assert = Y.Assert;
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        var value = this.data.pop();

        //array shouldn't be empty
        ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");

        //basic equality assertion - expected value, actual value, optional error message
        Assert.areEqual(5, this.data.length, "Array should have 5 items.");
        Assert.areEqual(5, value, "Value should be 5.");

        ArrayAssert.itemsAreSame([0,1,2,3,4], this.data, "Arrays should be equal.");

    },

    ...
});

This test also starts out by creating some shortcut variables, for Y.Assert and Y.ArrayAssert. Next, the pop() method is called, storing the returned item in value. Since pop() should only remove a single item, Y.ArrayAssert.isNotEmpty() is called to ensure that only one item has been removed. After that, Y.Assert.areEqual() is called twice: once to check the length of the array and once to confirm the value of the item that was removed from the array (which should be 5). The last assertion uses Y.ArrayAssert.itemsAreSame(), which is similar to Y.ArrayAssert.itemsAreEqual() in that it compares values between two arrays. The difference is that Y.ArrayAssert.itemsAreSame() uses strict equality (===) to compare values, ensuring that no behind-the-scenes type conversions will occur (this makes Y.ArrayAssert.itemsAreSame() more useful for working with arrays of objects).

Testing reverse()

The next test is testReverse(), which tests the functionality of the Array object's reverse() method:

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testReverse : function() {

        //shortcut variables
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        this.data = this.data.reverse();

        ArrayAssert.itemsAreEqual([5,4,3,2,1,0], this.data, "Arrays should be equal.");

    },

    ...
});

The testRemove() method is very simple, calling reverse() on the array and then testing the result. Since every item in the array has changed, the changes can be tested by calling Y.ArrayAssert.itemsAreEqual() once (instead of calling Y.ArrayAssert.indexOf() multiple times). The first argument is an array with all the values in the reverse order of the array that was created in setUp(). When compared with the second argument, the newly reversed array, the values in each position should be equal.

Testing shift()

The next test is testShift(), which tests the functionality of the Array object's shift() method:

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testShift : function() {

        //shortcut variables
        var Assert = Y.Assert;
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        var value = this.data.shift();

        //array shouldn't be empty
        ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");

        //basic equality assertion - expected value, actual value, optional error message
        Assert.areEqual(5, this.data.length, "Array should have 6 items.");
        Assert.areEqual(0, value, "Value should be 0.");

        ArrayAssert.itemsAreEqual([1,2,3,4,5], this.data, "Arrays should be equal.");

    },

    ...
});

The shift() method removes the first item in the array and returns it (similar to pop(), which removes the item from the end). In the testShift() method, shift() is called and the item is stored in value. To ensure that the rest of the array is still there, Y.ArrayAssert.isNotEmpty() is called. After that, Array.areEqual() is called twice, once to test the length of the array and once to test the value that was returned from shift() (which should be 0). As a last test, the entire array is tested using Y.ArrayAssert.itemsAreEqual() to ensure that all of the items have shifted into the appropriate positions in the array.

Testing splice()

The next test is testSplice(), which tests the functionality of the Array object's splice() method:

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testSplice : function() {

        //shortcut variables
        var Assert = Y.Assert;
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        var removed = this.data.splice(1, 2, 99, 100);

        //basic equality assertion - expected value, actual value, optional error message
        Assert.areEqual(6, this.data.length, "Array should have 6 items.");

        //the new items should be there
        ArrayAssert.indexOf(99, this.data, 1, "Value at index 1 should be 99.");
        ArrayAssert.indexOf(100, this.data, 2, "Value at index 2 should be 100.");

        ArrayAssert.itemsAreEqual([0,99,100,3,4,5], this.data, "Arrays should be equal.");
        ArrayAssert.itemsAreEqual([1,2], removed, "Removed values should be an array containing 1 and 2.");

    },

    ...
});

The splice() method is one of the most powerful Array manipulations. It can both remove and add any number of items from an array at the same time. This test begins by splicing some values into the array. When calling splice(), the first argument is 1, indicating that values should be inserted at index 1 of the array; the second argument is 2, indicating that two values should be removed from the array (the value in index 1 and the value in index 2); the third and fourth arguments are values that should be inserted into the array at the position given by the first argument. Essentially, values 1 and 2 should end up being replaced by values 99 and 100 in the array.

The first test is to determine that the length of the array is still 6 (since the previous step removed two items and then inserted two, the length should still be 6). After that, Y.Assert.indexOf() is called to determine that the values of 99 and 100 are in positions 1 and 2, respectively. To ensure the integrity of the entire array, Y.ArrayAssert.itemsAreEqual() is called on the array, comparing it to an array with the same values. The very last step is to test the value returned from splice(), which is an array containing the removed values, 1 and 2. Y.ArrayAssert.itemsAreEqual() is appropriate for this task as well.

Testing unshift()

The next test is testUnshift(), which tests the functionality of the Array object's unshift() method:

Y.example.test.ArrayTestCase = new Y.Test.Case({

    ...

    testUnshift : function() {

        //shortcut variables
        var Assert = Y.Assert;
        var ArrayAssert = Y.ArrayAssert;

        //do whatever data manipulation is necessary
        this.data.unshift(-1);

        //basic equality assertion - expected value, actual value, optional error message
        Assert.areEqual(7, this.data.length, "Array should have 7 items.");

        //the new item should be there
        ArrayAssert.indexOf(-1, this.data, 0, "First item should be -1.");

        ArrayAssert.itemsAreEqual([-1,0,1,2,3,4,5], this.data, "Arrays should be equal.");

    },

    ...
});

Working similar to push(), unshift() adds a value to the array, but the item is added to the front (index 0) instead of the back. This test begins by adding the value -1 to the array. The first assertion determines if the length of the array has been incremented to 7 to account for the new value. After that, Y.ArrayAssert.indexOf() is used to determine if the value has been placed in the correct location. The final assertions tests that the entire array is expected by using Y.ArrayAssert.itemsAreEqual().

Running the tests

With all of the tests defined, the last step is to run them:

//create the console
(new Y.Test.Console({
    verbose : true,
    newestOnTop : false,
    filters: {
        pass: true,
        fail: true
    }
})).render('#testLogger');

Y.Test.Runner.add(Y.example.test.ArrayTestCase);

//run the tests
Y.Test.Runner.run();

Before running the tests, it's necessary to create a Y.Test.Console object to display the results (otherwise the tests would run but you wouldn't see the results). After that, the Y.Test.Runner is loaded with the Y.Test.Case object by calling add() (any number of Y.Test.Case and TestSuite objects can be added to a Y.Test.Runner, this example only adds one for simplicity). The very last step is to call run(), which begins executing the tests in its queue and displays the results in the Y.Test.Console.

Complete Example Source

<div id="testLogger"></div>

<script>
YUI().use('node', 'test-console', 'test', function (Y) {

    Y.namespace("example.test");

    Y.example.test.ArrayTestCase = new Y.Test.Case({

        //the name of the test case - if not provided, one is automatically generated
        name: "Array Tests",

        //-------------------------------------------------------------------------
        // Setup and teardown
        //-------------------------------------------------------------------------

        /*
         * The setUp() method is used to setup data that necessary for a test to
         * run. This method is called immediately before each test method is run,
         * so it is run as many times as there are test methods.
         */
        setUp : function () {
            this.data = new Array (0,1,2,3,4,5);
        },

        /*
         * The tearDown() method is used to clean up the initialization that was done
         * in the setUp() method. Ideally, it should free up all memory allocated in
         * setUp(), anticipating any possible changes to the data. This method is called
         * immediately after each test method is run.
         */
        tearDown : function () {
            delete this.data;
        },

        //-------------------------------------------------------------------------
        // Basic tests - all method names must begin with "test"
        //-------------------------------------------------------------------------

        /*
         * Test the push() method.
         */
        testPush : function() {

            //shortcut variables
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            this.data.push(6);

            //array-specific assertions
            ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");
            ArrayAssert.contains(6, this.data, "Array should contain 6.");
            ArrayAssert.indexOf(6, this.data, 6, "The value in position 6 should be 6.");

            //check that all the values are there
            ArrayAssert.itemsAreEqual([0,1,2,3,4,5,6], this.data, "Arrays should be equal.");

        },

        /*
         * Test the pop() method.
         */
        testPop : function() {

            //shortcut variables
            var Assert = Y.Assert;
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            var value = this.data.pop();

            //array shouldn't be empty
            ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");

            //basic equality assertion - expected value, actual value, optional error message
            Assert.areEqual(5, this.data.length, "Array should have 5 items.");
            Assert.areEqual(5, value, "Value should be 5.");

            ArrayAssert.itemsAreSame([0,1,2,3,4], this.data, "Arrays should be equal.");
        },

        /*
         * Test the reverse() method.
         */
        testReverse : function() {

            //shortcut variables
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            this.data = this.data.reverse();

            ArrayAssert.itemsAreEqual([5,4,3,2,1,0], this.data, "Arrays should be equal.");
        },

        /*
         * Test the shift() method.
         */
        testShift : function() {

            //shortcut variables
            var Assert = Y.Assert;
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            var value = this.data.shift();

            //array shouldn't be empty
            ArrayAssert.isNotEmpty(this.data, "Array should not be empty.");

            //basic equality assertion - expected value, actual value, optional error message
            Assert.areEqual(5, this.data.length, "Array should have 6 items.");
            Assert.areEqual(0, value, "Value should be 0.");

            ArrayAssert.itemsAreEqual([1,2,3,4,5], this.data, "Arrays should be equal.");
        },

        /*
         * Test the splice() method.
         */
        testSplice : function() {

            //shortcut variables
            var Assert = Y.Assert;
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            var removed = this.data.splice(1, 2, 99, 100);

            //basic equality assertion - expected value, actual value, optional error message
            Assert.areEqual(6, this.data.length, "Array should have 6 items.");

            //the new items should be there
            ArrayAssert.indexOf(99, this.data, 1, "Value at index 1 should be 99.");
            ArrayAssert.indexOf(100, this.data, 2, "Value at index 2 should be 100.");

            ArrayAssert.itemsAreEqual([0,99,100,3,4,5], this.data, "Arrays should be equal.");
            ArrayAssert.itemsAreEqual([1,2], removed, "Removed values should be an array containing 1 and 2.");

        },

        /*
         * Test the unshift() method.
         */
        testUnshift : function() {

            //shortcut variables
            var Assert = Y.Assert;
            var ArrayAssert = Y.ArrayAssert;

            //do whatever data manipulation is necessary
            this.data.unshift(-1);

            //basic equality assertion - expected value, actual value, optional error message
            Assert.areEqual(7, this.data.length, "Array should have 7 items.");

            //the new item should be there
            ArrayAssert.indexOf(-1, this.data, 0, "First item should be -1.");

            ArrayAssert.itemsAreEqual([-1,0,1,2,3,4,5], this.data, "Arrays should be equal.");
        }

    });

    //create the console
    (new Y.Test.Console({
        newestOnTop : false,
        filters: {
            pass: true,
            fail: true
        }
    })).render('#testLogger');

    Y.Test.Runner.add(Y.example.test.ArrayTestCase);

    //run the tests
    Y.Test.Runner.run();
});

</script>