-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Add unit tests for Process module. Factor out Asserter into its own module. Reviewed By: hubyrod Differential Revision: D4386577 fbshipit-source-id: 46be3be54cf3e2a37a681e18131cb93cb468c876
- Loading branch information
Showing
4 changed files
with
166 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
module type Comparator = sig | ||
type t | ||
val to_string : t -> string | ||
val is_equal : t -> t -> bool | ||
end;; | ||
|
||
|
||
module String_comparator = struct | ||
type t = string | ||
let to_string x = x | ||
let is_equal x y = x = y | ||
end;; | ||
|
||
|
||
module Process_status_comparator = struct | ||
type t = Unix.process_status | ||
let to_string v = match v with | ||
| Unix.WEXITED i -> | ||
Printf.sprintf "Unix.WEXITED %d" i | ||
| Unix.WSIGNALED i -> | ||
Printf.sprintf "Unix.WSIGNALED %d" i | ||
| Unix.WSTOPPED i -> | ||
Printf.sprintf "Unix.WSTOPPED %d" i | ||
|
||
let is_equal exp actual = exp = actual | ||
end;; | ||
|
||
|
||
module type Pattern_substitutions = sig | ||
(** List of key-value pairs. We perform these key to value | ||
* substitutions in-order. | ||
* | ||
* For example, consider the substitions: | ||
* [ ("foo", "bar"); ("bar", "world"); ] | ||
* | ||
* being appied to the string: | ||
* "hello {{foo}}" | ||
* | ||
* which gets transformed to: | ||
* "hello {bar}" | ||
* | ||
* then finally to: | ||
* "hello world" | ||
* | ||
* Note: in actuality, the keys and values aren't treated as string literals | ||
* but as a pattern for regex and a template for replacement. | ||
*) | ||
val substitutions : (string * string) list | ||
end;; | ||
|
||
|
||
(** Comparison between an expected pattern and an actual string. *) | ||
module Pattern_comparator(Substitutions : Pattern_substitutions) = struct | ||
type t = string | ||
|
||
let apply_substitutions s = | ||
List.fold_left (fun acc (k, v) -> | ||
let re = Str.regexp ("{" ^ k ^ "}") in | ||
Str.global_replace re v acc | ||
) s Substitutions.substitutions | ||
|
||
(** Argh, due to the signature of Comparator, the "expected" and | ||
* "actual" have the same type, even though for this Pattern_comparator | ||
* we would really like them to be different. We'd like "actual" to | ||
* be type string, and "epxected" to be type "pattern", and | ||
* so we can apply the substitutions to only the pattern. But splitting | ||
* them out into different types for all the modules only because this module | ||
* needs it isn't really worth it. Oh well. So we treat actual as a pattern | ||
* as well and apply substitutions - oh well. *) | ||
let to_string s = apply_substitutions s | ||
let is_equal expected actual = | ||
let expected = apply_substitutions expected in | ||
expected = actual | ||
end;; | ||
|
||
|
||
module Make_asserter (Comp : Comparator) = struct | ||
|
||
let assert_equals exp actual failure_msg = | ||
if Comp.is_equal exp actual then | ||
() | ||
else | ||
let () = Printf.eprintf "Expected: %s; But Found: %s\n" | ||
(Comp.to_string exp) (Comp.to_string actual) in | ||
let () = Printf.eprintf "%s" failure_msg in | ||
assert false | ||
|
||
let assert_list_equals exp actual failure_msg = | ||
if (List.length exp) = (List.length actual) then | ||
List.iter2 (fun exp actual -> | ||
assert_equals exp actual failure_msg) | ||
exp actual | ||
else | ||
let () = Printf.eprintf | ||
"assert_list_equals failed. Counts not equal\n" in | ||
let exp_strs = List.map Comp.to_string exp in | ||
let actual_strs = List.map Comp.to_string actual in | ||
let () = Printf.eprintf | ||
"Expected:\n%s\n\n But Found:\n%s\n" | ||
(String.concat "\n" exp_strs) (String.concat "\n" actual_strs) in | ||
let () = Printf.eprintf "%s" failure_msg in | ||
assert false | ||
|
||
end;; | ||
|
||
|
||
module String_asserter = Make_asserter (String_comparator);; | ||
module Process_status_asserter = Make_asserter (Process_status_comparator);; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
open Asserter | ||
|
||
let test_echo () = | ||
let process = Process.exec "echo" [ "hello world"; ] in | ||
let status, result, _err = Process.read_and_close_pid process in | ||
let () = Process_status_asserter.assert_equals (Unix.WEXITED 0) status "" in | ||
let () = String_asserter.assert_equals "hello world\n" result "" in | ||
true | ||
|
||
let test_env_variable () = | ||
let process = Process.exec "printenv" ~env:[ "NAME=world" ] [ ] in | ||
let status, result, _err = Process.read_and_close_pid process in | ||
let () = Process_status_asserter.assert_equals (Unix.WEXITED 0) status "" in | ||
let () = String_asserter.assert_equals "NAME=world\n" result "" in | ||
true | ||
|
||
let tests = [ | ||
("test_echo", test_echo); | ||
("test_env_variable", test_env_variable); | ||
] | ||
|
||
let () = | ||
Unit_test.run_all tests |