Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix serveral bugs #5

Open
wants to merge 7 commits into
base: 0.4.0-instaparse
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions src/clj_toml/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@

basic-string = <quotation-mark> *basic-char <quotation-mark>

quotation-mark = %x22 ; \"
quotation-mark = %x22 ; \"

<basic-char> = basic-unescaped / escaped
<basic-unescaped> = %x20-21 / %x23-5B / %x5D-7E / %x80-10FFFF

<escaped> = escape escape-seq-char
escaped = escape escape-seq-char

<escape> = %x5C ; \\
<escape-seq-char> = %x22 ; \" quotation mark U+0022
Expand All @@ -87,8 +87,8 @@
<escape-seq-char> =/ %x6E ; n line feed U+000A
<escape-seq-char> =/ %x72 ; r carriage return U+000D
<escape-seq-char> =/ %x74 ; t tab U+0009
<escape-seq-char> =/ %x75 4HEXDIG ; uXXXX U+XXXX
<escape-seq-char> =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX
<escape-seq-char> =/ %x75 4HEXDIG ; uXXXX U+XXXX
<escape-seq-char> =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX

;; Multiline literals

Expand All @@ -97,11 +97,12 @@

;; Multiline Basic String

ml-basic-string = <ml-basic-string-delim> ml-basic-body <ml-basic-string-delim>
ml-basic-string = <ml-basic-string-beg-delim> ml-basic-body <ml-basic-string-end-delim>

ml-basic-string-delim = 3quotation-mark
ml-basic-string-beg-delim = 3quotation-mark 0*1ml-newline
ml-basic-string-end-delim = 3quotation-mark

<ml-basic-body> = *( ml-basic-char / ml-newline / ( escape ws ml-newline ) )
<ml-basic-body> = *( ml-basic-char / ml-newline / <( escape 1*99( wschar / ml-newline ) )> ) ; `1*99` is workaround, `1*(...)` is not working.
<ml-basic-char> = ml-basic-unescaped / escaped
<ml-basic-unescaped> = %x20-5B / %x5D-7E / %x80-10FFFF

Expand All @@ -115,9 +116,10 @@

;; Multiline Literal String

ml-literal-string = <ml-literal-string-delim> ml-literal-body <ml-literal-string-delim>
ml-literal-string = <ml-literal-string-beg-delim> ml-literal-body <ml-literal-string-end-delim>

ml-literal-string-delim = 3apostrophe
ml-literal-string-beg-delim = 3apostrophe 0*1ml-newline
ml-literal-string-end-delim = 3apostrophe

<ml-literal-body> = *( ml-literal-char / ml-newline )
<ml-literal-char> = %x09 / %x20-10FFFF
Expand Down Expand Up @@ -150,7 +152,7 @@
float = float-int-part ( exp / frac [ exp ] )
float =/ special-float

<float-int-part> = dec-int
<float-int-part> = [ minus / plus ] unsigned-dec-int
<frac> = decimal-point zero-prefixable-int
<decimal-point> = %x2E ; .
<zero-prefixable-int> = DIGIT *( DIGIT / <underscore> DIGIT )
Expand Down Expand Up @@ -266,10 +268,10 @@
(condp = x
"-inf" Double/NEGATIVE_INFINITY
"+inf" Double/POSITIVE_INFINITY
"inf" Double/POSITIVE_INFINITY
"inf" Double/POSITIVE_INFINITY
"-nan" Double/NaN
"+nan" Double/NaN
"nan" Double/NaN
"nan" Double/NaN
(read-string x)))

(def toml-transform
Expand All @@ -290,6 +292,7 @@
:local-date (comp read-instant-timestamp #(replace-first % #" " "T") str)
:local-time (comp local-time str)
:date-time identity
:escaped (comp read-string #(str "\"" % "\"") str)
:ml-basic-string str
:basic-string str
:ml-literal-string str
Expand Down Expand Up @@ -503,7 +506,9 @@

(defmethod ^:private process :inline-table
[_ values input]
[values (concat (convert-inline-array (first input)) (rest input))])
[(merge values
(segment-merge {} (convert-inline-array (first input))))
(rest input)])

(defmethod ^:private process :std-table
[_ values input]
Expand Down
241 changes: 144 additions & 97 deletions test/clj_toml/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
(:use clojure.test
[clojure.instant :only [read-instant-timestamp]]
[java-time :only [local-time]]
clj-toml.core))
clj-toml.core)
(:require [clojure.string :as s]))

