@@ -228,6 +228,98 @@ defmodule Mix.UtilsTest do
228
228
end
229
229
end
230
230
231
+ describe "write_dot_graph!/4" do
232
+ test "preserves newlines and other control characters" do
233
+ in_tmp ( "dot_newlines" , fn ->
234
+ callback = fn node -> { { node , nil } , [ ] } end
235
+
236
+ Mix.Utils . write_dot_graph! ( "graph.dot" , "graph" , [ "foo \n bar\r \n baz" ] , callback , [ ] )
237
+
238
+ assert File . read! ( "graph.dot" ) == """
239
+ digraph "graph" {
240
+ "foo
241
+ bar\r
242
+ baz"
243
+ }
244
+ """
245
+ end )
246
+ end
247
+
248
+ test "quote and backslash combinations" do
249
+ in_tmp ( "dot_complex" , fn ->
250
+ callback = fn node -> { { node , nil } , [ ] } end
251
+
252
+ test_cases = [
253
+ # "fo"o" -> "fo\"o"
254
+ { "fo\" o" , "fo\\ \" o" } ,
255
+ # "fo\"o" -> "fo\\\"o"
256
+ { "fo\\ \" o" , "fo\\ \\ \" o" } ,
257
+ # "fo\o" -> "fo\o"
258
+ { "fo\\ o" , "fo\\ o" } ,
259
+ # "fo\\o" -> "fo\\o"
260
+ { "fo\\ \\ o" , "fo\\ \\ o" } ,
261
+ # "fo\\\o" -> "fo\\\o"
262
+ { "fo\\ \\ \\ o" , "fo\\ \\ \\ o" }
263
+ ]
264
+
265
+ Enum . each ( test_cases , fn { input , expected } ->
266
+ Mix.Utils . write_dot_graph! ( "graph.dot" , "graph" , [ input ] , callback , [ ] )
267
+ content = File . read! ( "graph.dot" )
268
+ assert content == "digraph \" graph\" {\n \" #{ expected } \" \n }\n "
269
+ end )
270
+ end )
271
+ end
272
+
273
+ test "escapes backslash at end of string" do
274
+ in_tmp ( "dot_end_backslash" , fn ->
275
+ callback = fn node -> { { node , nil } , [ ] } end
276
+
277
+ test_cases = [
278
+ # "fo\" -> "fo\\" (add backslash)
279
+ { "fo\\ " , "fo\\ \\ " } ,
280
+ # "fo\\" -> "fo\\" (already valid)
281
+ { "fo\\ \\ " , "fo\\ \\ " } ,
282
+ # "fo\\\" -> "fo\\\\" (add backslash)
283
+ { "fo\\ \\ \\ " , "fo\\ \\ \\ \\ " }
284
+ ]
285
+
286
+ Enum . each ( test_cases , fn { input , expected } ->
287
+ Mix.Utils . write_dot_graph! ( "graph.dot" , "graph" , [ input ] , callback , [ ] )
288
+ content = File . read! ( "graph.dot" )
289
+ assert content == "digraph \" graph\" {\n \" #{ expected } \" \n }\n "
290
+ end )
291
+ end )
292
+ end
293
+
294
+ test "handles empty strings" do
295
+ in_tmp ( "dot_empty" , fn ->
296
+ callback = fn node -> { { node , nil } , [ ] } end
297
+
298
+ Mix.Utils . write_dot_graph! ( "graph.dot" , "graph" , [ "" ] , callback , [ ] )
299
+
300
+ assert File . read! ( "graph.dot" ) == """
301
+ digraph "graph" {
302
+ ""
303
+ }
304
+ """
305
+ end )
306
+ end
307
+
308
+ test "handles edge labels with escaping" do
309
+ in_tmp ( "dot_edge_labels" , fn ->
310
+ callback = fn node -> { { node , "edge \" label\" " } , [ ] } end
311
+
312
+ Mix.Utils . write_dot_graph! ( "graph.dot" , "graph" , [ "node" ] , callback , [ ] )
313
+
314
+ assert File . read! ( "graph.dot" ) == """
315
+ digraph "graph" {
316
+ "node" [label="edge \\ "label\\ ""]
317
+ }
318
+ """
319
+ end )
320
+ end
321
+ end
322
+
231
323
defp assert_ebin_symlinked_or_copied ( result ) do
232
324
case result do
233
325
{ :ok , paths } ->
0 commit comments