Skip to content

bbondy/codecheckjs

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 

codecheck.js

codecheck.js allows you to check JavaScript code structure against a set of goals in JavaScript. In general, it gives you the ability to check a list of whitelist code snippets and blacklist code snippets against a sample of code.

codecheck.js can be used either client or server side. Client side supports all modern browser, and also IE8+.

Each whitelist and blacklist item is generalized to an assertion. Each assertion is itself a mini JavaScript program to match the structure of the sample code against.

The API is very simple. It has 2 important methods:

  1. addAssertion which takes in a sample of code to match against. It also takes in an extra object which can carry extra state.
  2. parseSample which parses the sample and performs a match against all added assertions. Its callback passes an error if one occurs.

The API has 2 important members which should be used after a parseSample call:

  1. assertions holds an array of assertions that were added. Each one has a hit property. This property does not take into consideration if the item is marked as a whitelist or blacklist item.
  2. allSatisfied will hold true if all whitelist items are matched, and all blacklist items are NOT matched.

Example Usage of the API:

var checker = new CodeCheck();
checker.addAssertion("x = 3;");
checker.addAssertion("x++", { blacklist: true, otherProps: "hi" });
checker.parseSample("if (x) { x = 3; }", function(err) {
  console.log('whitelist hit? ' + checker.assertions[0].hit); // true
  console.log('blacklist hit? ' + checker.assertions[1].hit); // false
  console.log('all satisfied? ' + checker.allSatisfied); // true
});

Dependencies:

  • acorn.js
  • underscore

Demo:

http://codefirefox.com/exercise/intro-exercise

Tests:

Client side tests for the exercise module can also be run simply by loading ../test/clientside.html on the browser you want to test the exercise framework against.

Server side tests are run by using:

npm test

Assertions:

Each assertion will match as long as it appears somewhere in the sample of code. Even an assertion like while (x) break; will match even if there is an if statement before the break on the sample code.

Strict Identifier names:

Identifier names are ignored unless an __ prefix is added in the assertion. If an __ prefix is found, the identifier name will be matched, but the __ prefix will be dropped.

Strict literal matching:

Literal values are always matched strictly. If you'd like any match just use $$ instead.

An asseriton of:

var x = 3;

Will not match:

var x = 4;

But an assertion fo:

var x = $$;

Would match either 3 or 4.

Tracked / Captured Identifiers:

Strict identifier names are important if you want to make sure a person is typing things like document.window but it is not ideal for tracking a variable throughout a program.

To do that you should use tracked / captured identifiers in your assertion.

The same idea applies as strict identifier names, but instead of using a __ prefix, you use a $ prefix.

You can use any number of tracked identifiers in a single assertion.

The following assertion:

var $v1 = 3;
var $v2 = 2;
$v2 = 3;

Would match this code:

var var1 = 3;
var var2 = 2;
var2 = 3;

Capturing can happen on the first encounter of the $ anywhere to the code sample. Even if it is on the right hand side of an assignment, or within a block.

Context sensitive expression skips:

Lets say you want to skip only in one part of an expression, but not in another. You can do this with skips. These skips use identifiers of $$. They indicate that any expression or literal can match.

Example this assertion:

if($$) {
  x = 3;
}

Will match both this:

if(x) {
  x = 3;
}

and this:

if(x && (y < 3)) {
  x = 3;
}

Global Skip usage:

An extra property of skip can also be provided for advanced filtering. It takes a list of abstract node types and properties to ignore and auto-match. See the Mozilla Parser API for more information: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API

assertion.skip = [{"type" : "ForInStaTement", "prop": "left"},
                  {"type" : "ForInStatement", "prop": "right"}];

About

Check JavaScript code structure against a set of goals in JavaScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published