diff --git a/CHANGELOG.md b/CHANGELOG.md index b2d0bd8..d988cd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,8 +112,6 @@ _ = function() end ``` -* return's statement simplified - ## New Things * New code coverage tool built into `moonc` diff --git a/docs/reference.md b/docs/reference.md index 4299267..bb5275a 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -1688,6 +1688,47 @@ If you want to disable [error rewriting](#error_rewriting), you can pass the `-d` flag. A full list of flags can be seen by passing the `-h` or `--help` flag. +### Code Coverage + +`moon` lets you run a MoonScript file while keeping track of which lines +are executed with the `-c` flag. + +For example, consider the following `.moon` file: + +```moononly +-- test.moon +first = -> + print "hello" + +second = -> + print "world" + +first! +``` + +We can execute and get a glance of which lines ran: + +```bash +$ moon -c test.moon +``` + +The following output is produced: + +``` +------| @cool.moon + 1| -- test.moon +* 2| first = -> +* 3| print "hello" + 4| +* 5| second = -> + 6| print "world" + 7| +* 8| first! + 9| +``` + +The star next to the line means that it was executed. Blank lines are not +considered when running so by default they don't get marked as executed. ## `moonc` @@ -1713,9 +1754,128 @@ compiled automatically. A full list of flags can be seen by passing the `-h` or `--help` flag. +### Linter + +`moonc` contains a [lint](http://en.wikipedia.org/wiki/Lint_(software)) tool +for statically detecting potential problems with code. The current linter only +has one test: it detects the use of global variables. + +You can execute the linter with the `-l` flag. When the linting flag is +provided only linting takes place and no compiled code is generated. + +```bash +moonc -l file1.moon file2.moon +``` + +Like when compiling, you can also pass a directory as a command line argument +to recursively process all the `.moon` files. + +#### Global Variable Checking + +It's considered good practice to avoid using global variables and create local +variables for all the values referenced. A good case for not using global +variables is that you can analyize the code ahead of time without the need to +execute it to find references to undeclared variables. + +MoonScript makes it difficult to declare global variables by forcing you to be +explicit with the `export` keyword, so it's a good candidate for doing this +kind of linting. + +Consider the following program with a typo: (`my_number` is spelled wrong as +`my_nmuber` in the function) + +```moononly +-- lint_example.moon +my_number = 1234 + +some_function = -> + -- a contrived example with a small chance to pass + if math.random() < 0.01 + my_nmuber + 10 + +some_function! +``` + +Although there is a bug in this code, it rarely happens during execution. It's +more likely to be missed during development and cause problems in the future. + +Running the linter immediately identifies the problem: + +```bash +$ moonc -l lint_example.moon +``` + +Outputs: + +``` +./lint_example.moon + +line 7: accessing global my_nmuber +================================== +> my_nmuber + 10 + +``` + +##### Global Variable Whitelist + +In most circumstances it's impossible to avoid using some global variables. For +example, to access any of the built in modules or functions you typically +access them globally. + +For this reason a global variable whitelist is used. It's a list of global +variables that are allowed to be used. A default whitelist is provided that +contains all of Lua's built in functions and modules. + +You can create your own entires in the whitelist as well. For example, the +testing framework [Busted](http://olivinelabs.com/busted) uses a collection of +global functions (like `describe`, `before_each`, `setup`) to make writing +tests easy. + +It would be nice if we could allow all of those global functions to be called +for `.moon` files located in the `spec/` directory. We can do that by creating +a `lint_config` file. + +`lint_config` is a regular MoonScript or Lua file that provides configuration +for the linter. One of those settings is `whitelist_globals`. + +To create a configuration for Busted we might do something like this: + +```moononly +-- lint_config.moon +{ + whitelist_globals: { + ["spec/"]: { + "it", "describe", "setup", "teardown", + "before_each", "after_each", "pending" + } + } +} +``` + +Compile the file: + +```bash +$ moonc lint_config.moon +``` + +Then run the linter on your entire project: + +```bash +$ moonc -l . +``` + +The whitelisted global references in `spec/` will no longer raise notices. + +The `whitelist_globals` property of the `lint_config` is a table where the keys +are Lua patterns that match file names, and the values are an array of globals +that are allowed. + +Multiple patterns in `whitelist_globals` can match a single file, the union of +the allowed globals will be used when linting that file. + # License (MIT) - Copyright (C) 2013 by Leaf Corcoran + Copyright (C) 2014 by Leaf Corcoran Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal