1 | # xplain v0.4.0
|
2 |
|
3 | > Generates API documentation / markdown inserts from unit tests
|
4 |
|
5 | [![NPM][xplain-icon] ][xplain-url]
|
6 |
|
7 | [![Build status][xplain-ci-image] ][xplain-ci-url]
|
8 | [![dependencies][xplain-dependencies-image] ][xplain-dependencies-url]
|
9 | [![devdependencies][xplain-devdependencies-image] ][xplain-devdependencies-url]
|
10 |
|
11 | [xplain-icon]: https://nodei.co/npm/xplain.png?downloads=true
|
12 | [xplain-url]: https://npmjs.org/package/xplain
|
13 | [xplain-ci-image]: https://travis-ci.org/bahmutov/xplain.png?branch=master
|
14 | [xplain-ci-url]: https://travis-ci.org/bahmutov/xplain
|
15 | [xplain-dependencies-image]: https://david-dm.org/bahmutov/xplain.png
|
16 | [xplain-dependencies-url]: https://david-dm.org/bahmutov/xplain
|
17 | [xplain-devdependencies-image]: https://david-dm.org/bahmutov/xplain/dev-status.png
|
18 | [xplain-devdependencies-url]: https://david-dm.org/bahmutov/xplain#info=devDependencies
|
19 |
|
20 |
|
21 |
|
22 | ***This is still very early release, probably would not work right away for your needs.***
|
23 |
|
24 | **xplain** takes unit tests and generates documentation examples. Check out the reverse:
|
25 | [jsmd](https://github.com/vesln/jsmd) takes code blocks in Markdown and runs them as unit tests.
|
26 |
|
27 | #### inputs
|
28 |
|
29 | *src/add.js*
|
30 |
|
31 | /**
|
32 | Adds two numbers
|
33 |
|
34 | @method add
|
35 | */
|
36 | function add(a, b) { return a + b; }
|
37 |
|
38 | *test/add.js*
|
39 |
|
40 | /** @sample add */
|
41 | QUnit.test('adds numbers', function () {
|
42 | QUnit.equal(add(2, 3), 5);
|
43 | });
|
44 |
|
45 | #### usage
|
46 |
|
47 | xplain -i src/add.js -i test/add.js
|
48 |
|
49 | produces HTML documentation:
|
50 |
|
51 | **add**
|
52 | Adds two numbers
|
53 |
|
54 | add(2, 3); // 5
|
55 |
|
56 | See the generated [example api](http://bahmutov.github.io/xplain/)
|
57 |
|
58 | To see (the very few) command line options run `xplain` or `xplain -h` command.
|
59 |
|
60 | ### Updating Markdown doc
|
61 |
|
62 | **xplain** can update code blocks inside a Markdown file (like this doc) with unit tests marked using *@sample*. If we have:
|
63 |
|
64 | ```
|
65 | // add.js
|
66 | /** @sample add */
|
67 | gt.test('basic addition', function () {
|
68 | gt.equal(add(1, 2), 3, '1 + 2 = 3');
|
69 | gt.equal(add(100, -100), 0, '100 + -100 = 0');
|
70 | });
|
71 |
|
72 | // README.md
|
73 | #### basic addition
|
74 |
|
75 | add(10, 20); // 30
|
76 | ```
|
77 |
|
78 | then command `xplain -i add.js -o README.md` will update README.md and it will have:
|
79 |
|
80 | ```
|
81 | // README.md
|
82 | #### basic addition
|
83 |
|
84 | add(1, 2); // 3
|
85 | add(100, -100); // 0
|
86 | ```
|
87 |
|
88 | This feature makes the package's top level README.md file a great place to provide lots of examples, without needing a separate API docs. It can be also used to
|
89 | [unit test blog posts](http://bahmutov.calepin.co/unit-testing-blog-posts.html).
|
90 |
|
91 | ### Details
|
92 |
|
93 | Stop writing unmaintainable source samples inside the
|
94 | help comments using *@example* tag. Instead tag your unit tests with *@sample* or *@example* tag and they will be included in the generated API documentation.
|
95 |
|
96 | The test code will be intelligently transformed into human
|
97 | readable format. [QUnit](http://qunitjs.com/) and [gt](https://github.com/bahmutov/gt) test syntax is supported. If the code cannot be transformed, it will be displayed in its original form. *qunit* is assumed by default, specify an alternative using *-f* command line option, for example *-f gt*.
|
98 |
|
99 | #### Multiple documentation levels
|
100 |
|
101 | There are 4 levels of details captured in the API.
|
102 |
|
103 | 1. Method description from jsdoc comments
|
104 | 2. Sample source code transformed from the unit tests and displayed under the method
|
105 | 3. Unit test source code tagged *@example* can be displayed by clicking on the toggle
|
106 | 4. Finally the original function source code can be shown by clicking on the *source* button.
|
107 |
|
108 | ### Supported frameworks
|
109 |
|
110 | * [QUnit](http://qunitjs.com/)
|
111 | * [gt](https://github.com/bahmutov/gt)
|
112 | * [Jasmine/Mocha/Bdd](http://visionmedia.github.io/mocha/)
|
113 | * `console.assert` statements
|
114 | * [lazy-ass](https://github.com/bahmutov/lazy-ass) assertions
|
115 |
|
116 | ### Inspiration
|
117 |
|
118 | There are several API examples that I found particularly useful.
|
119 |
|
120 | * [lo-dash](http://lodash.com/docs) and [underscore](http://underscorejs.org/) APIs are beautiful and extremely easy to use.
|
121 | * [tooltipster](http://calebjacob.com/tooltipster/) gently introduces its features from basic use to more advanced.
|
122 | * [AngularJs](http://docs.angularjs.org/guide/expression) shows end to end unit test source as an example. The source code is not transformed from its original BDD Jasmine (?) style.
|
123 |
|
124 | ### New @- tags
|
125 |
|
126 | *xplain* uses two new custom [*jsdoc*](http://usejsdoc.org/) tags:
|
127 |
|
128 | 1. **@sample** - transforms the unit test that follows into human readable form and displays the code block
|
129 | right under the method's description.
|
130 | 2. **@example** - displays the unit test only when clicked on the button with the test's name.
|
131 |
|
132 |
|
133 | #### Example
|
134 |
|
135 | /** @sample Arrays/first */
|
136 | QUnit.test(function () {
|
137 | QUnit.equal(_.first([5,4,3,2,1]), 5, 'returns first element');
|
138 | QUnit.deepEqual(_.first([1,2,3], 2), [1, 2], 'can pass an index to first');
|
139 | });
|
140 |
|
141 | will be transformed into
|
142 |
|
143 | _.first([5, 4, 3, 2, 1]); // 5
|
144 | _.first([1, 2, 3], 2); // [1,2]
|
145 |
|
146 | If a unit test has a name, it will be displayed above the transformed code.
|
147 |
|
148 | ### Known issues
|
149 |
|
150 | On some systems, OS wildcard expansion can be misleading. For example on Windows when using Git bash shell, when calling using -i foo/\*.js the shell will expand wild card to match the FIRST file only. If you find that wildcard is not working as correctly, please switch the slash direction. For example -i foo\\*.js
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | ### 3<sup>rd</sup> party libraries
|
156 |
|
157 | * [lo-dash](https://github.com/bestiejs/lodash) is used throught the code to deal with collections. This library was the inspiration for this project, because it has an excellent API documentation.
|
158 | * [dox](https://github.com/visionmedia/dox) together with some custom glue parses JSdoc style comments.
|
159 | * [check-types](https://github.com/philbooth/check-types.js) is used to verify arguments through out the code.
|
160 | * [esprima](https://github.com/ariya/esprima) and [escodegen](https://github.com/Constellation/escodegen) are used to parse and reformat unit test code in human readable form.
|
161 | * [js-beautify](https://github.com/einars/js-beautify) is used for final example code formatting.
|
162 | * [jQuery](https://github.com/jquery/jquery) is used to drive UI in the generated HMTL documentation.
|
163 | * [google-code-prettify](https://google-code-prettify.googlecode.com) is used to syntax highlight code samples in the generated documentation.
|
164 | * [moment.js](http://momentjs.com/) is used for date and time manipulation.
|
165 | * [optimist](https://github.com/substack/node-optimist) is used to process command line arguments. I tried to use [commander.js](https://github.com/visionmedia/commander.js/), but it had problems grouping multiple arguments into arrays.
|
166 | * [background pattern](http://subtlepatterns.com/) is the source for the background pattern.
|
167 | * [glob](https://github.com/isaacs/node-glob) is used to find input source files using wildcards.
|
168 | * [allong.es](http://allong.es/) provides convenient functional bits and pieces.
|
169 | * [intro.js](https://github.com/usablica/intro.js) was used to create the [feature tour](http://bahmutov.github.io/xplain/)
|
170 | * [pithy](https://github.com/caolan/pithy) is used to programmatically generate the output HTML.
|
171 | * [html](https://github.com/maxogden/commonjs-html-prettyprinter) is used to beautify the output HMTL (tabs and stuff).
|
172 | * [mkdirp](https://github.com/substack/node-mkdirp) simplified folder creation.
|
173 | * [fs.extra](https://npmjs.org/package/fs.extra) simplified usual file operations (file copy, move).
|
174 | * [tooltipster](http://calebjacob.com/tooltipster/) is used in the generated API page to display tooltips.
|
175 | * [marked](https://npmjs.org/package/marked) to parse optional header markdown document to place in the output.
|
176 |
|
177 |
|
178 |
|
179 | ### Small print
|
180 |
|
181 | Author: Gleb Bahmutov © 2014
|
182 |
|
183 | * [@bahmutov](https://twitter.com/bahmutov)
|
184 | * [glebbahmutov.com](http://glebbahmutov.com)
|
185 | * [blog](http://bahmutov.calepin.co/)
|
186 |
|
187 | License: MIT - do anything with the code, but don't blame me if it does not work.
|
188 |
|
189 | Spread the word: tweet, star on github, etc.
|
190 |
|
191 | Support: if you find any problems with this module, email / tweet /
|
192 | [open issue](https://github.com/bahmutov/xplain/issues?state=open) on Github
|
193 |
|
194 |
|
195 |
|
196 | ## MIT License
|
197 |
|
198 | Copyright (c) 2014 Gleb Bahmutov
|
199 |
|
200 | Permission is hereby granted, free of charge, to any person
|
201 | obtaining a copy of this software and associated documentation
|
202 | files (the "Software"), to deal in the Software without
|
203 | restriction, including without limitation the rights to use,
|
204 | copy, modify, merge, publish, distribute, sublicense, and/or sell
|
205 | copies of the Software, and to permit persons to whom the
|
206 | Software is furnished to do so, subject to the following
|
207 | conditions:
|
208 |
|
209 | The above copyright notice and this permission notice shall be
|
210 | included in all copies or substantial portions of the Software.
|
211 |
|
212 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
213 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
214 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
215 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
216 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
217 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
218 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
219 | OTHER DEALINGS IN THE SOFTWARE.
|
220 |
|
221 |
|
222 |
|