HTML Canvas Unit testing

前端 未结 6 859
既然无缘
既然无缘 2020-12-08 13:46

How can I unit-test Javascript that draws on an HTML canvas? Drawing on the canvas should be checked.

6条回答
  •  悲哀的现实
    2020-12-08 14:28

    As discussed in the question comments it's important to check that certain functions have been invoked with suitable parameters. pcjuzer proposed the usage of proxy pattern. The following example (RightJS code) shows one way to do this:

    var Context = new Class({
        initialize: function($canvasElem) {
            this._ctx = $canvasElem._.getContext('2d');
    
            this._calls = []; // names/args of recorded calls
    
            this._initMethods();
        },
        _initMethods: function() {
            // define methods to test here
            // no way to introspect so we have to do some extra work :(
            var methods = {
                fill: function() {
                    this._ctx.fill();
                },
                lineTo: function(x, y) {
                    this._ctx.lineTo(x, y);
                },
                moveTo: function(x, y) {
                    this._ctx.moveTo(x, y);
                },
                stroke: function() {
                    this._ctx.stroke();
                }
                // and so on
            };
    
            // attach methods to the class itself
            var scope = this;
            var addMethod = function(name, method) {
                scope[methodName] = function() {
                    scope.record(name, arguments);
    
                    method.apply(scope, arguments);
                };
            }
    
            for(var methodName in methods) {
                var method = methods[methodName];
    
                addMethod(methodName, method);
            }
        },
        assign: function(k, v) {
            this._ctx[k] = v;
        },
        record: function(methodName, args) {
            this._calls.push({name: methodName, args: args});
        },
        getCalls: function() {
            return this._calls;
        }
        // TODO: expand API as needed
    });
    
    // Usage
    var ctx = new Context($('myCanvas'));
    
    ctx.moveTo(34, 54);
    ctx.lineTo(63, 12);
    
    ctx.assign('strokeStyle', "#FF00FF");
    ctx.stroke();
    
    var calls = ctx.getCalls();
    
    console.log(calls);
    

    You can find a functional demo here.

    I have used a similar pattern to implement some features missing from the API. You might need to hack it a bit to fit your purposes. Good luck!

提交回复
热议问题