imports.rs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // SPDX-License-Identifier: Apache-2.0
  2. use assert_cmd::cargo_bin_cmd;
  3. #[test]
  4. fn import_map_dup() {
  5. let mut cmd = cargo_bin_cmd!("solang");
  6. let run = cmd
  7. .args([
  8. "compile",
  9. "--target",
  10. "solana",
  11. "--importmap",
  12. "foo=tests",
  13. "--importmap",
  14. "foo=tests2",
  15. "dummy.sol",
  16. ])
  17. .current_dir("tests/imports_testcases")
  18. .assert()
  19. .success();
  20. let output = run.get_output();
  21. assert_eq!(
  22. String::from_utf8_lossy(&output.stderr),
  23. "warning: mapping 'foo' to 'tests' is overwritten\n"
  24. );
  25. }
  26. #[test]
  27. fn import_map_badpath() {
  28. let mut cmd = cargo_bin_cmd!("solang");
  29. let run = cmd
  30. .args([
  31. "compile",
  32. "--target",
  33. "solana",
  34. "--importmap",
  35. "foo=/does/not/exist",
  36. "dummy.sol",
  37. ])
  38. .current_dir("tests/imports_testcases")
  39. .assert()
  40. .success();
  41. let output = run.get_output();
  42. assert_eq!(String::from_utf8_lossy(&output.stderr), "");
  43. }
  44. #[test]
  45. fn import_map() {
  46. let mut cmd = cargo_bin_cmd!("solang");
  47. let assert = cmd
  48. .args([
  49. "compile",
  50. "--target",
  51. "solana",
  52. "--importmap",
  53. "foo=imports/",
  54. "import_map.sol",
  55. ])
  56. .current_dir("tests/imports_testcases")
  57. .assert()
  58. .success();
  59. let output = assert.get_output();
  60. assert_eq!(String::from_utf8_lossy(&output.stderr), "");
  61. let mut cmd = cargo_bin_cmd!("solang");
  62. let badpath = cmd
  63. .args(["compile", "import_map.sol", "--target", "solana"])
  64. .current_dir("tests/imports_testcases")
  65. .assert()
  66. .failure();
  67. let output = badpath.get_output();
  68. let stderr = String::from_utf8_lossy(&output.stderr);
  69. println!("stderr: {stderr}");
  70. assert!(stderr.contains("file not found 'foo/bar.sol'"));
  71. }
  72. #[test]
  73. fn import() {
  74. let mut cmd = cargo_bin_cmd!("solang");
  75. let assert = cmd
  76. .args([
  77. "compile",
  78. "--target",
  79. "solana",
  80. "--importpath",
  81. "./imports_testcases/imports",
  82. "imports_testcases/import.sol",
  83. ])
  84. .current_dir("tests")
  85. .assert()
  86. .success();
  87. let output = assert.get_output();
  88. assert_eq!(String::from_utf8_lossy(&output.stderr), "");
  89. let mut cmd = cargo_bin_cmd!("solang");
  90. let badpath = cmd
  91. .args(["compile", "--target", "solana", "import.sol"])
  92. .current_dir("tests/imports_testcases")
  93. .assert()
  94. .failure();
  95. let output = badpath.get_output();
  96. let stderr = String::from_utf8_lossy(&output.stderr);
  97. println!("stderr: {stderr}");
  98. assert!(stderr.contains("file not found 'bar.sol'"));
  99. }
  100. #[test]
  101. fn contract_name_defined_twice() {
  102. let mut cmd = cargo_bin_cmd!("solang");
  103. let ok = cmd
  104. .args(["compile", "--target", "solana", "bar.sol", "rel.sol"])
  105. .current_dir("tests/imports_testcases/imports")
  106. .assert()
  107. .success();
  108. let output = ok.get_output();
  109. assert_eq!(String::from_utf8_lossy(&output.stderr), "");
  110. let mut cmd = cargo_bin_cmd!("solang");
  111. let not_ok = cmd
  112. .args([
  113. "compile",
  114. "--target",
  115. "solana",
  116. "relative_import.sol",
  117. "rel.sol",
  118. ])
  119. .current_dir("tests/imports_testcases/imports")
  120. .assert()
  121. .failure();
  122. let output = not_ok.get_output();
  123. let err = String::from_utf8_lossy(&output.stderr);
  124. println!("{err}");
  125. // The error contains the absolute paths, so we cannot assert the whole string
  126. assert!(err.starts_with("error: contract rel defined at "));
  127. assert!(err.contains("relative_import.sol:1:1-6:2 and "));
  128. assert!(err.ends_with("rel.sol:2:1-16\n"));
  129. }
  130. #[test]
  131. fn bad_escape() {
  132. let mut cmd = cargo_bin_cmd!("solang");
  133. let not_ok = cmd
  134. .args([
  135. "compile",
  136. "--target",
  137. "solana",
  138. "tests/imports_testcases/bad_escape.sol",
  139. ])
  140. .assert()
  141. .failure();
  142. let output = not_ok.get_output();
  143. let err = String::from_utf8_lossy(&output.stderr);
  144. println!("{err}");
  145. // The error contains the absolute paths, so we cannot assert the whole string
  146. assert!(err.contains(": \\x escape should be followed by two hex digits"));
  147. #[cfg(windows)]
  148. assert!(err.contains(": string is not a valid filename"));
  149. #[cfg(not(windows))]
  150. assert!(err.contains(": file not found 'bar�.sol'"));
  151. }
  152. // Ensure that .\ and ..\ are not interpreted as relative paths on Unix/MacOS
  153. // Note Windows allows these as relative paths, but we do not.
  154. #[test]
  155. fn backslash_path() {
  156. let mut cmd = cargo_bin_cmd!("solang");
  157. let not_ok = cmd
  158. .args([
  159. "compile",
  160. "--target",
  161. "solana",
  162. "tests/imports_testcases/imports/bar_backslash.sol",
  163. "--importpath",
  164. "tests/imports_testcases/imports",
  165. ])
  166. .assert();
  167. #[cfg(windows)]
  168. let not_ok = not_ok.success();
  169. #[cfg(not(windows))]
  170. let not_ok = not_ok.failure();
  171. let output = not_ok.get_output();
  172. let err = String::from_utf8_lossy(&output.stderr);
  173. println!("{err}");
  174. #[cfg(windows)]
  175. assert!(err.is_empty());
  176. #[cfg(not(windows))]
  177. assert!(err.contains(": file not found '.\\relative_import.sol'"));
  178. #[cfg(not(windows))]
  179. assert!(err.contains(": file not found '..\\import.sol'"));
  180. }
  181. #[test]
  182. fn found_two_files() {
  183. let mut cmd = cargo_bin_cmd!("solang");
  184. let run = cmd
  185. .args([
  186. "compile",
  187. "--target",
  188. "solana",
  189. "--importpath",
  190. "imports",
  191. "-I",
  192. "imports",
  193. "--importpath",
  194. "meh",
  195. "-I",
  196. "meh",
  197. "import.sol",
  198. ])
  199. .current_dir("tests/imports_testcases")
  200. .assert()
  201. .failure();
  202. let output = run.get_output();
  203. let error = String::from_utf8_lossy(&output.stderr);
  204. println!("{error}");
  205. assert!(error.contains("error: import paths 'imports', 'meh' specified more than once"));
  206. let mut cmd = cargo_bin_cmd!("solang");
  207. let run = cmd
  208. .args([
  209. "compile",
  210. "--target",
  211. "solana",
  212. "--importpath",
  213. "imports",
  214. "-I",
  215. "imports2",
  216. "import.sol",
  217. ])
  218. .current_dir("tests/imports_testcases")
  219. .assert()
  220. .failure();
  221. let output = run.get_output();
  222. let error = String::from_utf8_lossy(&output.stderr);
  223. println!("{error}");
  224. assert!(error.contains(": found multiple files matching 'bar.sol': '"));
  225. #[cfg(windows)]
  226. {
  227. assert!(error.contains("\\tests\\imports_testcases\\imports\\bar.sol', '"));
  228. assert!(error.contains("\\tests\\imports_testcases\\imports2\\bar.sol'"));
  229. }
  230. #[cfg(not(windows))]
  231. {
  232. assert!(error.contains("/tests/imports_testcases/imports/bar.sol', '"));
  233. assert!(error.contains("/tests/imports_testcases/imports2/bar.sol'"));
  234. }
  235. }