(deftest comment-test
(testing "Comments"
Expand All @@ -26,12 +27,44 @@
(deftest string-test
(testing "Strings (standard)"
(is (= (parse-string "str = \"I'm a string. Name Jos\u00E9 Location SF.\"")
{"str" "I'm a string. Name Jos\u00E9 Location SF."})))
{"str" "I'm a string. Name Jos\u00E9 Location SF."}))
(is (= (parse-string "str = \"I'm a string. Name José Location SF.\"")
{"str" "I'm a string. Name José Location SF."})))
(testing "Strings (literal)"
(is (= (parse-string "str = 'Comes$as\\is<:>'")
{"str" "Comes$as\\is<:>"})))
(testing "Strings (multiline)")
(testing "Strings (multiline literal)"))
(testing "Strings (multiline)"
(is (= (parse-string (s/join "\n" ["key1 = \"\"\""
"Roses are red"
"Violets are blue\"\"\""]))
{"key1" "Roses are red\nViolets are blue"}))
(is (= (parse-string (s/join "\n" ["key1 = \"\"\""
"The quick brown \\"
""
" fox jumps over \\"
" the lazy dog.\"\"\""]))
{"key1" "The quick brown fox jumps over the lazy dog."}))
(is (= (parse-string (s/join "\n" ["key1 = \"\"\"\\"
" The quick brown \\"
" fox jumps over \\"
" the lazy dog.\\"
" \"\"\""]))
{"key1" "The quick brown fox jumps over the lazy dog."})))
(testing "Strings (multiline literal)"
(is (= (parse-string "regex2 = '''I [dw]on't need \\d{2} apples'''")
{"regex2" "I [dw]on't need \\d{2} apples"}))
(is (= (parse-string (s/join "\n" ["lines = '''"
"The first newline is"
"trimmed in raw strings."
" All other whitespace"
" is preserved."
"'''"]))
{"lines" (s/join "\n" ["The first newline is"
"trimmed in raw strings."
" All other whitespace"
" is preserved."
""])}))
))

(deftest integer-test
(testing "Integer numbers"
Expand Down Expand Up @@ -59,6 +92,10 @@

(deftest float-test
(testing "Float point numbers"
(is (= (parse-string "float = 0.3")
{"float" 0.3}))
(is (= (parse-string "float = -0.3")
{"float" -0.3}))
(is (= (parse-string "float = 3.0")
{"float" 3.0}))
(is (= (parse-string "float = -3.0")
Expand Down Expand Up @@ -150,7 +187,15 @@
(is (= (parse-string "name = {first = \"Tom\", last = \"Preston-Werner\"}")
{"name" {"first" "Tom" "last" "Preston-Werner"}}))
(is (= (parse-string "point = {x = 1, y = 1, color = {r = 0, g = 0, b = 0}}")
{"point" {"x" 1 "y" 1 "color" {"r" 0 "g" 0 "b" 0}}}))))
{"point" {"x" 1 "y" 1 "color" {"r" 0 "g" 0 "b" 0}}}))
(is (= (parse-string (s/join "\n" ["[tb_parent]"
"val = 1"
"tb_a = {val = 10}"
"tb_b = {val = 20}"]))
{"tb_parent"
{"val" 1
"tb_a" {"val" 10}
"tb_b" {"val" 20}}}))))

(deftest array-of-tables-test
(testing "Array of Tables"
Expand Down Expand Up @@ -183,123 +228,125 @@
(deftest example-test
(testing "TOML example"
(is (= (parse-string (slurp "resources/example.toml"))
{"title" "TOML Example"
{"title" "TOML Example"
"owner"
{"name" "Tom Preston-Werner"
"organization" "GitHub"
"bio" "GitHub Cofounder & CEO\\nLikes tater tots and beer."
"dob" (read-instant-timestamp "1979-05-27T07:32:00Z")}
"organization" "GitHub"
"bio" "GitHub Cofounder & CEO\nLikes tater tots and beer."
"dob" (read-instant-timestamp "1979-05-27T07:32:00Z")}
"database"
{"enabled" true,
"connection_max" 5000,
"server" "192.168.1.1",
"ports" [8001 8001 8002]}
"connection_max" 5000,
"server" "192.168.1.1",
"ports" [8001 8001 8002]}
"servers"
{"alpha"
{"ip" "10.0.0.1"
{"ip" "10.0.0.1"
"dc" "eqdc10"}
"beta"
{"ip" "10.0.0.2"
"beta"
{"ip" "10.0.0.2"
"dc" "eqdc10"
"country" "中国"}}
"clients"
{"data" [["gamma" "delta"] [1 2]]
"hosts" ["alpha" "omega"]}
"hosts" ["alpha" "omega"]}
"products"
[{"name" "Hammer"
"sku" 738594937}
{"name" "Nail"
{"name" "Nail"
"sku" 284758393
"color" "gray"}]}))))

(deftest hard-example-test
(testing "TOML hard example"
(is (= (parse-string (slurp "resources/hard_example.toml"))
{"the"
{"the"
{"hard"
{"another_test_string" " Same thing, but with a string #",
{"another_test_string" " Same thing, but with a string #",
"test_array2"
["Test #11 ]proved that" "Experiment #9 was a success"],
"test_array" ["] " " # "],
"bit#"
{"what?" "You don't think some user won't do that?",
"multi_line_array" ["]"]},
"multi_line_array" ["]"]},
"harder_test_string"
" And when \\\"'s are in the string, along with # \\\""},
"test_string" "You'll hate me after this - #"}}))))
" And when \"'s are in the string, along with # \""},
"test_string" "You'll hate me after this - #"}}))))

