knockout viewmodel dirtyFlag unit test

Combine KoLite dirty flag with knockout.viewmodel plugin

HTML

<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css">
<script src="http://code.jquery.com/qunit/qunit-1.10.0.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>
<script src="http://coderenaissance.github.com/knockout.viewmodel/knockout.viewmodel.js"></script>
<div id="qunit"></div>

JavaScript

// Inline version of KoLite dirtyFlag
(function (ko) {
    ko.DirtyFlag = function (objectToTrack, isInitiallyDirty, hashFunction) {

        hashFunction = hashFunction || ko.toJSON;

        var
        _objectToTrack = objectToTrack,
            _lastCleanState = ko.observable(hashFunction(_objectToTrack)),
            _isInitiallyDirty = ko.observable(isInitiallyDirty),

            result = function () {
                var self = this;

                self.isDirty = ko.computed(function () {
                    return _isInitiallyDirty() || hashFunction(_objectToTrack) !== _lastCleanState();
                });

                self.reset = function () {
                    _lastCleanState(hashFunction(_objectToTrack));
                    _isInitiallyDirty(false);
                };

                return self;
            };

        return result;
    };
})(ko);


test("Test", function () {
    ko.viewmodel.options.logging = true;
    var viewmodel, model, options;

    model = {
        "Captain": {
            "Id": 17,
                "Job": 37,
                "Name": "James T. Kirk",
                "Years": 7,
                "Nationality": "US",
                "Comments": "Beware the corbomite.",
                "_destroy": false
        },
            "Navigator": {
            "Id": 19,
                "Job": 38,
                "Name": "Hikaru Sulu",
                "Years": null,
                "Nationality": null,
                "Comments": "Oh My!",
                "_destroy": false
        }
    };

    options = {
        extend: {
            "{root}.Captain": "CrewDirtyFlag",
            "{root}.Navigator": "CrewDirtyFlag"
        },
        shared: {
            CrewDirtyFlag: function (crew) {
                crew.dirtyFlag = new ko.DirtyFlag([
                crew.Name,
                crew.Nationality,
                crew.Years,
                crew.Comments], false);

                crew.isDirty = ko.computed(function () {
  ...