├── .gitignore ├── .monkeyci ├── build.clj └── deps.edn ├── LICENSE ├── README.md ├── deps.edn ├── dev-resources ├── deep-merge-test.edn ├── file-test.edn ├── privkey-test.edn ├── test-key-pub.pem ├── test-key.pem ├── test-key.pem.enc └── test.txt ├── src └── monkey │ └── aero.clj ├── test └── monkey │ └── aero_test.clj └── tests.edn /.gitignore: -------------------------------------------------------------------------------- 1 | pom.xml 2 | /.cpcache 3 | /junit.xml 4 | .nrepl-port 5 | /target 6 | -------------------------------------------------------------------------------- /.monkeyci/build.clj: -------------------------------------------------------------------------------- 1 | (require '[monkey.ci.plugin.clj :as p]) 2 | (require '[monkey.ci.plugin.github :as gh]) 3 | 4 | [(p/deps-library) 5 | (gh/release-job {:dependencies ["publish"]})] 6 | -------------------------------------------------------------------------------- /.monkeyci/deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {com.monkeyci/plugin-clj {:mvn/version "0.4.0"} 2 | com.monkeyci/plugin-github {:mvn/version "0.1.3"}}} 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 monkey-projects 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aero Extensions 2 | 3 | [![Clojars Project](https://img.shields.io/clojars/v/com.monkeyprojects/aero-ext.svg)](https://clojars.org/com.monkeyprojects/aero-ext) 4 | 5 | This is a Clojure lib that adds some more tag readers to use with [Aero](https://github.com/juxt/aero?tab=readme-ov-file). This is a configuration library that reads `.edn` files but adds 6 | some additional functionality to it. For use with our own projects, we have 7 | created this library, that adds some more extensions. 8 | 9 | ## Usage 10 | 11 | First include the library: 12 | ```clojure 13 | ;; deps.edn 14 | {:deps {com.monkeyprojects/aero-ext {:mvn/version "0.3.0"}}} 15 | ``` 16 | Or with Leiningen: 17 | ```clojure 18 | :dependencies [[com.monkeyprojects/aero-ext "0.3.0"]] 19 | ``` 20 | 21 | Then enable the readers just by requiring the ns: 22 | ```clojure 23 | (require '[monkey.aero]) 24 | 25 | ;; Load something with aero 26 | (require '[aero.core :as ac]) 27 | 28 | ;; This will automatically process any extension readers 29 | (ac/read-config "path/to/edn/file") 30 | ``` 31 | 32 | ## Available Readers 33 | 34 | These are the readers that are provided by this library. 35 | 36 | ### to-edn 37 | 38 | Serializes the argument to an `edn` string. 39 | ```clojure 40 | {:config-str #to-edn {:key "value"}} 41 | ``` 42 | 43 | ### from-edn 44 | 45 | Opposite of `#to-edn`, parses an `edn` string: 46 | ```clojure 47 | {:config-str #from-edn "{:key \"value\"}"} 48 | ``` 49 | 50 | This is useful when you want to process an edn file before including it in your config 51 | (like decrypting it). 52 | 53 | ### meta-merge 54 | 55 | Similar to Aero's `#merge`, this performs a deep merge using 56 | [meta-merge](https://github.com/weavejester/meta-merge). Existing maps don't overwrite 57 | eachother, but are merged again: 58 | ```clojure 59 | {:value #meta-merge [{:first {:second "value"}} 60 | {:first {:third "other value"}}]} 61 | ``` 62 | This will result in a map like this: 63 | ```clojure 64 | {:value 65 | {:first 66 | {:second "value" 67 | :third "other value"}}} 68 | ``` 69 | 70 | See the [meta-merge docs](https://github.com/weavejester/meta-merge) for more details. 71 | `#deep-merge` is a synonym, for backwards compatibility. 72 | 73 | ### deep-merge 74 | 75 | See `meta-merge`. 76 | 77 | ### file 78 | 79 | To include any file as a string in your config, use `#file`: 80 | ```clojure 81 | {:log-config #file "path/to/file"} 82 | ``` 83 | This is not the same as the Aero-provided `#include`, because `#include` 84 | will parse the file as `edn`, whereas `#file` will just read it as raw text. 85 | This will use the `:resolver` as configured when reading the config. 86 | 87 | ### to-b64 88 | 89 | This will encode the argument to Base64. 90 | ```clojure 91 | {:password #to-b64 #env PASSWORD} 92 | ``` 93 | Useful for including binary data. 94 | 95 | ### from-b64 96 | 97 | Similar to `#to-b64`, this will decode from Base64 98 | ```clojure 99 | {:password #from-b64 #env PASSWORD} 100 | ``` 101 | 102 | ### privkey 103 | 104 | Will parse the argument as a PEM-encoded private key. The result is a `java.security.PrivateKey`. 105 | ```clojure 106 | {:private-key #privkey #file "ssh/private-key.pem"} 107 | ``` 108 | 109 | If the key is encrypted, you can specify the password by using a vector: 110 | ```clojure 111 | {:private-key #privkey [#file "ssh/private-key.pem" "verysecretpass"]} 112 | ``` 113 | 114 | Returns a `java.security.PrivateKey`. 115 | 116 | ### pubkey 117 | 118 | The counterpart of `privkey` for public `PEM` keys: 119 | ```clojure 120 | {:public-key #pubkey #file "ssh/public-key.pem"} 121 | ``` 122 | 123 | Returns a `java.security.PublicKey`. 124 | 125 | ### str 126 | 127 | Converts the argument to a string. Useful in combination with `#from-b64`, which returns 128 | a byte array. 129 | ```clojure 130 | {:password #str #from-b64 #env PASSWORD} 131 | ``` 132 | 133 | ### random 134 | 135 | Selects an item at random from the argument list. 136 | ```clojure 137 | {:continent #random ["europe" "asia" "africa" "north-america" "south-america" "oceania"]} 138 | ``` 139 | It has its uses ;-). 140 | 141 | ## License 142 | 143 | Copyright (c) 2024 by [Monkey Projects BV](https://www.monkey-projects.be) 144 | 145 | [MIT License](LICENSE) -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {aero/aero {:mvn/version "1.1.6"} 2 | buddy/buddy-sign {:mvn/version "3.6.1-359"} 3 | meta-merge/meta-merge {:mvn/version "1.0.0"}} 4 | 5 | :aliases 6 | {:dev 7 | {:extra-paths ["env/dev" "dev-resources"]} 8 | 9 | :test 10 | {:extra-deps {babashka/fs {:mvn/version "0.5.25"} 11 | com.monkeyprojects/build {:mvn/version "0.3.1"}} 12 | :extra-paths ["test" "dev-resources"] 13 | :exec-fn monkey.test/all} 14 | 15 | :watch 16 | {:exec-fn monkey.test/watch} 17 | 18 | :junit 19 | {:exec-fn monkey.test/junit} 20 | 21 | :coverage 22 | {:exec-fn monkey.test/coverage 23 | :exec-args {:ns-regex ["monkey.aero.*"]}} 24 | 25 | :jar 26 | {:extra-deps {com.monkeyprojects/build {:mvn/version "0.3.1"}} 27 | :exec-fn monkey.build/jar 28 | :exec-args {:jar "target/aero-ext.jar" 29 | :lib "com.monkeyprojects/aero-ext" 30 | :version [[:env "LIB_VERSION"] "0.3.1-SNAPSHOT"] 31 | :scm {:url "https://github.com/monkey-projects/aero-ext"} 32 | :pom-data 33 | [[:licenses 34 | [:license 35 | [:name "MIT"] 36 | [:url "https://mit-license.org/"]]]]}} 37 | 38 | :install 39 | {:exec-fn monkey.build/jar+install} 40 | 41 | :publish 42 | {:exec-fn monkey.build/jar+deploy}}} 43 | -------------------------------------------------------------------------------- /dev-resources/deep-merge-test.edn: -------------------------------------------------------------------------------- 1 | {:first #deep-merge [{:second {:third "value"}} 2 | {:second {:fourth "other value"}}]} 3 | -------------------------------------------------------------------------------- /dev-resources/file-test.edn: -------------------------------------------------------------------------------- 1 | {:some-file #file "test.txt"} 2 | -------------------------------------------------------------------------------- /dev-resources/privkey-test.edn: -------------------------------------------------------------------------------- 1 | {:private-key #privkey #file "test-key.pem"} 2 | -------------------------------------------------------------------------------- /dev-resources/test-key-pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA558dmwKbFQOqwGjD+UkN 3 | TaHFB8v7D2KCJx1Pt+YbSm2KSR9yGvGOG6EMKob8WQknZvp6kRpj3XjG0wCRYag1 4 | zlSPQJhSPORpLXCI4iW7qv+mcPOkw2l7+umHcf83tU7bzuU/zgVn0aC6ayF4Vtds 5 | HgVKgXtPVFtdHIkKgI3OdNq3uRNbrk0CZEgwoNQKXJU8S1oerKbAH3iG1ckpb4AN 6 | x3z6QpoZTWMmxUZ/crLQOXAe9fVHm07B9nl+eNkXD3iIl3ZM/GQcMIsxJJnVzJy5 7 | vQanBzmrGivOBs+vzmNtMROMzlgATPVkSrH3aN8TsGge4Cqz5EhtMx8mS5olLGLb 8 | awIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /dev-resources/test-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDnnx2bApsVA6rA 3 | aMP5SQ1NocUHy/sPYoInHU+35htKbYpJH3Ia8Y4boQwqhvxZCSdm+nqRGmPdeMbT 4 | AJFhqDXOVI9AmFI85GktcIjiJbuq/6Zw86TDaXv66Ydx/ze1TtvO5T/OBWfRoLpr 5 | IXhW12weBUqBe09UW10ciQqAjc502re5E1uuTQJkSDCg1ApclTxLWh6spsAfeIbV 6 | ySlvgA3HfPpCmhlNYybFRn9ystA5cB719UebTsH2eX542RcPeIiXdkz8ZBwwizEk 7 | mdXMnLm9BqcHOasaK84Gz6/OY20xE4zOWABM9WRKsfdo3xOwaB7gKrPkSG0zHyZL 8 | miUsYttrAgMBAAECggEATrrWoNx7Y2K6NSnHR2Jt66/rnbFXtsyIqgv8D2nfZ+ah 9 | BSbzrbXi1IBi9seoWglTA91rMQxT2rGVf55nTFcVZvt2MAI2ne0T1Ta1yI0D4+V/ 10 | KVCf9i5STqD3gae7Q105OPPSwtAykF4+T3Dyiy4xWWj6ANYtymI93Ze1YqoQ/cW+ 11 | 6Jzyz9lxAqdKFudO7hAp1vDGs5Uu+MKc5+/it53aRDdVxruK7l78wcJYBS6zNveK 12 | YmtvnjKV0NxhKk5GRBknUHD1sM+ztpiYQCNdfRyoKdLF4hbqhAFJIsQ0Jias1cPf 13 | tXQjRBJZlkW4Mix7ysDQ7+airrpkRTgIgJ6LTGk1jQKBgQD6HKaLy6cZX6qB2fdx 14 | rUH2Xkh3YehonBbaae4QcQatt04feaaA0LOh63JGkLqXJeY05D1v3fD+ZFx5OV2k 15 | 8YVHCQnqMCjJ4xzJS7Gqj9amsq+BR24Fk5GdalZGAyHie23Jex0akszUU6Z6D6nR 16 | YuzaTsAOPEYXWDlRuppirwHNvwKBgQDtEwd3L+wzxZ6WeZLq9nt0r35twOS1AC7U 17 | 0JumHuRd0NUkmMvzzYyuACuwmAWyzAQI+LJPFm6g0dzThqh+SdVE1hERzK5fZ9SX 18 | +oOD7rCsWUYCt7aWHyvk+3OAauGG46FMddb753m9Un/441DlwWNMmqk4PkD3ZtB1 19 | Y3NEHQ81VQKBgHrdDCtsNX/PcPEs49Mh619dXXfXztVkqA1PMDU/cKpxe50Wo2Zw 20 | H24RPSfQ/Pg3E+kzncKQYkx1fL/IIGpggroshIRYeBEE0iVIW9SPqEBnUrPNJQz0 21 | Ovn7PLpT25doTrxFEDz3lEtRdFxNyXwkfnmXad0UWtIo8q9lXWXQ1q/9AoGANzsL 22 | rjS37ofHnn7MP3kU4eZQqfkaTyCvyFyhJl5kDYctYM1IFpB4icD4bLe9/B2TgxON 23 | Vud+9nBt5cmlT2acDOFiMKdiqE9kM9Pk98OP3Vce/FsYanjwnPQHwI8l42r8lPeP 24 | EjinH/gsYCt1GVGodJxDeBrov7pwLijxHZk3hdECgYAXFN3sqfY2jzJy7cUBXO9D 25 | hS9WmwBWGz0bW/YKyuxtzohW6DlCarYe5XEJzsIbiutqOGzSLuqHcej7Y1SmE8VN 26 | x2MTvX+Am1xLDgbF3KdlGMmMgftzFlSnKASlwV71CfABQWrfi9T0Xkb07x9dKr01 27 | J2zLx4DAgIJXJ52sMfo9ZQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /dev-resources/test-key.pem.enc: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQTmcKhZxBvLCJlzvb 3 | mrBdoQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEO7fbV5GuMoBqfMK 4 | lwj64/sEggTQyoi2ziIOmkUhGkbYOBUeNKQcPMmNI+PQ6S2eRxSLfqCsjFhFmr9J 5 | i8mJIhymVDaVESm8TyVsXw39EMXT01XmaxM80UnLJdeM2iRYREQLqARSP4EqDw7p 6 | Kr7FamEEQNhFM57t+pVZvSF1s/1SHjLK8Z0mMrqTaHiqDJ1DjntpAX+BU1V3An7K 7 | T+AYXPUdVeiUN3oU2JXZ0d09zJrFdFrsToY+W7wZIVIr0ON+mwkNEjpwlpbRih5v 8 | z7upFs5LjYVZslZv6VJNc/ASQTogxgUpUb15XrONhB1n+8iX3IPTBESLGI07Y9Uh 9 | Vp02Zoh0xZPcG7bXYmoGkilWo+jwgUmZTptptEHqqz0cJM6QnUjLUOPFSOJJ1d10 10 | vKwOyKkiDbnCE4GiW9awtDLK4WYRo27zwP3rf4BTpi86BxAh1hXxM+cuBDSYsDFi 11 | FBMdApvlbOlntLKv2nDLc1xla8ZCRg48Iba2yuLHii6qWKpC3qdYULS0tJCR56KU 12 | ZhaL7fl/1J0CUsBIrnLXLXi3J6OC54dbudvNmUftrsHr43iWHk4q8EKYuXsz6Om0 13 | anG3kQjA5VFlzSPOCzVZGvwXclGKe6S4Y/eXaP9SerzRsUiWJtGIYgDeTWZjkwQn 14 | Ct2iebJP2ypvR1hmFYKwm5V458cL13esEzapXboZIrDCPOjPOP3VLn9IDo0eiUGi 15 | vPaj0l/FH1wu+gPU5SzMNIlN5TD5W9OSLRjZORZfaTm4poOMDJML8AGtjPJhFkjs 16 | 6Tg6ARXO35T7JnnTsPimJPuZ7MmR36fdbpduvMhlDi0863xtoG+dfvIPw+p8IvfT 17 | CwBSiBU/cyghcSuvbBgd4HTAkIWRoT0MBQBryhXSe9FYfDVtLke2ZeMeLtVYnIOD 18 | twUHRGq0uOURCSD5XjeQjpMYxDYKGaeBDrVfENE/BPXzgljUMbS9s/eTMs0WEeDP 19 | M8SWi6gxIPnMythjaxgIa/RUTJpgUFQrIkBIrpsyZXE3+yPqlZS9TCm+gSVPhERu 20 | 47hPZYk/G+lDGbdHEpkTt6qvDI8kXtap52z4v8e47chOWoD7iwGdmTPtW5t9mNgD 21 | BCRER9AH64Z93/7IUcU1UMJLEPh5wjqf6pUKBH3nXuSqLcC3RoDDCSkip8JqY16q 22 | dM/+0a8o60HKXCtfOZVQWRZXV15pDMxLDn9RTktwkV2OR3O+7dnYovG0UFEo7gnE 23 | kpSbWBKCS/1fnotNHMDUcWNwhr8J5QAScxcz8Bn2dMT1ua0LjS2nFwJq0UH1SLeB 24 | DFOYW+5taCTVfjsx4lxWqrcq0iI7qHstt4fz8KfDh2ry5t7buF3wlAiBSo3bOwck 25 | 5yF0Ph5pB9BZD+wZP7X0C0KEDMd2NEtNydTDvE21KDj8huBKhT0EmB08lequS8dk 26 | whHR49O79tICa7gx1HsS+CuOioI7l8mAxrlft89FahaAsBCojshtRQv6JGKuIkYL 27 | o1ksHQBIUBZ3mZL97d+a3d1kTG7WaBeXkQXvDRRLsIRLComXTuycf7SIbNY+4/iC 28 | 2vd01L/CjkIX6vf4qlyp+d5CAEP5VUno1JT1mR7CVUxjh58o+429+dgnPCauH+gl 29 | 3WxlIDxoDCXTdMUi+qAmNqnb+xET8UXp5r8PWSAQD7ZA7IPmUAyu/vM= 30 | -----END ENCRYPTED PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /dev-resources/test.txt: -------------------------------------------------------------------------------- 1 | This is a test file 2 | -------------------------------------------------------------------------------- /src/monkey/aero.clj: -------------------------------------------------------------------------------- 1 | (ns monkey.aero 2 | (:require [aero.core :as ac] 3 | [buddy.core.keys.pem :as pem] 4 | [clojure.edn :as edn] 5 | [meta-merge.core :as mm]) 6 | (:import java.util.Base64 7 | [java.io PushbackReader StringReader])) 8 | 9 | (defn- resolve-path [{:keys [resolver source]} path] 10 | ;; Copied from the aero source, which unfortunately does not expose this as a fn. 11 | ;; Would be better as a protocol imho. 12 | (if (map? resolver) 13 | (get resolver path) 14 | (resolver source path))) 15 | 16 | (defmethod ac/reader 'file [opts _ arg] 17 | (let [p (resolve-path opts arg)] 18 | (slurp p))) 19 | 20 | (defn ->b64 21 | "Converts the input string to base64" 22 | [x] 23 | (.encodeToString (Base64/getEncoder) (.getBytes x))) 24 | 25 | (defn b64-> 26 | "Decodes from base64, returns a byte array." 27 | [x] 28 | (.decode (Base64/getDecoder) x)) 29 | 30 | (defmethod ac/reader 'to-b64 [_ _ arg] 31 | (->b64 arg)) 32 | 33 | (defmethod ac/reader 'from-b64 [_ _ arg] 34 | (b64-> arg)) 35 | 36 | (defmethod ac/reader 'privkey [_ _ arg] 37 | ;; If arg is a string, it's assumed to contain the key 38 | ;; If it's a vector, the first should be the key, the second the passphrase 39 | (let [[keystr passwd] (cond 40 | (string? arg) [arg nil] 41 | (vector? arg) arg 42 | :else (throw 43 | (ex-info "Private key must either consist of a string, or a vector containing the key and the passphrase" {:arg arg})))] 44 | (with-open [r (java.io.StringReader. keystr)] 45 | (pem/read-privkey r passwd)))) 46 | 47 | (defmethod ac/reader 'pubkey [_ _ arg] 48 | (with-open [r (java.io.StringReader. arg)] 49 | (pem/read-pubkey r))) 50 | 51 | (defmethod ac/reader 'to-edn [_ _ arg] 52 | (pr-str arg)) 53 | 54 | (defmethod ac/reader 'from-edn [opts _ arg] 55 | (with-open [r (PushbackReader. (StringReader. arg))] 56 | (ac/read-config r))) 57 | 58 | (defmethod ac/reader 'meta-merge [opts _ args] 59 | (apply mm/meta-merge args)) 60 | 61 | ;; Kept this for backwards compatibility 62 | (defmethod ac/reader 'deep-merge [opts _ args] 63 | (apply mm/meta-merge args)) 64 | 65 | (defmulti ->str class) 66 | 67 | (defmethod ->str java.lang.String [arg] 68 | arg) 69 | 70 | (def byte-array-class (class (byte-array 0))) 71 | 72 | (defmethod ->str byte-array-class [arg] 73 | (String. arg)) 74 | 75 | (defmethod ->str :default [arg] 76 | (str arg)) 77 | 78 | (defmethod ac/reader 'str [opts _ arg] 79 | (->str arg)) 80 | 81 | (defmethod ac/reader 'random [opts _ args] 82 | (nth args (rand-int (count args)))) 83 | -------------------------------------------------------------------------------- /test/monkey/aero_test.clj: -------------------------------------------------------------------------------- 1 | (ns monkey.aero-test 2 | (:require [clojure.test :refer [deftest testing is]] 3 | [babashka.fs :as fs] 4 | [clojure.java.io :as io] 5 | [aero.core :as ac] 6 | [monkey.aero :as sut])) 7 | 8 | (defn with-tmp-dir* [f] 9 | (let [dir (fs/create-temp-dir)] 10 | (try 11 | (f dir) 12 | (finally 13 | (fs/delete-tree dir))))) 14 | 15 | (defmacro with-tmp-dir [dir & body] 16 | `(with-tmp-dir* 17 | (fn [d#] 18 | (let [~dir d#] 19 | ~@body)))) 20 | 21 | (defn read-test-config [s] 22 | (with-tmp-dir dir 23 | (let [f (fs/file (fs/path dir "test-config.edn"))] 24 | (spit f s) 25 | (ac/read-config f)))) 26 | 27 | (deftest file 28 | (testing "reads file using the resolver" 29 | (is (= {:some-file "This is a test file\n"} 30 | (ac/read-config (io/resource "file-test.edn") {:resolver ac/resource-resolver}))))) 31 | 32 | (deftest to-b64 33 | (testing "converts arg to base64" 34 | (is (= {:value "anVzdCB0ZXN0aW5n"} 35 | (read-test-config "{:value #to-b64 \"just testing\"}"))))) 36 | 37 | (deftest from-b64 38 | (testing "converts arg from base64 to byte array" 39 | (is (= "just testing" 40 | (-> (read-test-config "{:value #from-b64 \"anVzdCB0ZXN0aW5n\"}") 41 | :value 42 | (String.)))))) 43 | 44 | (deftest privkey 45 | (testing "reads arg as pem private key" 46 | (is (instance? java.security.PrivateKey 47 | (-> (ac/read-config (io/resource "privkey-test.edn")) 48 | :private-key)))) 49 | 50 | (testing "can specify passkey" 51 | (is (instance? java.security.PrivateKey 52 | (-> (read-test-config "{:private-key #privkey [#file \"test-key.pem.enc\" \"secretpass\"]}") 53 | :private-key))))) 54 | 55 | (deftest pubkey 56 | (testing "reads arg as pem public key" 57 | (is (instance? java.security.PublicKey 58 | (-> (read-test-config "{:public-key #pubkey #file \"test-key-pub.pem\"}") 59 | :public-key))))) 60 | 61 | (deftest to-edn 62 | (testing "converts arg to edn" 63 | (is (= {:text "{:key \"value\"}"} 64 | (read-test-config "{:text #to-edn {:key \"value\"}}"))))) 65 | 66 | (deftest from-edn 67 | (testing "parses arg from edn" 68 | (is (= {:edn {:key "value"}} 69 | (read-test-config "{:edn #from-edn \"{:key \\\"value\\\"}\"}")))) 70 | 71 | (testing "applies aero tags in parsed edn" 72 | (is (= {:edn {:key "other-value" 73 | :other "other-value"}} 74 | (read-test-config "{:edn #from-edn \"{:key #ref [:other] :other \\\"other-value\\\"}\"}"))))) 75 | 76 | (defn- test-meta-merge [] 77 | (is (= {:top {:child [:first :second]}} 78 | (read-test-config "{:top #meta-merge [{:child [:second]} {:child ^:prepend [:first]}]}")))) 79 | 80 | (deftest deep-merge 81 | (testing "deep-merges maps" 82 | (is (= {:first {:second {:third "value" 83 | :fourth "other value"}}} 84 | (ac/read-config (io/resource "deep-merge-test.edn"))))) 85 | 86 | (testing "meta-merges datastructures" 87 | (is (= {:top {:child [:first :second]}} 88 | (read-test-config "{:top #deep-merge [{:child [:second]} {:child ^:prepend [:first]}]}"))))) 89 | 90 | (deftest meta-merge 91 | (testing "meta-merges datastructures" 92 | (is (= {:top {:child [:first :second]}} 93 | (read-test-config "{:top #meta-merge [{:child [:second]} {:child ^:prepend [:first]}]}"))))) 94 | 95 | (deftest str-tag 96 | (testing "converts byte array arg to string" 97 | (is (= {:value "just testing"} 98 | (read-test-config "{:value #str #from-b64 \"anVzdCB0ZXN0aW5n\"}")))) 99 | 100 | (testing "converts number to string" 101 | (is (= {:value "100"} 102 | (read-test-config "{:value #str 100}")))) 103 | 104 | (testing "leaves string arg unchanged" 105 | (is (= {:value "test"} 106 | (read-test-config "{:value #str \"test\"}"))))) 107 | 108 | (deftest random 109 | (testing "selects item at random from arg" 110 | (let [items (->> (range 10) 111 | (mapv (partial str "item-")))] 112 | (is (contains? (set items) 113 | (-> (format "{:item #random %s}" (pr-str items)) 114 | (read-test-config) 115 | :item)))))) 116 | -------------------------------------------------------------------------------- /tests.edn: -------------------------------------------------------------------------------- 1 | #kaocha/v1 {} 2 | --------------------------------------------------------------------------------