Skip to content

Commit 85b720f

Browse files
committed
Add mocha_test rule.
- Rule implementation. - Add explanation in README. - Adds transitive_node_modules to node_library.
1 parent b633c0f commit 85b720f

File tree

12 files changed

+243
-40
lines changed

12 files changed

+243
-40
lines changed

README.md

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,8 @@ node_repositories()
3232
| [npm_repository](#npm_repository) | Install a set of npm dependencies. |
3333
| [node_library](#node_library) | Define a local npm module. |
3434
| [node_binary](#node_binary) | Build or execute a nodejs script. |
35+
| [mocha_test](#mocha_test) | Run a mocha test script. |
3536

36-
# Example
37-
38-
```python
39-
load("@org_pubref_rules_node//node:rules.bzl", "node_binary")
40-
41-
node_binary(
42-
name = "foo",
43-
main = "foo.js",
44-
modules = [
45-
"@npm_react_stack//:modules",
46-
],
47-
)
48-
```
4937

5038
## node_repositories
5139

@@ -152,7 +140,46 @@ makes this very clean and convenient.
152140
## node_binary
153141
154142
Creates an executable script that will run the file named in the
155-
`main_script` attribute. Paths to dependent `node_library` and
143+
`main` attribute. Paths to dependent `node_library` and
156144
`@npm_repository//:modules` labels are used to construct a `NODE_PATH`
157145
environment variable that the `node` executable will use to fulfill
158146
`require` dependencies.
147+
148+
```python
149+
load("@org_pubref_rules_node//node:rules.bzl", "node_binary")
150+
151+
node_binary(
152+
name = "foo",
153+
main = "foo.js",
154+
modules = [
155+
"@npm_react_stack//:modules",
156+
],
157+
)
158+
```
159+
160+
161+
## mocha_test
162+
163+
Runs a mocha test identified by the start script given in `main`.
164+
External modules dependencies can be listed in the `modules`
165+
attribute, while internal module dependencies are named in the `deps`
166+
attribute. Additional arguments to the `mocha` script runner can be
167+
listed in the `mocha_args` attribute.
168+
169+
```python
170+
load("@org_pubref_rules_node//node:rules.bzl", "mocha_test")
171+
172+
mocha_test(
173+
name = "foo_test",
174+
main = "foo_test.js",
175+
modules = [
176+
"@npm_underscore//:modules",
177+
],
178+
deps = [
179+
"//examples/baz",
180+
],
181+
mocha_args = [
182+
"--reporter=dot",
183+
]
184+
)
185+
```

WORKSPACE

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@ npm_repository(
2121
)
2222

2323
npm_repository(
24-
name = "npm_webpack",
24+
name = "npm_mocha",
2525
deps = {
26-
"webpack": "1.13.2",
26+
"mocha": "3.1.0",
2727
},
28-
sha256 = "705fac8595a57368185ac25f0a54bac475f4646285b4bc4af650ae754ac56e2b",
28+
sha256 = "9b48987065bb42003bab81b4538afa9ac194d217d8e2e770a5cba782249f7dc8",
29+
)
30+
31+
npm_repository(
32+
name = "npm_underscore",
33+
deps = {
34+
"underscore": "1.8.3",
35+
},
36+
sha256 = "7c413345ad4f97024258e5d9fda40e26be0f2c2b73987d13f03352b5c489b1a8",
2937
)
3038

3139
npm_repository(

examples/foo/BUILD

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
1-
load("//node:rules.bzl", "node_binary")
1+
load("//node:rules.bzl", "node_binary", "mocha_test")
22

33
node_binary(
44
name = "foo",
55
main = "foo.js",
66
modules = [
77
"@npm_react_stack//:modules",
8-
"@npm_glob//:modules",
98
],
109
deps = [
1110
"//examples/baz",
1211
]
1312
)
13+
14+
mocha_test(
15+
name = "foo_test",
16+
main = "foo_test.js",
17+
modules = ["@npm_underscore//:modules"],
18+
deps = [
19+
"//examples/baz",
20+
],
21+
mocha_args = [
22+
"--reporter=dot"
23+
]
24+
)

examples/foo/foo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// stdlib dependency
22
var process = require("process");
33
// npm_repository module dependency
4-
var glob = require("glob");
4+
var react = require("react");
55
// local module dependency
66
var baz = require("examples-baz");
77
// relative file dependency

examples/foo/foo_test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var assert = require('assert');
2+
var baz = require('examples-baz');
3+
var _ = require('underscore');
4+
5+
describe('Array', function() {
6+
describe('#indexOf()', function() {
7+
it('should return -1 when the value is not present', function() {
8+
assert.equal(-1, [1,2,3].indexOf(4));
9+
});
10+
});
11+
});
12+
13+
describe('baz', function() {
14+
describe('#value', function() {
15+
it('should return a function', function() {
16+
assert.equal("function", typeof(baz));
17+
//assert.ok(baz.indexOf("baz") != -1);
18+
});
19+
it('should resolve to string', function() {
20+
assert.equal("string", typeof(baz()));
21+
//assert.ok(baz.indexOf("baz") != -1);
22+
});
23+
it('should resolve to module name', function() {
24+
assert.ok(baz().match(/.*[bB]az.*/));
25+
});
26+
});
27+
});

examples/webpack/BUILD

Lines changed: 0 additions & 9 deletions
This file was deleted.

node/internal/dar.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ def dar_execute(ctx, dar_root=None):
3434
"--file", "%s=%s" % (dar_filename, dar_root),
3535
]
3636

37-
print("dar: %s" % cmd)
37+
#print("dar: %s" % cmd)
3838
return execute(ctx, cmd)

node/internal/mocha_test.bzl

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
_js_filetype = FileType([".js"])
2+
_modules_filetype = FileType(["node_modules"])
3+
4+
BASH_TEMPLATE = """
5+
#!/usr/bin/env bash
6+
set -e
7+
8+
# Resolve to 'this' node instance if other scripts
9+
# have '/usr/bin/env node' shebangs
10+
export PATH={node_bin_path}:$PATH
11+
12+
# Used by NPM
13+
export NODE_PATH={node_paths}
14+
15+
# Run it
16+
"{node}" "{mocha}" {mocha_args} "{script_path}" $@
17+
"""
18+
19+
20+
def _get_abs_sourcepath(file):
21+
filename = str(file)
22+
#print("filename: %s" % filename)
23+
parts = filename.partition("[source]]")
24+
prefix = parts[0][len("Artifact:["):]
25+
suffix = parts[2]
26+
d = "/".join([prefix, suffix])
27+
#print("abs filename: %s" % d)
28+
return d
29+
30+
31+
def _get_node_modules_dir_from_binfile(file):
32+
bin = str(file)
33+
parts = bin.partition("[source]]")
34+
prefix = parts[0][len("Artifact:["):]
35+
suffix_parts = parts[2].split("/")
36+
#print("prefix: %s, suffix_parts: %s" % (prefix, suffix_parts))
37+
return "/".join([prefix] + suffix_parts[0:2] + ["node_modules"])
38+
39+
40+
def _get_node_modules_dir_from_package_json(file):
41+
filename = str(file)
42+
parts = filename.split("]")
43+
prefix = parts[0][len("Artifact:[["):]
44+
middle = parts[1]
45+
suffix = parts[2].split("/")
46+
d = "/".join([prefix, middle] + suffix[0:-3] + ["node_modules"])
47+
return d
48+
49+
50+
51+
def mocha_test_impl(ctx):
52+
inputs = []
53+
srcs = []
54+
script = ctx.file.main
55+
node = ctx.file._node
56+
mocha = ctx.file.mocha
57+
node_paths = []
58+
node_paths.append(_get_node_modules_dir_from_binfile(mocha))
59+
60+
mocha_path = _get_abs_sourcepath(mocha)
61+
62+
for file in ctx.files.modules:
63+
#print("file: %s" % file)
64+
if not file.basename.endswith("node_modules"):
65+
fail("npm_dependency should be a path to a node_modules/ directory.")
66+
node_paths += [_get_node_modules_dir_from_binfile(file)]
67+
68+
for dep in ctx.attr.deps:
69+
lib = dep.node_library
70+
srcs += lib.transitive_srcs
71+
inputs += [lib.package_json, lib.npm_package_json]
72+
node_paths += [_get_node_modules_dir_from_package_json(lib.package_json)]
73+
for file in lib.transitive_node_modules:
74+
node_paths += [file.path]
75+
inputs.append(file)
76+
77+
node_paths = list(set(node_paths))
78+
79+
ctx.file_action(
80+
output = ctx.outputs.executable,
81+
executable = True,
82+
content = BASH_TEMPLATE.format(
83+
node_paths = ":".join(node_paths),
84+
node = node.short_path,
85+
node_bin_path = node.dirname,
86+
script_path = script.short_path,
87+
mocha = mocha_path,
88+
mocha_args = " ".join(ctx.attr.mocha_args),
89+
),
90+
)
91+
92+
#print("node_paths %s" % "\n".join(node_paths))
93+
94+
runfiles = [node, script] + inputs + srcs
95+
96+
return struct(
97+
runfiles = ctx.runfiles(
98+
files = runfiles,
99+
),
100+
)
101+
102+
103+
mocha_test = rule(
104+
mocha_test_impl,
105+
attrs = {
106+
"main": attr.label(
107+
single_file = True,
108+
allow_files = True,
109+
#allow_files = _js_filetype,
110+
),
111+
"data": attr.label_list(
112+
allow_files = True,
113+
),
114+
"deps": attr.label_list(
115+
providers = ["node_library"],
116+
),
117+
"modules": attr.label_list(
118+
allow_files = _modules_filetype,
119+
),
120+
"_node": attr.label(
121+
default = Label("@org_pubref_rules_node_toolchain//:node_tool"),
122+
single_file = True,
123+
allow_files = True,
124+
executable = True,
125+
cfg = "host",
126+
),
127+
"mocha": attr.label(
128+
default = Label("@npm_mocha//:bin/mocha"),
129+
allow_files = True,
130+
single_file = True,
131+
),
132+
"mocha_modules": attr.label(
133+
default = Label("@npm_mocha//:modules"),
134+
),
135+
"mocha_args": attr.string_list(),
136+
},
137+
test = True,
138+
)

node/internal/node_binary.bzl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ def node_binary_impl(ctx):
5050
for dep in ctx.attr.deps:
5151
lib = dep.node_library
5252
srcs += lib.transitive_srcs
53-
inputs += [lib.package_json]
54-
inputs += [lib.npm_package_json]
53+
inputs += [lib.package_json, lib.npm_package_json]
5554
node_paths += [_get_node_modules_dir_from_package_json(lib.package_json)]
55+
for file in lib.transitive_node_modules:
56+
inputs.append(file)
57+
node_paths += [file.path]
5658

5759
node_paths = list(set(node_paths))
5860

node/internal/node_library.bzl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def _copy_to_namespace(base, file):
4040
def node_library_impl(ctx):
4141
node = ctx.executable._node
4242
npm = ctx.executable._npm
43+
modules = ctx.attr.modules
44+
4345
lib_name = _get_lib_name(ctx)
4446
stage_name = lib_name + ".npmfiles"
4547

@@ -53,9 +55,7 @@ def node_library_impl(ctx):
5355
npm_package_json_file = ctx.new_file("lib/node_modules/%s/package.json" % lib_name)
5456

5557
transitive_srcs = []
56-
57-
modules = ctx.attr.modules
58-
transitive_modules = []
58+
transitive_node_modules = []
5959

6060
files = []
6161
for d in ctx.attr.data:
@@ -65,7 +65,7 @@ def node_library_impl(ctx):
6565
for dep in ctx.attr.deps:
6666
lib = dep.node_library
6767
transitive_srcs += lib.transitive_srcs
68-
transitive_modules += lib.transitive_modules
68+
transitive_node_modules += lib.transitive_node_modules
6969

7070
ctx.template_action(
7171
template = package_json_template_file,
@@ -125,8 +125,7 @@ def node_library_impl(ctx):
125125
label = ctx.label,
126126
srcs = srcs,
127127
transitive_srcs = srcs + transitive_srcs,
128-
modules = modules,
129-
transitive_modules = modules + transitive_modules,
128+
transitive_node_modules = ctx.files.modules + transitive_node_modules,
130129
package_json = npm_package_json_file,
131130
npm_package_json = npm_package_json_file,
132131
),

0 commit comments

Comments
 (0)