Skip to content

Commit f2cdb63

Browse files
authored
Add API documentation (#447)
1 parent 3612a81 commit f2cdb63

File tree

6 files changed

+403
-21
lines changed

6 files changed

+403
-21
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ module.exports = {
9595

9696
[<sup>*</sup> Advanced use][14]
9797

98+
## API
99+
100+
Solidity-coverage's core methods and many utilities are available as an API.
101+
102+
```javascript
103+
const CoverageAPI = require('solidity-coverage/api');
104+
```
105+
106+
[Documentation available here][28].
107+
98108
## FAQ
99109

100110
Common problems & questions:
@@ -171,3 +181,4 @@ $ yarn
171181
[25]: https://github.com/sc-forks/solidity-coverage/issues/417
172182
[26]: https://buidler.dev/
173183
[27]: https://www.trufflesuite.com/docs
184+
[28]: https://github.com/sc-forks/solidity-coverage/blob/beta/docs/api.md

docs/api.md

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
# Solidity-Coverage API Documentation
2+
3+
`solidity-coverage`'s API provides test coverage measurement for the Solidity language.
4+
The repository contains two complete coverage tool/plugin implementations (for Buidler and Truffle)
5+
which can be used as sources if you're building something similar.
6+
7+
`solidity-coverage`'s core algorithm resembles the one used by [Istanbul][3] for javascript programs.
8+
It tracks line and branch locations by 'instrumenting' solidity contracts with special solidity
9+
statements and detecting their execution in a coverage-enabled EVM. As such, its API spans the
10+
full set of tasks typically required to run a solidity test suite.
11+
12+
+ compile
13+
+ ethereum client launch
14+
+ test
15+
+ report outcome and exit
16+
17+
[3]: https://github.com/gotwarlost/istanbul
18+
19+
The API's corresponding methods are:
20+
21+
+ `instrument`: Rewrites contracts for instrumented compilation. Generates an instrumentation data map.
22+
+ `ganache`: Launches a ganache client with coverage collection enabled in its VM. As the client
23+
runs it will mark line/branch hits on the instrumentation data map.
24+
+ `report`: Generates a coverage report from the data collected by the VM after tests complete. Converts
25+
the instrumentation data map into an object IstanbulJS can process.
26+
+ `finish`: Shuts client down
27+
28+
The library also includes some file system [utilities](#Utils) which are helpful for managing the
29+
disposable set of contracts/artifacts which coverage must use in lieu of the 'real' contracts/artifacts.
30+
31+
# Table of Contents
32+
33+
- [API Methods](#api)
34+
* [constructor](#constructor)
35+
* [instrument](#instrument)
36+
* [ganache](#ganache)
37+
* [report](#report)
38+
* [finish](#finish)
39+
* [getInstrumentationData](#getinstrumentationdata)
40+
* [setInstrumentationData](#setinstrumentationdata)
41+
- [Utils Methods](#utils)
42+
* [loadSolcoverJS](#loadsolcoverjs)
43+
* [assembleFiles](#assemblefiles)
44+
* [getTempLocations](#gettemplocations)
45+
* [setupTempFolders](#setuptempfolders)
46+
* [save](#save)
47+
* [finish](#finish-1)
48+
49+
# API
50+
51+
**Example**
52+
```javascript
53+
const CoverageAPI = require("solidity-coverage/api");
54+
const api = new CoverageAPI(options);
55+
```
56+
57+
## constructor
58+
59+
Creates a coverage API instance. Configurable.
60+
61+
**Parameters**
62+
63+
- `options` **Object** : API options
64+
65+
| Option <img width=200/>| Type <img width=200/> | Default <img width=1300/> | Description <img width=800/> |
66+
| ------ | ---- | ------- | ----------- |
67+
| port | *Number* | 8555 | Port to launch client on |
68+
| silent | *Boolean* | false | Suppress logging output |
69+
| client | *Object* | `require("ganache-core")` | JS Ethereum client |
70+
| providerOptions | *Object* | `{ }` | [ganache-core options][1] |
71+
| skipFiles | *Array* | `[]` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. |
72+
| istanbulFolder | *String* | `./coverage` | Folder location for Istanbul coverage reports. |
73+
| istanbulReporter | *Array* | `['html', 'lcov', 'text', 'json']` | [Istanbul coverage reporters][2] |
74+
75+
[1]: https://github.com/trufflesuite/ganache-core#options
76+
[2]: https://istanbul.js.org/docs/advanced/alternative-reporters/
77+
78+
--------------
79+
80+
## instrument
81+
82+
Instruments a set of sources to prepare them for compilation.
83+
84+
:warning: **Important:** Instrumented sources must be compiled with **solc optimization OFF** :warning:
85+
86+
**Parameters**
87+
88+
- `contracts` **Object[]**: Array of solidity sources and their paths
89+
90+
Returns **Object[]** in the same format as the `contracts` param, but with sources instrumented.
91+
92+
**Example**
93+
```javascript
94+
const contracts = [{
95+
source: "contract Simple { uint x = 5; }",
96+
canonicalPath: "/Users/user/project/contracts/Simple.sol",
97+
relativePath: "Simple.sol" // Optional, used for pretty printing.
98+
},...]
99+
100+
const instrumented = api.instrument(contracts)
101+
```
102+
103+
--------------
104+
105+
## ganache
106+
107+
Enables coverage data collection on an in-process ganache server. By default, will return
108+
a url after server has begun listening on the port specified in the [config](#constructor)
109+
(or 8555 by default). When `autoLaunchServer` is false, method returns`ganache.server`
110+
so the consumer can control the 'server.listen' invocation themselves.
111+
112+
**Parameters**
113+
114+
- `client` **Object**: (*Optional*) ganache module
115+
- `autoLaunchServer` **Boolean**: (*Optional*)
116+
117+
Returns **Promise** Address of server to connect to, or initialized, unlaunched server
118+
119+
**Example**
120+
```javascript
121+
const client = require('ganache-cli');
122+
123+
const api = new CoverageAPI( { client: client } );
124+
const address = await api.ganache();
125+
126+
> http://127.0.0.1:8555
127+
128+
// Alternatively...
129+
130+
const server = await api.ganache(client, false);
131+
await pify(server.listen()(8545));
132+
```
133+
134+
--------------
135+
136+
## report
137+
138+
Generates coverage report using IstanbulJS
139+
140+
**Parameters**
141+
142+
- `istanbulFolder` **String**: (*Optional*) path to folder IstanbulJS will deposit coverage reports in.
143+
144+
Returns **Promise**
145+
146+
**Example**
147+
```javascript
148+
await api.report('./coverage_4A3cd2b'); // Default folder name is 'coverage'
149+
```
150+
151+
-------------
152+
153+
## finish
154+
155+
Shuts down coverage-enabled ganache server instance
156+
157+
Returns **Promise**
158+
159+
**Example**
160+
```javascript
161+
const client = require('ganache-cli');
162+
163+
await api.ganache(client); // Server listening...
164+
await api.finish(); // Server shut down.
165+
```
166+
167+
-------------
168+
169+
## getInstrumentationData
170+
171+
Returns a copy of the hit map created during instrumentation. Useful if you'd like to delegate
172+
coverage collection to multiple processes.
173+
174+
Returns **Object** instrumentation data;
175+
176+
177+
**Example**
178+
```javascript
179+
const contracts = api.instrument(contracts);
180+
const data = api.getInstrumentationData();
181+
save(data);
182+
```
183+
184+
-------------
185+
186+
## setInstrumentationData
187+
188+
Sets the hit map object generated during instrumentation. Useful if you'd like
189+
to collect or convert data to coverage for an instrumentation which was generated
190+
in a different process.
191+
192+
**Example**
193+
```javascript
194+
const data = load(data);
195+
api.setIntrumentationData(data);
196+
197+
// Client will collect data for the loaded map
198+
const address = await api.ganache(client);
199+
200+
// Or to `report` instrumentation data which was collected in a different process.
201+
const data = load(data);
202+
api.setInstrumentationData(data);
203+
204+
api.report();
205+
```
206+
207+
----------------------------------------------------------------------------------------------------
208+
209+
# Utils
210+
211+
```javascript
212+
const utils = require('solidity-coverage/utils');
213+
```
214+
215+
Many of the utils methods take a `config` object param which
216+
defines the absolute paths to your project root and contracts directory.
217+
218+
**Example**
219+
```javascript
220+
const config = {
221+
workingDir: process.cwd(),
222+
contractsDir: path.join(process.cwd(), 'contracts'),
223+
}
224+
```
225+
-------------
226+
227+
## loadSolcoverJS
228+
229+
Loads `.solcoverjs`. Users may specify options described in the README in `.solcover.js` config
230+
file which your application needs to consume.
231+
232+
**Parameters**
233+
234+
- `config` **Object**: [See *config* above](#Utils)
235+
236+
Returns **Object** Normalized coverage config
237+
238+
239+
**Example**
240+
```javascript
241+
const solcoverJS = utils.loadSolcoverJS(config);
242+
const api = new CoverageAPI(solcoverJS);
243+
```
244+
245+
-------------
246+
247+
## assembleFiles
248+
249+
Loads contracts from the filesystem in a format that can be passed directly to the
250+
[api.instrument](#instrument) method. Filters by an optional `skipFiles` parameter.
251+
252+
**Parameters**
253+
254+
- `config` **Object**: [See *config* above](#Utils)
255+
- `skipFiles` **String[]**: (*Optional*) Array of files or folders to skip
256+
[See API *constructor*](#constructor)
257+
258+
Returns **Object** with `targets` and `skipped` keys. These are Object arrays of contract sources
259+
and paths.
260+
261+
**Example**
262+
```javascript
263+
const {
264+
targets,
265+
skipped
266+
} = utils.assembleFiles(config, ['Migrations.sol'])
267+
268+
const instrumented = api.instrument(targets);
269+
```
270+
271+
--------------
272+
273+
## getTempLocations
274+
275+
Returns a pair of canonically named temporary directory paths for contracts
276+
and artifacts. Instrumented assets can be compiled from and written to these so the unit tests can
277+
use them as sources.
278+
279+
**Parameters**
280+
281+
- `config` **Object**: [See *config* above](#Utils)
282+
283+
Returns **Object** with two absolute paths to disposable folders, `tempContractsDir`, `tempArtifactsDir`.
284+
These directories are named `.coverage_contracts` and `.coverage_artifacts`.
285+
286+
**Example**
287+
```javascript
288+
const {
289+
tempContractsDir,
290+
tempArtifactsDir
291+
} = utils.getTempLocations(config)
292+
293+
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir)
294+
295+
// Later, you can call `utils.finish` to delete these...
296+
utils.finish(config, api)
297+
```
298+
299+
----------
300+
301+
## setupTempFolders
302+
303+
Creates temporary directories to store instrumented contracts and their compilation artifacts in.
304+
305+
**Parameters**
306+
307+
- `config` **Object**: [See *config* above](#Utils)
308+
- `tempContractsDir` **String**: absolute path to temporary contracts directory
309+
- `tempArtifactsDir` **String**: absolute path to temporary artifacts directory
310+
311+
**Example**
312+
```javascript
313+
const {
314+
tempContractsDir,
315+
tempArtifactsDir
316+
} = utils.getTempLocations(config)
317+
318+
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);
319+
```
320+
-------------
321+
322+
## save
323+
324+
Writes an array of instrumented sources in the object format returned by
325+
[api.instrument](#instrument) to a temporary directory.
326+
327+
**Parameters**
328+
329+
- `contracts` **Object[]**: array of contracts & paths generated by [api.instrument](#instrument)
330+
- `originalDir` **String**: absolute path to original contracts directory
331+
- `tempDir` **String**: absolute path to temp contracts directory (the destination of the save)
332+
333+
**Example**
334+
```javascript
335+
const {
336+
tempContractsDir,
337+
tempArtifactsDir
338+
} = utils.getTempLocations(config)
339+
340+
utils.setupTempFolders(config, tempContractsDir, tempArtifactsDir);
341+
342+
const instrumented = api.instrument(targets);
343+
344+
utils.save(instrumented, config.contractsDir, tempContractsDir);
345+
```
346+
347+
-------------
348+
349+
## finish
350+
351+
Deletes temporary folders and shuts the ganache server down. Is tolerant - if folders or ganache
352+
server don't exist it will return silently.
353+
354+
**Parameters**
355+
356+
- `config` **Object**: [See *config* above](#Utils)
357+
- `api` **Object**: (*Optional*) coverage api instance whose own `finish` method will be called
358+
359+
Returns **Promise**
360+
361+
**Example**
362+
```javascript
363+
await utils.finish();
364+
```
365+
366+
367+
368+

0 commit comments

Comments
 (0)