var Plotly = require('../src/plotly');

describe('plot schema', function() {
    'use strict';

    var plotSchema = Plotly.PlotSchema.get(),
        valObjects = plotSchema.defs.valObjects;

    function isPlainObject(o) {
        return Object.prototype.toString.call(o) === '[object Object]';
    }

    function isValObject(o) {
        return Object.keys(o).indexOf('valType') !== -1;
    }

    function assertPlotSchema(check) {
        var traces = plotSchema.traces;
        Object.keys(traces).forEach(function(traceName) {
            crawl(traces[traceName].attributes, check);
        });

        crawl(plotSchema.layout.layoutAttributes, check);
    }

    function crawl(attrs, check) {
        Object.keys(attrs).forEach(function(attrName) {
            var attr = attrs[attrName];

            if(isValObject(attr)) check(attr);
            else if(isPlainObject(attr)) crawl(attr, check);
        });
    }

    it('all attributes should have a valid `valType`', function() {
        var valTypes = Object.keys(valObjects);

        assertPlotSchema(function(attr) {
            expect(valTypes.indexOf(attr.valType) !== -1).toBe(true);
        });

    });

    it('all attributes should have the required options', function() {
        assertPlotSchema(function(attr) {
            var keys = Object.keys(attr);

            valObjects[attr.valType].requiredOpts.forEach(function(opt) {
                expect(keys.indexOf(opt) !== -1).toBe(true);
            });
        });
    });

    it('all attributes should only have compatible options', function() {
        assertPlotSchema(function(attr) {
            var valObject = valObjects[attr.valType],
                opts = valObject.requiredOpts
                    .concat(valObject.otherOpts)
                    .concat(['valType', 'description', 'role']);

            Object.keys(attr).forEach(function(key) {
                expect(opts.indexOf(key) !== -1).toBe(true);
            });
        });
    });
});

@@ -189,213 +189,8 @@
 s;%0A%0A
-    function isPlainObject(o) %7B%0A        return Object.prototype.toString.call(o) === '%5Bobject Object%5D';%0A    %7D%0A%0A    function isValObject(o) %7B%0A        return Object.keys(o).indexOf('valType') !== -1;%0A    %7D%0A%0A
     
@@ -264,16 +264,17 @@
 traces;%0A
+%0A
         
@@ -331,24 +331,42 @@
             
+Plotly.PlotSchema.
 crawl(traces
@@ -418,16 +418,34 @@
         
+Plotly.PlotSchema.
 crawl(pl
@@ -497,267 +497,8 @@
  %7D%0A%0A
-    function crawl(attrs, check) %7B%0A        Object.keys(attrs).forEach(function(attrName) %7B%0A            var attr = attrs%5BattrName%5D;%0A%0A            if(isValObject(attr)) check(attr);%0A            else if(isPlainObject(attr)) crawl(attr, check);%0A        %7D);%0A    %7D%0A%0A
     

use PlotSchema.crawl in plotschema test