Skip to content

Commit 82dd03d

Browse files
authored
Run tests against API, not against binary (#55)
1 parent 43bc4be commit 82dd03d

File tree

14 files changed

+124
-171
lines changed

14 files changed

+124
-171
lines changed

bin/Extract.re

Lines changed: 45 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,60 @@
11
open Lib;
22

3-
module StringMap = Map.Make(String);
4-
5-
let messages = ref(StringMap.empty);
6-
7-
let duplicatesAreAllowed = ref(false);
8-
9-
let iterator =
10-
ExtractionIterator.getIterator(message => {
11-
let {Message.id, defaultMessage} = message;
12-
switch (messages^ |> StringMap.find_opt(id)) {
13-
| None => messages := messages^ |> StringMap.add(id, message)
14-
| Some(existingMessage) when duplicatesAreAllowed^ && defaultMessage == existingMessage.defaultMessage =>
15-
messages := messages^ |> StringMap.add(id, message)
16-
| Some(existingMessage) when duplicatesAreAllowed^ && defaultMessage != existingMessage.defaultMessage =>
17-
Printf.eprintf("Error: duplicate message id: %s with different default messages\n", id);
18-
exit(3);
19-
| Some(_) =>
20-
Printf.eprintf("Error: duplicate message id: %s\n", id);
21-
exit(3);
22-
};
23-
});
24-
25-
let extractMessages = ast => iterator.structure(iterator, ast);
26-
27-
let processReasonFile = path => {
28-
let channel = open_in_bin(path);
29-
let lexbuf = Lexing.from_channel(channel);
30-
let ast = Reason_toolchain.(RE.implementation(lexbuf) |> To_current.copy_structure);
31-
close_in(channel);
32-
33-
extractMessages(ast);
34-
};
35-
36-
let rec processPath = path => {
37-
if (!Sys.file_exists(path)) {
3+
let extract = (~duplicatesAllowed, paths) =>
4+
try({
5+
let messages = Extractor.extract(~duplicatesAllowed, paths);
6+
7+
`List(messages |> List.map(Message.toJson)) |> Yojson.Basic.pretty_to_channel(stdout);
8+
print_newline();
9+
}) {
10+
| Extractor.PathNotFound(path) =>
3811
Printf.eprintf("Error: file or directory does not exist: %s\n", path);
3912
exit(1);
40-
};
4113

42-
if (Sys.is_directory(path)) {
43-
Sys.readdir(path) |> Array.iter(filename => processPath(Filename.concat(path, filename)));
44-
} else if (Filename.extension(path) == ".re") {
45-
processReasonFile(path);
46-
};
47-
};
48-
49-
let outputJson = () => {
50-
let sortedJsonObjects =
51-
messages^
52-
|> StringMap.bindings
53-
|> List.map(((_id, message)) => message)
54-
|> List.sort(Message.compare)
55-
|> List.map(Message.toJson);
56-
57-
Yojson.Basic.pretty_to_channel(stdout, `List(sortedJsonObjects));
58-
print_newline();
59-
};
14+
| Extractor.DuplicateMessageId(id) =>
15+
Printf.eprintf("Error: duplicate message id: %s\n", id);
16+
exit(2);
6017

61-
let inputFilenames = ref([]);
18+
| Extractor.DefaultMessageNotMatching(id) =>
19+
Printf.eprintf("Error: duplicate message id: %s with different default messages\n", id);
20+
exit(3);
6221

63-
let processInputFilename = filename => inputFilenames := [filename, ...inputFilenames^];
22+
| exn =>
23+
Printf.eprintf("Unexpected error: %s\n", Printexc.to_string(exn));
24+
exit(10);
25+
};
6426

65-
let showVersion = () => {
66-
print_endline(Version.version);
67-
exit(0);
27+
type options = {
28+
showVersion: bool,
29+
paths: list(string),
30+
duplicatesAllowed: bool,
6831
};
6932

70-
let allowDuplicates = () => duplicatesAreAllowed := true;
33+
let run = () => {
34+
let options = ref({showVersion: false, paths: [], duplicatesAllowed: false});
35+
36+
let processInputFilename = filename => options := {...options^, paths: [filename, ...options^.paths]};
37+
let allowDuplicates = () => options := {...options^, duplicatesAllowed: true};
38+
let showVersion = () => options := {...options^, showVersion: true};
7139

72-
let args = [
73-
("-v", Arg.Unit(showVersion), "shows the program version"),
74-
(
75-
"--allow-duplicates",
76-
Arg.Unit(allowDuplicates),
77-
"allows messages with identical `id` props if `defaultMessage` props are identical as well",
78-
),
79-
];
40+
let args = [
41+
("-v", Arg.Unit(showVersion), "shows the program version"),
42+
(
43+
"--allow-duplicates",
44+
Arg.Unit(allowDuplicates),
45+
"allows messages with identical `id` props if `defaultMessage` props are identical as well",
46+
),
47+
];
8048

81-
let usage = "Usage: " ++ Sys.argv[0] ++ " [path...]";
49+
let usage = "Usage: " ++ Sys.argv[0] ++ " [path...]";
8250

83-
Arg.parse(args, processInputFilename, usage);
51+
Arg.parse(args, processInputFilename, usage);
8452

85-
switch (inputFilenames^) {
86-
| [] => Arg.usage(args, usage)
87-
| filenames =>
88-
filenames |> List.rev |> List.iter(processPath);
89-
outputJson();
53+
switch (options^) {
54+
| {showVersion: true} => print_endline(Version.version)
55+
| {paths: []} => Arg.usage(args, usage)
56+
| {paths, duplicatesAllowed} => extract(~duplicatesAllowed, paths)
57+
};
9058
};
59+
60+
run();

bin/dune

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
(executable
22
(name Extract)
33
(public_name Extract.exe)
4-
(flags (:standard -w -9))
54
(libraries lib)
65
)

dune

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
(env
2+
(dev
3+
(flags (:standard -w -9)))
4+
(release
5+
(flags (:standard -w -9))))

lib/ExtractionIterator.re

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ open Parsetree;
66

77
open Longident;
88

9-
module StringMap = Map.Make(String);
10-
119
let extractMessageFromLabels = (callback, labels) => {
1210
let map =
1311
labels

lib/Extractor.re

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
exception PathNotFound(string);
2+
exception DuplicateMessageId(string);
3+
exception DefaultMessageNotMatching(string);
4+
5+
let extract = (~duplicatesAllowed=false, paths) => {
6+
let messages = ref(StringMap.empty);
7+
8+
let iterator =
9+
ExtractionIterator.getIterator(message => {
10+
let {Message.id, defaultMessage} = message;
11+
12+
switch (messages^ |> StringMap.find_opt(id)) {
13+
| None => messages := messages^ |> StringMap.add(id, message)
14+
15+
| Some(existingMessage) when duplicatesAllowed && defaultMessage == existingMessage.defaultMessage =>
16+
messages := messages^ |> StringMap.add(id, message)
17+
18+
| Some(existingMessage) when duplicatesAllowed && defaultMessage != existingMessage.defaultMessage =>
19+
raise(DefaultMessageNotMatching(id))
20+
21+
| Some(_) => raise(DuplicateMessageId(id))
22+
};
23+
});
24+
25+
let extractMessages = ast => iterator.structure(iterator, ast);
26+
27+
let processReasonFile = path => {
28+
let channel = open_in_bin(path);
29+
let lexbuf = Lexing.from_channel(channel);
30+
let ast = Reason_toolchain.(RE.implementation(lexbuf) |> To_current.copy_structure);
31+
close_in(channel);
32+
33+
extractMessages(ast);
34+
};
35+
36+
let rec processPath = path => {
37+
if (!Sys.file_exists(path)) {
38+
raise(PathNotFound(path));
39+
};
40+
41+
if (Sys.is_directory(path)) {
42+
Sys.readdir(path) |> Array.iter(filename => processPath(Filename.concat(path, filename)));
43+
} else if (Filename.extension(path) == ".re") {
44+
processReasonFile(path);
45+
};
46+
};
47+
48+
paths |> List.iter(processPath);
49+
messages^ |> StringMap.bindings |> List.map(((_id, message)) => message) |> List.sort(Message.compare);
50+
};

lib/Message.re

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
module StringMap = Map.Make(String);
2-
31
type t = {
42
id: string,
53
defaultMessage: string,
@@ -18,7 +16,7 @@ let fromStringMap = map => {
1816
};
1917
};
2018

21-
let toJson = ({id, defaultMessage, description}) =>
19+
let toJson = ({id, defaultMessage, description}): Yojson.Basic.t =>
2220
switch (description) {
2321
| Some(description) =>
2422
`Assoc([

lib/StringMap.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include Map.Make(String);

lib/dune

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
(library
22
(name lib)
33
(public_name bs-react-intl-extractor)
4-
(flags (:standard -w -9))
54
(libraries reason yojson unix)
65
)
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
Duplicates › allowOk
1+
Duplicates › allowedOk
22
[
33
{ \"id\": \"test3.msg1.1\", \"defaultMessage\": \"This is message 1.1\" },
44
{ \"id\": \"test3.msg1.2\", \"defaultMessage\": \"This is message 1.2\" },
55
{ \"id\": \"test3.msg1.3\", \"defaultMessage\": \"This is message 1.3\" }
66
]
7-

test/__snapshots__/Extract.372ae0d1.0.snapshot

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ Extract › partial
88
},
99
{ \"id\": \"test2.msg1.1\", \"defaultMessage\": \"This is message 2.1.1\" }
1010
]
11-

0 commit comments

Comments
 (0)