1 module d_properties; 2 3 public import d_properties.properties; 4 public import d_properties.writer; 5 public import d_properties.reader; 6 7 unittest { 8 import std.format; 9 import std.file; 10 import std.stdio; 11 12 // First test all valid cases. 13 14 void readWriteValidTest(uint testCase) { 15 string filename = format("test_cases/valid/%d.properties", testCase); 16 string outFilename = format("test_cases/valid/%d-out.properties", testCase); 17 auto p1 = Properties(filename); 18 p1.writeToFile(outFilename); 19 auto p2 = Properties(outFilename); 20 remove(outFilename); // Remove the extra file now that we're done. 21 assert(p1 == p2, "Properties are not equal after read/write cycle."); 22 } 23 24 readWriteValidTest(1); 25 readWriteValidTest(2); 26 27 // Test some specifics to ensure reading produces the expected values. 28 auto p = Properties("test_cases/valid/2.properties"); 29 assert("my.value" in p); 30 assert(p["my.value"] == "Hello world!"); 31 assert(p["another.value"] == "\"This is a quoted string\""); 32 assert(p["This is an indented value"] == "12345"); 33 assert(p.get!int("This is an indented value") == 12_345); 34 import std.conv : ConvException; 35 try { 36 p.get!char("This is an indented value"); 37 assert(false); // We expect an exception to be thrown. 38 } catch (ConvException e) { 39 // All good. 40 } 41 assert(p["multiline_2"] == "abc"); 42 assert("missing_key" !in p); 43 assert(p.get("missing_key", "none") == "none"); 44 p["missing_key"] = "yes"; 45 assert("missing_key" in p); 46 47 // Test property overwriting. 48 p = Properties("test_cases/valid/2.properties", "test_cases/valid/3.properties"); 49 assert(p["my.value"] == "Goodbye world!"); 50 assert(p["another.value"] == "test"); 51 52 p = Properties("test_cases/valid/3.properties", "test_cases/valid/2.properties"); 53 assert(p["my.value"] == "Hello world!"); 54 assert(p["another.value"] == "\"This is a quoted string\""); 55 56 p = Properties("test_cases/valid/2.properties"); 57 auto p2 = Properties("test_cases/valid/3.properties"); 58 p.addAll(p2); 59 assert(p["my.value"] == "Goodbye world!"); 60 p.addAll("test_cases/valid/1.properties"); 61 assert("language" in p); 62 63 // Test property subsets. 64 p = Properties("test_cases/valid/subs.properties"); 65 auto one = p.getAll("one"); 66 assert(one["a"] == "1"); 67 assert(one["b"] == "2"); 68 assert(one["c"] == "3"); 69 assert(!one.has("name")); 70 assert(!one.has("url")); 71 auto two = p.getAll("two"); 72 assert(two["name"] == "Andrew"); 73 assert(two["url"] == "google.com"); 74 assert(!two.has("a")); 75 assert(!two.has("b")); 76 assert(!two.has("c")); 77 78 struct TestOne { 79 int a, b, c; 80 } 81 auto oneStruct = p.getAll!TestOne("one"); 82 assert(oneStruct.a == 1); 83 assert(oneStruct.b == 2); 84 assert(oneStruct.c == 3); 85 86 // Then test all invalid cases, one-by-one, to check line number and/or message. 87 88 try { 89 readFromFile("test_cases/invalid/1.json"); 90 } catch (PropertiesParseException e) { 91 assert(e.lineNumber == 1); 92 } 93 94 try { 95 readFromFile("test_cases/invalid/2.properties"); 96 } catch (PropertiesParseException e) { 97 assert(e.lineNumber == 2); 98 } 99 100 try { 101 readFromFile("test_cases/invalid/3.properties"); 102 } catch (PropertiesParseException e) { 103 assert(e.lineNumber == 3); 104 } 105 }