#_(deftest example-v0.4.0-test
(testing "TOML 0.4.0 example"
(is (= (parse-string (slurp "resources/example-v0.4.0.toml"))
{"table"
{"key" "value"
"subtable" {"key" "another value"}
"inline" {"first" "Tom" "last" "Preston-Werner"}}
"x" {"y" {"z" {"w" {}}}}
"string"
{"basic"
{"basic" "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."}
"multiline"
{"key1" "One\nTwo"
"key2" "One\nTwo"
"key3" "One\nTwo"
"continued"
{"key1" "The quick brown fox jumps over the lazy dog."
"key2" "The quick brown fox jumps over the lazy dog."
"key3" "The quick brown fox jumps over the lazy dog."}}
"literal"
{"winpath" "C:\\Users\\nodejs\\templates"
"winpath2" "\\\\ServerX\\admin$\\system32\\"
"quoted" "Tom \"Dubs\" Preston-Werner"
"regex" "<\\i\\c*\\s*>"
"multiline"
{"regex2" "I [dw]on't need \\d{2} apples"
"lines" "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"}}}
"integer"
{"key1" 99
"key2" 42
"key3" 0
"key4" -17
"underscores"
{"key1" 1000
"key2" 5349221
"key3" 12345}}
"float"
{"fractional"
{"key1" 1.0
"key2" 3.1415
"key3" -0.01}
"exponent"
{"key1" 5e+22
"key2" 1e6
"key3" -2E-2}
"both"
{"key" 6.626e-34}
"underscores"
{"key1" 9224617.445991228313
"key2" 1e1000}}
"boolean"
{"True" true
"False" false}
"datetime"
{"key1" "1979-05-27T07:32:00Z"
"key2" "1979-05-27T00:32:00-07:00"
"key3" "1979-05-27T00:32:00.999999-07:00"}
"array"
{"key1" [1 2 3]
"key2" ["red" "yellow" "green"]
"key3" [[1 2] [3 4 5]]
"key4" [[1 2] ["a" "b" "c"]]
"key5" [1 2 3]
"key6" [1 2]}
"products"
[{"name" "Hammer" "sku" 738594937}
{}
{"name" "Neil" "sku" 284758393 "color" "gray"}]
"fruit"
[{"name" "apple"
"physical" {"color" "red" "shape" "round"}
"variety" [{"name" "red delicious"}
{"name" "granny smith"}]}
{"name" "banana"
"variety" [{"name" "plantain"}]}]}))))
(deftest example-v0.4.0-test
(testing "TOML 0.4.0 example"
(is (= (parse-string (slurp "resources/example-v0.4.0.toml"))
{"table"
{"key" "value"
"subtable" {"key" "another value"}
"inline"
{"name" {"first" "Tom" "last" "Preston-Werner"}
"point" {"x" 1 "y" 2}}}
"x" {"y" {"z" {"w" {}}}}
"string"
{"basic"
{"basic" "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."}
"multiline"
{"key1" "One\nTwo"
"key2" "One\nTwo"
"key3" "One\nTwo"
"continued"
{"key1" "The quick brown fox jumps over the lazy dog."
"key2" "The quick brown fox jumps over the lazy dog."
"key3" "The quick brown fox jumps over the lazy dog."}}
"literal"
{"winpath" "C:\\Users\\nodejs\\templates"
"winpath2" "\\\\ServerX\\admin$\\system32\\"
"quoted" "Tom \"Dubs\" Preston-Werner"
"regex" "<\\i\\c*\\s*>"
"multiline"
{"regex2" "I [dw]on't need \\d{2} apples"
"lines" "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"}}}
"integer"
{"key1" 99
"key2" 42
"key3" 0
"key4" -17
"underscores"
{"key1" 1000
"key2" 5349221
"key3" 12345}}
"float"
{"fractional"
{"key1" 1.0
"key2" 3.1415
"key3" -0.01}
"exponent"
{"key1" 5e+22
"key2" 1e6
"key3" -2E-2}
"both"
{"key" 6.626e-34}
"underscores"
{"key1" 9224617.445991228313
"key2" 1e1000}}
"boolean"
{"True" true
"False" false}
"datetime"
{"key1" (read-instant-timestamp "1979-05-27T07:32:00Z")
"key2" (read-instant-timestamp "1979-05-27T00:32:00-07:00")
"key3" (read-instant-timestamp "1979-05-27T00:32:00.999999-07:00")}
"array"
{"key1" [1 2 3]
"key2" ["red" "yellow" "green"]
"key3" [[1 2] [3 4 5]]
"key4" [[1 2] ["a" "b" "c"]]
"key5" [1 2 3]
"key6" [1 2]}
"products"
[{"name" "Hammer" "sku" 738594937}
{}
{"name" "Nail" "sku" 284758393 "color" "gray"}]
"fruit"
[{"name" "apple"
"physical" {"color" "red" "shape" "round"}
"variety" [{"name" "red delicious"}
{"name" "granny smith"}]}
{"name" "banana"
"variety" [{"name" "plantain"}]}]}))))