From 2064eb740f81d8dab1be7e1ce257d2a2fe224e9b Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 24 Jul 2022 14:27:38 -0500 Subject: [PATCH 01/44] Create enricher pattern, create equipment enrichers --- doc/enricher-pattern.md | 133 ++++++ src/brewtility/calculations.cljc | 1 + src/brewtility/enrich/equipment.cljc | 485 +++++++++++++++++++ src/brewtility/enrich/impl.cljc | 157 +++++++ test/brewtility/enrich/equipment_test.cljc | 517 +++++++++++++++++++++ 5 files changed, 1293 insertions(+) create mode 100644 doc/enricher-pattern.md create mode 100644 src/brewtility/enrich/equipment.cljc create mode 100644 src/brewtility/enrich/impl.cljc create mode 100644 test/brewtility/enrich/equipment_test.cljc diff --git a/doc/enricher-pattern.md b/doc/enricher-pattern.md new file mode 100644 index 0000000..5f1c33e --- /dev/null +++ b/doc/enricher-pattern.md @@ -0,0 +1,133 @@ +# Enricher Pattern + +In [BeerXML](http://www.beerxml.com/ "The XML standard to encode beer data"), and, by extension, [common-beer-format](https://github.com/Wall-Brew-Co/common-beer-format "A clojure library/spec for BeerXML"), there are specifications which ultimately represent and encode the same concept. +For a concrete example, consider a sample [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc "The specification for a piece of brewing equipment") record. + +```clj +{:name "8 Gal pot with 5 gal Igloo Cooler" + :boil-size 22.71 + :trub-chiller-loss 0.95 + :boil-time 60.0 + :version 1 + :tun-specific-heat 0.3 + :batch-size 18.93 + :display-boil-size "6.0 US Gallons"} +``` + +In the above, you can find two representations of the pre-boil volume that piece of equipment held. +By the standard, the `:boil-size` is standardized to be the volume in litres, and the `:display-boil-size` is meant to represent that value in a region and human friendly way. +This is great for users; however, it can be unweildy in applications for a few to store and transmit data which may only be used in the display layer. Programatically, we are often more interested in a smaller subset of the equipment record and will defer computing display values until they are needed. + +While the unit conversion is simple, it can often lead to front-end code like this: + +```clj +(defn display-equipment + [equipment system-of-measure] + [:span + [:h1 (:name equipment)] + [:ul + [:li (str "Boil volume: " (->display (convert-units (:boil-size equipment) system-of-measure)))] + (when (:tun-weight equipment) + [:li (str "Mash Tun Weight: " (->display (convert-units (:tun-weight equipment) system-of-measure)))]) + ... + ]]) +``` + +Helper functions may be extracted, but the above code would certainly benefit from the `:display-boil-size` and `:display-tun-weight` fields which may optionally exist on the `equipment` record. +As a utility library for beer data, brewtility comes with the functionality needed to compute these display fields; however, keeping them as loose datums isn't fully desireable either. +In the contexts we want display data available for an equipment record, it's much easier to provide that data with the equipment record. +To that end, this library implements an enrichment pattern. + +## Enrichers + +An enrichment function is a function from maps to maps, which non-destructively adds to the source value derived information. +For example, if we know the user's location, we could infer wether Metric or Imperial measurements would be more appropriate to display. +With that information, we could leverage an enricher to modify the prior equipment example: + +```clj +(def igloo-cooler + {:name "8 Gal pot with 5 gal Igloo Cooler" + :boil-size 22.71 + :trub-chiller-loss 0.95 + :boil-time 60.0 + :version 1 + :tun-specific-heat 0.3 + :batch-size 18.93}) + +(require '[brewtility.enrich.equipment :as enrich]) + +(enrich/enrich-display-boil-size igloo-cooler {:system-of-measure :imperial}) +;; => {:name "8 Gal pot with 5 gal Igloo Cooler" +;; :boil-size 22.71 +;; :trub-chiller-loss 0.95 +;; :boil-time 60.0 +;; :version 1 +;; :tun-specific-heat 0.3 +;; :batch-size 18.93 +;; :display-boil-size "6.0 US Gallons"} +;; +``` + +If we wanted to calculate multiple display values in serial, we can also perform a best-effort enrichment of the entire record. + +```clj +(enrich/enrich-equipment igloo-cooler {:system-of-measure :imperial}) +;; => {:name "8 Gal pot with 5 gal Igloo Cooler" +;; :boil-size 22.71 +;; :trub-chiller-loss 0.95 +;; :boil-time 60.0 +;; :version 1 +;; :tun-specific-heat 0.3 +;; :batch-size 18.93 +;; :display-boil-size "6.0 US Gallons" +;; :display-trub-chiller-loss "0.251 US Gallons" +;; :display-batch-size "5.0 US Gallons"} +;; +``` + +Or, in our example front-end: + +```clj +(defn fetch-equipment! + [equipment-id] + (-> (http/get (str some-url "/equipment/" equipment-id)) + :body + json/decode + enrich/enrich-equipment {:system-of-measure :imperial}))) + +(defn display-equipment + [equipment] + [:span + [:h1 (:name equipment)] + [:ul + [:li (str "Boil volume: " (:display-boil-size equipment))))] + (when (:display-tun-weight equipment) + [:li (str "Mash Tun Weight: " (display-tun-weight equipment))]) + ... + ]]) + +(defn fetch-and-display-equipment! + [equipment-id] + (-> equipment-id fetch-equipment! display-equipment)) +``` + +In the above, we're able to calculate display values for the boil size, batch size, and trub chiller loss since the data sources for that information. +While the equipment record does specify display values for the tun's volume, the source of that data is missing- and therefore excluded. + +## Implementations + +Enricher functions exist for each of the core specifications supported by BeerXML and common-beer-format. + +- [Equipment](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/equipment.cljc "Equipment enrichers") +- [Fermentables](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/fermentables.cljc "Fermentable enrichers") +- [Hops](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/hops.cljc "Hop enrichers") +- [Mash](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/mash.cljc "Mash enrichers") +- [Miscs](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/miscs.cljc "Misc enrichers") +- [Recipes](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/recipes.cljc "Recipe enrichers") +- [Styles](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/styles.cljc "Style enrichers") +- [Waters](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/waters.cljc "Water enrichers") +- [yeasts](https://github.com/Wall-Brew-Co/brewtility/blob/master/src/brewtility/enrich/yeasts.cljc "Yeast enrichers") + +## Inspiration + +- [Maybe Not - Rich Hickey](https://www.youtube.com/watch?v=YR5WdGrpoug&ab_channel=ClojureTV "A great presentation on the types of problems type systems try to solve") diff --git a/src/brewtility/calculations.cljc b/src/brewtility/calculations.cljc index 14e1259..6eb4575 100644 --- a/src/brewtility/calculations.cljc +++ b/src/brewtility/calculations.cljc @@ -169,6 +169,7 @@ (defn calculate-hop-utilization "Calculate the percentage of alpha acid that a hop could release over `boil-duration` in a wort at a specific `gravity`. Based on: http://howtobrew.com/book/section-1/hops/hop-bittering-calculations" + {:added "1.0"} [gravity boil-duration] (let [gravity-factor (* 1.65 (Math/pow 0.000125 (- gravity 1))) time-factor (/ (- 1 (Math/pow Math/E (* -0.04 boil-duration))) 4.15)] diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc new file mode 100644 index 0000000..9775930 --- /dev/null +++ b/src/brewtility/enrich/equipment.cljc @@ -0,0 +1,485 @@ +(ns brewtility.enrich.equipment + "Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.fermentables" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.calculations :as calc] + [brewtility.enrich.impl :as impl] + [brewtility.precision :as precision])) + + +(defn enrich-calculated-boil-size + "An enricher pattern function to calculate the boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record via [[brewtility.calculations/calculate-equipment-boil-volume]]. + In the BeerXML spec, this behavior is controlled by the `:calc-boil-volume` field. + When `:calc-boil-volume` is set to `true`, the `:boil-size` field is calculated as: + `(batch-size - top-up-water - trub-chiller-loss) * (1 + (boil-time * evap-rate))` + + When `:calc-boil-volume` is set to `false`, the `:boil-size` field is left unmodified. + As a note, both the BeerXML spec and common-beer-format only require the `boil-size` field to be a number. + Neither the specification nor the implementation will check to ensure the value is correct given the other fields. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - `:precision` - The number of decimal places to round the calculated value to. + Defaults to `3`." + {:added "1.3" + :see-also ["brewtility.calculations/calculate-equipment-boil-volume" + "enrich-equipment" + "enrich-equipment-wrapper"]} + ([equipment] (enrich-calculated-boil-size equipment {})) + ([{:keys [calc-boil-volume] + :as equipment} + {:keys [safe-calculating-boil-size precision] + :or {precision 3}}] + (try + (if calc-boil-volume + (let [derived-boil-size (precision/->precision (calc/calculate-equipment-boil-volume equipment) precision)] + (assoc equipment :boil-size derived-boil-size)) + equipment) + #?(:clj (catch Exception e + (if safe-calculating-boil-size + equipment + (throw e)))) + #?(:cljs (catch js/Error e + (if safe-calculating-boil-size + equipment + (throw e))))))) + + +(defn enrich-display-boil-size + "An enricher pattern function to add the displayable boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the boil size into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-boil-size equipment {})) + ([equipment + {:keys [boil-size-target-units boil-size-precision boil-size-suffix] + :as opts}] + (let [options (merge opts + {:value-key :boil-size + :display-key :display-boil-size + :fine-grain-target-units boil-size-target-units + :fine-grain-precision boil-size-precision + :fine-grain-suffix boil-size-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-batch-size + "An enricher pattern function to add the displayable batch size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the batch size into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the batch size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-batch-size equipment {})) + ([equipment + {:keys [batch-size-target-units batch-size-precision batch-size-suffix] + :as opts}] + (let [options (merge opts + {:value-key :batch-size + :display-key :display-batch-size + :fine-grain-target-units batch-size-target-units + :fine-grain-precision batch-size-precision + :fine-grain-suffix batch-size-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-tun-volume + "An enricher pattern function to add the displayable tun volume to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the tun volume into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the tun volume. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-tun-volume equipment {})) + ([equipment + {:keys [tun-volume-target-units tun-volume-precision tun-volume-suffix] + :as opts}] + (let [options (merge opts + {:value-key :tun-volume + :display-key :display-tun-volume + :fine-grain-target-units tun-volume-target-units + :fine-grain-precision tun-volume-precision + :fine-grain-suffix tun-volume-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-tun-weight + "An enricher pattern function to add the displayable tun weight to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the tun weight into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the tun weight. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-tun-weight equipment {})) + ([equipment + {:keys [tun-weight-target-units tun-weight-precision tun-weight-suffix] + :as opts}] + (let [options (merge opts + {:value-key :tun-weight + :display-key :display-tun-weight + :fine-grain-target-units tun-weight-target-units + :fine-grain-precision tun-weight-precision + :fine-grain-suffix tun-weight-suffix})] + (impl/enrich-displayable-weight equipment options)))) + + +(defn enrich-display-top-up-water + "An enricher pattern function to add the displayable top up water to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the top up water into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the top up water. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-top-up-water equipment {})) + ([equipment + {:keys [top-up-water-target-units top-up-water-precision top-up-water-suffix] + :as opts}] + (let [options (merge opts + {:value-key :top-up-water + :display-key :display-top-up-water + :fine-grain-target-units top-up-water-target-units + :fine-grain-precision top-up-water-precision + :fine-grain-suffix top-up-water-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-trub-chiller-loss + "An enricher pattern function to add the displayable trub chiller loss to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the trub chiller loss into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the trub chiller loss. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-trub-chiller-loss equipment {})) + ([equipment + {:keys [trub-chiller-loss-target-units trub-chiller-loss-precision trub-chiller-loss-suffix] + :as opts}] + (let [options (merge opts + {:value-key :trub-chiller-loss + :display-key :display-trub-chiller-loss + :fine-grain-target-units trub-chiller-loss-target-units + :fine-grain-precision trub-chiller-loss-precision + :fine-grain-suffix trub-chiller-loss-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-lauter-deadspace + "An enricher pattern function to add the displayable lauter deadspace to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the lauter deadspace into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the lauter deadspace. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-lauter-deadspace equipment {})) + ([equipment + {:keys [lauter-deadspace-target-units lauter-deadspace-precision lauter-deadspace-suffix] + :as opts}] + (let [options (merge opts + {:value-key :lauter-deadspace + :display-key :display-lauter-deadspace + :fine-grain-target-units lauter-deadspace-target-units + :fine-grain-precision lauter-deadspace-precision + :fine-grain-suffix lauter-deadspace-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-display-top-up-kettle + "An enricher pattern function to add the displayable top up kettle to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the top up kettle into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the top up kettle. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained selections within the context of `enrich-equipment` and `enrich-equipment-wrapper`, this function also supports the following keys: + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} + ([equipment] (enrich-display-top-up-kettle equipment {})) + ([equipment + {:keys [top-up-kettle-target-units top-up-kettle-precision top-up-kettle-suffix] + :as opts}] + (let [options (merge opts + {:value-key :top-up-kettle + :display-key :display-top-up-kettle + :fine-grain-target-units top-up-kettle-target-units + :fine-grain-precision top-up-kettle-precision + :fine-grain-suffix top-up-kettle-suffix})] + (impl/enrich-displayable-volume equipment options)))) + + +(defn enrich-equipment + "An enricher pattern function to derive as many values from an [equipment record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-calculated-boil-size]] + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - [[enrich-display-boil-size]] + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. + - [[enrich-display-batch-size]] + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. + - [[enrich-diplay-tun-volume]] + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. + - [[enrich-display-tun-weight]] + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. + - [[enrich-display-top-up-water]] + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. + - [[enrich-display-trub-chiller-loss]] + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. + - [[enrich-display-lauter-deadspace]] + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. + - [[enrich-display-top-up-kettle]] + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-calculated-boil-size" + "enrich-calculated-boil-size" + "enrich-diplay-tun-volume" + "enrich-display-tun-weight" + "enrich-display-top-up-water" + "enrich-display-trub-chiller-loss" + "enrich-display-lauter-deadspace" + "enrich-display-top-up-kettle" + "enrich-equipment-wrapper"]} + ([equipment] + (enrich-equipment equipment {})) + + ([equipment opts] + (-> equipment + (enrich-calculated-boil-size opts) + (enrich-display-boil-size opts) + (enrich-display-batch-size opts) + (enrich-display-tun-volume opts) + (enrich-display-tun-weight opts) + (enrich-display-top-up-water opts) + (enrich-display-trub-chiller-loss opts) + (enrich-display-lauter-deadspace opts) + (enrich-display-top-up-kettle opts)))) + + +(defn enrich-equipment-wrapper + "An enricher pattern function to derive as many values from an [equipment-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. + - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-calculated-boil-size]] + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - [[enrich-display-boil-size]] + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. + - [[enrich-display-batch-size]] + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. + - [[enrich-diplay-tun-volume]] + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. + - [[enrich-display-tun-weight]] + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. + - [[enrich-display-top-up-water]] + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. + - [[enrich-display-trub-chiller-loss]] + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. + - [[enrich-display-lauter-deadspace]] + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. + - [[enrich-display-top-up-kettle]] + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-calculated-boil-size" + "enrich-calculated-boil-size" + "enrich-diplay-tun-volume" + "enrich-display-tun-weight" + "enrich-display-top-up-water" + "enrich-display-trub-chiller-loss" + "enrich-display-lauter-deadspace" + "enrich-display-top-up-kettle" + "enrich-equipment"]} + ([equipment-wrapper] + (enrich-equipment-wrapper equipment-wrapper {})) + + ([equipment-wrapper opts] + (update equipment-wrapper :equipment enrich-equipment opts))) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc new file mode 100644 index 0000000..d6582f9 --- /dev/null +++ b/src/brewtility/enrich/impl.cljc @@ -0,0 +1,157 @@ +(ns brewtility.enrich.impl + {:no-doc true} + (:require [brewtility.precision :as precision] + [brewtility.units :as units])) + + +;; TODO: Pluralize strings +(defn ->displayable-volume + {:added "1.3.0" + :see-also ["->displayable-weight"]} + ([source-value source-units target-units] + (->displayable-volume source-value source-units target-units {:precision 3 + :suffix :short})) + ([source-value source-units target-units {:keys [precision suffix]}] + (-> source-value + (units/convert-volume source-units target-units) + (precision/->precision precision) + (str " " (get-in units/volume-measurements->display-name [target-units suffix]))))) + + +(defn ->displayable-weight + ([source-value source-units target-units] + (->displayable-weight source-value source-units target-units {:precision 3 + :suffix :short})) + ([source-value source-units target-units {:keys [precision suffix]}] + (-> source-value + (units/convert-weight source-units target-units) + (precision/->precision precision) + (str " " (get-in units/weight-measurements->display-name [target-units suffix]))))) + + +(def ^:private default-volume-by-system + {:imperial :imperial-gallon + :metric :litre + :us :american-gallon + :si :litre}) + + +(def ^:private default-weight-by-system + {:imperial :pound + :metric :kilogram + :us :pound + :si :kilogram}) + + +(defn target-unit-error + [error-map conversion-type target-units] + (let [error-msg (format "Invalid unit for %s conversion : %s. Allowed values are: %s" + (name conversion-type) + target-units + units/volume-measurements)] + (assoc error-map :units error-msg))) + + +(defn systems-of-meaure-error + [error-map conversion-type system-of-measure] + (let [error-msg (format "Invalid system of measure for %s conversion : %s. Allowed values are: %s" + (name conversion-type) + system-of-measure + units/systems-of-meaure)] + (assoc error-map :system-of-measure error-msg))) + + +(defn precision-error + [error-map conversion-type precision] + (let [error-msg (format "Invalid precision for %s conversion : %s. Must be an integer." + (name conversion-type) + precision)] + (assoc error-map :precision error-msg))) + + +(defn suffix-error + [error-map conversion-type suffix] + (let [error-msg (format "Invalid suffix type for %s conversion : %s. Allowed values are: %s" + (name conversion-type) + suffix + units/suffix-types)] + (assoc error-map :suffix error-msg))) + + +(defn verify-enrich-displayable-volume-opts + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? units/volume-measurements target-units) + valid-system? (contains? units/systems-of-meaure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? units/suffix-types suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :volume target-units) + (not valid-system?) (systems-of-meaure-error :volume system-of-measure) + (not valid-precision?) (precision-error :volume precision) + (not valid-suffix?) (suffix-error :volume suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid enrichment options: " errors))))) + + +(defn enrich-displayable-volume + {:added "1.3.0" + :see-also ["enrich-displayable-weight"]} + [source-data + {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + :or {system-of-measure :us + suffix :short + precision 3}}] + + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-volume (get default-volume-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-volume) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (verify-enrich-displayable-volume-opts + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] + (assoc source-data display-key (->displayable-volume source-value :liter target-units opts))) + source-data)) + + +(defn verify-enrich-displayable-weight-opts + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? units/weight-measurements target-units) + valid-system? (contains? units/systems-of-meaure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? units/suffix-types suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :weight target-units) + (not valid-system?) (systems-of-meaure-error :weight system-of-measure) + (not valid-precision?) (precision-error :weight precision) + (not valid-suffix?) (suffix-error :weight suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid enrichment options: " errors))))) + + +(defn enrich-displayable-weight + {:added "1.3.0" + :see-also ["enrich-displayable-volume"]} + [source-data + {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + :or {system-of-measure :us + suffix :short + precision 3}}] + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-weight (get default-weight-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-weight) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (verify-enrich-displayable-weight-opts + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] + (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) + source-data)) diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc new file mode 100644 index 0000000..b26d448 --- /dev/null +++ b/test/brewtility/enrich/equipment_test.cljc @@ -0,0 +1,517 @@ +(ns brewtility.enrich.equipment-test + (:require [brewtility.enrich.equipment :as equipment.enrich] + [clojure.spec.alpha :as s] + [clojure.spec.gen.alpha :as gen] + [common-beer-format.equipment :as equipment.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(def ^:const sample-equipment + {:lauter-deadspace 0.8 + :calc-boil-volume true + :top-up-water 0.5 + :hop-utilization 100.5 + :name "8 Gal pot with 5 gal Igloo Cooler" + :boil-size 26.2 + :trub-chiller-loss 0.8 + :boil-time 60.5 + :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + :tun-volume 19.9 + :top-up-kettle 0.5 + :tun-weight 2.5 + :version 1 + :tun-specific-heat 0.3 + :batch-size 19.9 + :evap-rate 9.0}) + + +(def ^:const sample-equipment-wrapper + {:equipment sample-equipment}) + + +(deftest static-test-data-check + (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" + (is (s/valid? ::equipment.format/equipment sample-equipment) + "Static test data should conform to common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment-wrapper sample-equipment-wrapper) + "Static test data should conform to common-beer-format.equipment/equipment-wrapper"))) + + +(deftest enrich-calculated-boil-size-tests + (testing "Ensure enrichment pattern works for calculating boil size" + (is (= 20.288 + (-> sample-equipment + equipment.enrich/enrich-calculated-boil-size + :boil-size)) + "Boil size can be derived in liters when sufficient data is present") + (is (= (:boil-size sample-equipment) + (-> sample-equipment + (dissoc :batch-size) + (equipment.enrich/enrich-calculated-boil-size {:safe-calculating-boil-size true}) + :boil-size)) + "Boil size will not be modified when required data for calculations are missing and `safe-calculating-boil-size` is true") + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate boil volume with non-numeric values" + (-> sample-equipment + (dissoc :batch-size) + equipment.enrich/enrich-calculated-boil-size + :boil-size)) + "Computation will throw an Exception when required data for calculations are missing and `safe-calculating-boil-size` is missing/false")) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate boil volume with non-numeric values" + (-> sample-equipment + (dissoc :batch-size) + equipment.enrich/enrich-calculated-boil-size + :boil-size)) + "Computation will throw an Exception when required data for calculations are missing and `safe-calculating-boil-size` is missing/false")) + (is (= "5.36 gal" + (-> sample-equipment + equipment.enrich/enrich-calculated-boil-size + equipment.enrich/enrich-display-boil-size + :display-boil-size))))) + + +(deftest enrich-display-boil-size-tests + (testing "Ensure enrichment pattern works for all displayable boil sizes" + (is (= "6.921 gal" + (-> sample-equipment + equipment.enrich/enrich-display-boil-size + :display-boil-size)) + "Boil size conversion defaults to US gallons and 3 significant figures of precision") + (is (= "6.92 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-boil-size {:precision 2}) + :display-boil-size)) + "Boil size precision can be set to 2 significant figures") + (is (= "6.921 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-boil-size {:suffix :full}) + :display-boil-size)) + "Boil size suffix can be set to full descriptive text") + (is (= "26.2 l" + (-> sample-equipment + (equipment.enrich/enrich-display-boil-size {:system-of-measure :metric}) + :display-boil-size))) + (is (= "110.7 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-boil-size {:boil-size-target-units :cup + :boil-size-precision 1 + :boil-size-suffix :full}) + :display-boil-size)) + "Broad settings can be overriden with boil-size specific settings") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-boil-size sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-batch-size-tests + (testing "Ensure enrichment pattern works for all displayable batch-sizes" + (is (= "5.257 gal" + (-> sample-equipment + equipment.enrich/enrich-display-batch-size + :display-batch-size)) + "batch-size conversion defaults to US gallons and 3 significant figures of precision") + (is (= "5.26 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-batch-size {:precision 2}) + :display-batch-size)) + "batch-size precision can be set to 2 significant figures") + (is (= "5.257 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-batch-size {:suffix :full}) + :display-batch-size)) + "batch-size suffix can be set to full descriptive text") + (is (= "19.9 l" + (-> sample-equipment + (equipment.enrich/enrich-display-batch-size {:system-of-measure :metric}) + :display-batch-size))) + (is (= "84.1 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-batch-size {:batch-size-target-units :cup + :batch-size-precision 1 + :batch-size-suffix :full}) + :display-batch-size)) + "Broad settings can be overriden with batch-size specific settings") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-batch-size sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-tun-volume-tests + (testing "Ensure enrichment pattern works for all displayable tun-volumes" + (is (= "5.257 gal" + (-> sample-equipment + equipment.enrich/enrich-display-tun-volume + :display-tun-volume)) + "tun-volume conversion defaults to US gallons and 3 significant figures of precision") + (is (= "5.26 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-volume {:precision 2}) + :display-tun-volume)) + "tun-volume precision can be set to 2 significant figures") + (is (= "5.257 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-volume {:suffix :full}) + :display-tun-volume)) + "tun-volume suffix can be set to full descriptive text") + (is (= "19.9 l" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-volume {:system-of-measure :metric}) + :display-tun-volume))) + (is (= "84.1 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-volume {:tun-volume-target-units :cup + :tun-volume-precision 1 + :tun-volume-suffix :full}) + :display-tun-volume)) + "Broad settings can be overriden with tun-volume specific settings") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-volume sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-tun-weight-tests + (testing "Ensure enrichment pattern works for all displayable tun-weights" + (is (= "5.512 lb" + (-> sample-equipment + equipment.enrich/enrich-display-tun-weight + :display-tun-weight)) + "tun-weight conversion defaults to US gallons and 3 significant figures of precision") + (is (= "5.51 lb" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-weight {:precision 2}) + :display-tun-weight)) + "tun-weight precision can be set to 2 significant figures") + (is (= "5.512 pound" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-weight {:suffix :full}) + :display-tun-weight)) + "tun-weight suffix can be set to full descriptive text") + (is (= "2.5 kg" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-weight {:system-of-measure :metric}) + :display-tun-weight))) + (is (= "88.2 ounce" + (-> sample-equipment + (equipment.enrich/enrich-display-tun-weight {:tun-weight-target-units :ounce + :tun-weight-precision 1 + :tun-weight-suffix :full}) + :display-tun-weight)) + "Broad settings can be overriden with tun-weight specific settings") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-weight sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-top-up-water-tests + (testing "Ensure enrichment pattern works for all displayable top-up-waters" + (is (= "0.132 gal" + (-> sample-equipment + equipment.enrich/enrich-display-top-up-water + :display-top-up-water)) + "top-up-water conversion defaults to US gallons and 3 significant figures of precision") + (is (= "0.13 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-water {:precision 2}) + :display-top-up-water)) + "top-up-water precision can be set to 2 significant figures") + (is (= "0.132 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-water {:suffix :full}) + :display-top-up-water)) + "top-up-water suffix can be set to full descriptive text") + (is (= "0.5 l" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-water {:system-of-measure :metric}) + :display-top-up-water))) + (is (= "2.1 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-water {:top-up-water-target-units :cup + :top-up-water-precision 1 + :top-up-water-suffix :full}) + :display-top-up-water)) + "Broad settings can be overriden with top-up-water specific settings") + (is (nil? (-> sample-equipment + (dissoc :top-up-water) + equipment.enrich/enrich-display-top-up-water + :display-top-up-water)) + ":display-top-up-water is not added if trub-chiller-loss is not present") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-water sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-trub-chiller-loss-tests + (testing "Ensure enrichment pattern works for all displayable trub-chiller-losss" + (is (= "0.211 gal" + (-> sample-equipment + equipment.enrich/enrich-display-trub-chiller-loss + :display-trub-chiller-loss)) + "trub-chiller-loss conversion defaults to US gallons and 3 significant figures of precision") + (is (= "0.21 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-trub-chiller-loss {:precision 2}) + :display-trub-chiller-loss)) + "trub-chiller-loss precision can be set to 2 significant figures") + (is (= "0.211 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-trub-chiller-loss {:suffix :full}) + :display-trub-chiller-loss)) + "trub-chiller-loss suffix can be set to full descriptive text") + (is (= "0.8 l" + (-> sample-equipment + (equipment.enrich/enrich-display-trub-chiller-loss {:system-of-measure :metric}) + :display-trub-chiller-loss))) + (is (= "3.4 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-trub-chiller-loss {:trub-chiller-loss-target-units :cup + :trub-chiller-loss-precision 1 + :trub-chiller-loss-suffix :full}) + :display-trub-chiller-loss)) + "Broad settings can be overriden with trub-chiller-loss specific settings") + (is (nil? (-> sample-equipment + (dissoc :trub-chiller-loss) + equipment.enrich/enrich-display-lauter-deadspace + :display-trub-chiller-loss)) + ":display-trub-chiller-loss is not added if trub-chiller-loss is not present") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-trub-chiller-loss sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-lauter-deadspace-tests + (testing "Ensure enrichment pattern works for all displayable lauter-deadspaces" + (is (= "0.211 gal" + (-> sample-equipment + equipment.enrich/enrich-display-lauter-deadspace + :display-lauter-deadspace)) + "lauter-deadspace conversion defaults to US gallons and 3 significant figures of precision") + (is (= "0.21 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-lauter-deadspace {:precision 2}) + :display-lauter-deadspace)) + "lauter-deadspace precision can be set to 2 significant figures") + (is (= "0.211 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-lauter-deadspace {:suffix :full}) + :display-lauter-deadspace)) + "lauter-deadspace suffix can be set to full descriptive text") + (is (= "0.8 l" + (-> sample-equipment + (equipment.enrich/enrich-display-lauter-deadspace {:system-of-measure :metric}) + :display-lauter-deadspace))) + (is (= "3.4 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-lauter-deadspace {:lauter-deadspace-target-units :cup + :lauter-deadspace-precision 1 + :lauter-deadspace-suffix :full}) + :display-lauter-deadspace)) + "Broad settings can be overriden with lauter-deadspace specific settings") + (is (nil? (-> sample-equipment + (dissoc :lauter-deadspace) + (equipment.enrich/enrich-display-lauter-deadspace {:lauter-deadspace-target-units :cup + :lauter-deadspace-precision 1 + :lauter-deadspace-suffix :full}) + :display-lauter-deadspace)) + "Display value will not be set if lauter-deadspace is not present") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-lauter-deadspace sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-display-top-up-kettle-tests + (testing "Ensure enrichment pattern works for all displayable top-up-kettles" + (is (= "0.132 gal" + (-> sample-equipment + equipment.enrich/enrich-display-top-up-kettle + :display-top-up-kettle)) + "top-up-kettle conversion defaults to US gallons and 3 significant figures of precision") + (is (= "0.13 gal" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-kettle {:precision 2}) + :display-top-up-kettle)) + "top-up-kettle precision can be set to 2 significant figures") + (is (= "0.132 US gallon" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-kettle {:suffix :full}) + :display-top-up-kettle)) + "top-up-kettle suffix can be set to full descriptive text") + (is (= "0.5 l" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-kettle {:system-of-measure :metric}) + :display-top-up-kettle))) + (is (= "2.1 cup" + (-> sample-equipment + (equipment.enrich/enrich-display-top-up-kettle {:top-up-kettle-target-units :cup + :top-up-kettle-precision 1 + :top-up-kettle-suffix :full}) + :display-top-up-kettle)) + "Broad settings can be overriden with top-up-kettle specific settings") + (is (nil? (-> sample-equipment + (dissoc :top-up-kettle) + equipment.enrich/enrich-display-top-up-kettle + :display-top-up-kettle)) + ":display-top-up-kettle is not added if top-up-kettle is not present") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-kettle sample-equipment)) + "Enrichment pattern should produce a valid equipment object"))) + + +(deftest enrich-equipment-tests + (testing "Ensure enrichment pattern works for all equipment" + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-equipment sample-equipment)) + "Enrichment pattern should produce a valid equipment object") + (is (= {:display-top-up-kettle "0.132 gal" + :display-batch-size "5.257 gal" + :lauter-deadspace 0.8 + :calc-boil-volume true + :top-up-water 0.5 + :hop-utilization 100.5 + :name "8 Gal pot with 5 gal Igloo Cooler" + :display-top-up-water "0.132 gal" + :boil-size 20.288 + :display-trub-chiller-loss "0.211 gal" + :display-lauter-deadspace "0.211 gal" + :trub-chiller-loss 0.8 + :boil-time 60.5 + :display-tun-weight "5.512 lb" + :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + :tun-volume 19.9 + :top-up-kettle 0.5 + :display-tun-volume "5.257 gal" + :display-boil-size "5.36 gal" + :tun-weight 2.5 + :version 1 + :tun-specific-heat 0.3 + :batch-size 19.9 + :evap-rate 9.0} + (equipment.enrich/enrich-equipment sample-equipment))) + (is (= {:display-top-up-kettle "0.5 litre" + :display-batch-size "19.9 litre" + :lauter-deadspace 0.8 + :calc-boil-volume true + :top-up-water 0.5 + :hop-utilization 100.5 + :name "8 Gal pot with 5 gal Igloo Cooler" + :display-top-up-water "0.5 litre" + :boil-size 20.3 + :display-trub-chiller-loss "0.8 litre" + :display-lauter-deadspace "0.8 litre" + :trub-chiller-loss 0.8 + :boil-time 60.5 + :display-tun-weight "2.5 kilogram" + :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + :tun-volume 19.9 + :top-up-kettle 0.5 + :display-tun-volume "19.9 litre" + :display-boil-size "20.3 litre" + :tun-weight 2.5 + :version 1 + :tun-specific-heat 0.3 + :batch-size 19.9 + :evap-rate 9.0} + (equipment.enrich/enrich-equipment sample-equipment {:system-of-measure :si + :precision 1 + :suffix :full})) + "Composed enrichment pattern global settings set default behavior for all enrichers"))) + + +(deftest enrich-equipment-wrapper-tests + (testing "Ensure enrichment pattern works for all equipment-wrapper" + (is (s/valid? ::equipment.format/equipment-wrapper + (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper)) + "Enrichment pattern should produce a valid equipment-wrapper object") + (is (= {:equipment {:display-top-up-kettle "0.132 gal" + :display-batch-size "5.257 gal" + :lauter-deadspace 0.8 + :calc-boil-volume true + :top-up-water 0.5 + :hop-utilization 100.5 + :name "8 Gal pot with 5 gal Igloo Cooler" + :display-top-up-water "0.132 gal" + :boil-size 20.288 + :display-trub-chiller-loss "0.211 gal" + :display-lauter-deadspace "0.211 gal" + :trub-chiller-loss 0.8 + :boil-time 60.5 + :display-tun-weight "5.512 lb" + :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + :tun-volume 19.9 + :top-up-kettle 0.5 + :display-tun-volume "5.257 gal" + :display-boil-size "5.36 gal" + :tun-weight 2.5 + :version 1 + :tun-specific-heat 0.3 + :batch-size 19.9 + :evap-rate 9.0}} + (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper))) + (is (= {:equipment {:display-top-up-kettle "0.5 litre" + :display-batch-size "19.9 litre" + :lauter-deadspace 0.8 + :calc-boil-volume true + :top-up-water 0.5 + :hop-utilization 100.5 + :name "8 Gal pot with 5 gal Igloo Cooler" + :display-top-up-water "0.5 litre" + :boil-size 20.3 + :display-trub-chiller-loss "0.8 litre" + :display-lauter-deadspace "0.8 litre" + :trub-chiller-loss 0.8 + :boil-time 60.5 + :display-tun-weight "2.5 kilogram" + :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + :tun-volume 19.9 + :top-up-kettle 0.5 + :display-tun-volume "19.9 litre" + :display-boil-size "20.3 litre" + :tun-weight 2.5 + :version 1 + :tun-specific-heat 0.3 + :batch-size 19.9 + :evap-rate 9.0}} + (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper {:system-of-measure :si + :precision 1 + :suffix :full})) + "Composed enrichment pattern global settings set default behavior for all enrichers"))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary equipment" + ;; We disable boil voulme calculation in generative tests because :boil-size must be positive + ;; Which puts tight constraints on the test data, meaning actual generation of values would be + ;; extremely unlikely or require highly complex generators. + (letfn [(gen-equipment [] (assoc (gen/generate (s/gen ::equipment.format/equipment)) :calc-boil-volume false))] + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-boil-size (gen-equipment))) + "enrich-display-boil-size is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-batch-size (gen-equipment))) + "enrich-display-batch-size is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-volume (gen-equipment))) + "enrich-display-tun-volume is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-weight (gen-equipment))) + "enrich-display-tun-weight is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-water (gen-equipment))) + "enrich-display-top-up-water is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) + "enrich-display-trub-chiller-loss is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) + "enrich-display-lauter-deadspace is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) + "enrich-display-top-up-kettle is a function to and from common-beer-format.equipment/equipment") + (is (s/valid? ::equipment.format/equipment + (equipment.enrich/enrich-equipment (gen-equipment))) + "enrich-equipment is a function to and from common-beer-format.equipment/equipment"))) + (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" + (is (s/valid? ::equipment.format/equipment-wrapper + (equipment.enrich/enrich-equipment-wrapper + (assoc-in (gen/generate (s/gen ::equipment.format/equipment-wrapper)) [:equipment :calc-boil-volume] false))) + "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) + From a5e561e92d336095baba676a8c40d6192f2e3e73 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 7 Aug 2022 08:11:39 -0500 Subject: [PATCH 02/44] Clean up doc metadata --- src/brewtility/enrich/impl.cljc | 36 +++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index d6582f9..2b90334 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -6,11 +6,12 @@ ;; TODO: Pluralize strings (defn ->displayable-volume - {:added "1.3.0" + {:added "1.3.0" + :no-doc true :see-also ["->displayable-weight"]} ([source-value source-units target-units] (->displayable-volume source-value source-units target-units {:precision 3 - :suffix :short})) + :suffix :short})) ([source-value source-units target-units {:keys [precision suffix]}] (-> source-value (units/convert-volume source-units target-units) @@ -19,6 +20,9 @@ (defn ->displayable-weight + {:added "1.3.0" + :no-doc true + :see-also ["->displayable-volume"]} ([source-value source-units target-units] (->displayable-weight source-value source-units target-units {:precision 3 :suffix :short})) @@ -44,6 +48,9 @@ (defn target-unit-error + {:added "1.3.0" + :no-doc true + :see-also ["systems-of-meaure-error" "precision-error" "suffix-error"]} [error-map conversion-type target-units] (let [error-msg (format "Invalid unit for %s conversion : %s. Allowed values are: %s" (name conversion-type) @@ -53,6 +60,9 @@ (defn systems-of-meaure-error + {:added "1.3.0" + :no-doc true + :see-also ["target-unit-error" "precision-error" "suffix-error"]} [error-map conversion-type system-of-measure] (let [error-msg (format "Invalid system of measure for %s conversion : %s. Allowed values are: %s" (name conversion-type) @@ -62,6 +72,9 @@ (defn precision-error + {:added "1.3.0" + :no-doc true + :see-also ["target-unit-error" "systems-of-meaure-error" "suffix-error"]} [error-map conversion-type precision] (let [error-msg (format "Invalid precision for %s conversion : %s. Must be an integer." (name conversion-type) @@ -70,6 +83,9 @@ (defn suffix-error + {:added "1.3.0" + :no-doc true + :see-also ["target-unit-error" "systems-of-meaure-error" "precision-error"]} [error-map conversion-type suffix] (let [error-msg (format "Invalid suffix type for %s conversion : %s. Allowed values are: %s" (name conversion-type) @@ -79,6 +95,9 @@ (defn verify-enrich-displayable-volume-opts + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-volume"]} [{:keys [target-units system-of-measure precision suffix] :as opts}] (let [valid-target? (contains? units/volume-measurements target-units) @@ -97,6 +116,7 @@ (defn enrich-displayable-volume {:added "1.3.0" + :no-doc true :see-also ["enrich-displayable-weight"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] @@ -119,6 +139,9 @@ (defn verify-enrich-displayable-weight-opts + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-weight"]} [{:keys [target-units system-of-measure precision suffix] :as opts}] (let [valid-target? (contains? units/weight-measurements target-units) @@ -137,6 +160,7 @@ (defn enrich-displayable-weight {:added "1.3.0" + :no-doc true :see-also ["enrich-displayable-volume"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] @@ -149,9 +173,9 @@ precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-weight-opts - {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) From 930a865c86dc3e569ee5fde12f81d73056aae7aa Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 7 Aug 2022 18:50:13 -0500 Subject: [PATCH 03/44] Add fermentables enricher --- src/brewtility/color.cljc | 328 ++++++++++++++++++ src/brewtility/enrich/fermentables.cljc | 374 +++++++++++++++++++++ src/brewtility/enrich/impl.cljc | 78 +++-- src/brewtility/string.cljc | 55 +++ src/brewtility/units/options.cljc | 4 + test/brewtility/data/equipment.cljc | 1 + test/brewtility/data/fermentables.cljc | 3 + test/brewtility/data/hops.cljc | 3 + test/brewtility/data/mash.cljc | 4 + test/brewtility/data/miscs.cljc | 3 + test/brewtility/data/recipes.cljc | 3 + test/brewtility/data/styles.cljc | 1 + test/brewtility/data/waters.cljc | 3 + test/brewtility/data/yeasts.cljc | 3 + test/brewtility/enrich/equipment_test.cljc | 175 ++++------ test/brewtility/string_test.cljc | 47 +++ 16 files changed, 945 insertions(+), 140 deletions(-) create mode 100644 src/brewtility/color.cljc create mode 100644 src/brewtility/enrich/fermentables.cljc create mode 100644 src/brewtility/string.cljc create mode 100644 test/brewtility/string_test.cljc diff --git a/src/brewtility/color.cljc b/src/brewtility/color.cljc new file mode 100644 index 0000000..f0c04c0 --- /dev/null +++ b/src/brewtility/color.cljc @@ -0,0 +1,328 @@ +(ns brewtility.color + "Namespace for calculating beer colors" + {:added "1.0"}) + + +(def ^:const color-systems + "The color systems available across brewtility" + #{:srm :ebc :lovibond :rgba}) + + +(def ^:const color-system->display-name + "A map from color system names to their full and short unit names" + {:srm {:full "standard reference method" + :short "srm"} + :ebc {:full "ebc" + :short "ebc"} + :lovibond {:full "degrees lovibond" + :short "°L"} + :rgba {:full "" + :short ""}}) + + +;; +;; SRM Beer Colors (https://en.wikipedia.org/wiki/Standard_Reference_Method) +;; +(def ^:const srm-1 + "An SRM of 1 mapped to an RGBa color code" + + "rgba(255,230,153,1)") + + +(def ^:const srm-2 + "An SRM of 2 mapped to an RGBa color code" + + "rgba(255,216,120,1)") + + +(def ^:const srm-3 + "An SRM of 3 mapped to an RGBa color code" + + "rgba(255,202,90,1)") + + +(def ^:const srm-4 + "An SRM of 4 mapped to an RGBa color code" + "rgba(255,191,66,1)") + + +(def ^:const srm-5 + "An SRM of 5 mapped to an RGBa color code" + "rgba(251,177,35,1)") + + +(def ^:const srm-6 + "An SRM of 6 mapped to an RGBa color code" + "rgba(248,166,0,1)") + + +(def ^:const srm-7 + "An SRM of 7 mapped to an RGBa color code" + "rgba(243,156,0,1)") + + +(def ^:const srm-8 + "An SRM of 8 mapped to an RGBa color code" + "rgba(234,143,0,1)") + + +(def ^:const srm-9 + "An SRM of 9 mapped to an RGBa color code" + "rgba(229,133,0,1)") + + +(def ^:const srm-10 + "An SRM of 10 mapped to an RGBa color code" + "rgba(222,124,0,1)") + + +(def ^:const srm-11 + "An SRM of 11 mapped to an RGBa color code" + "rgba(215,114,0,1)") + + +(def ^:const srm-12 + "An SRM of 12 mapped to an RGBa color code" + "rgba(207,105,0,1)") + + +(def ^:const srm-13 + "An SRM of 13 mapped to an RGBa color code" + "rgba(203,98,0,1)") + + +(def ^:const srm-14 + "An SRM of 14 mapped to an RGBa color code" + "rgba(195,89,0,1)") + + +(def ^:const srm-15 + "An SRM of 15 mapped to an RGBa color code" + "rgba(187,81,0,1)") + + +(def ^:const srm-16 + "An SRM of 16 mapped to an RGBa color code" + "rgba(181,76,0,1)") + + +(def ^:const srm-17 + "An SRM of 17 mapped to an RGBa color code" + "rgba(176,69,0,1)") + + +(def ^:const srm-18 + "An SRM of 18 mapped to an RGBa color code" + "rgba(166,62,0,1)") + + +(def ^:const srm-19 + "An SRM of 19 mapped to an RGBa color code" + "rgba(161,55,0,1)") + + +(def ^:const srm-20 + "An SRM of 20 mapped to an RGBa color code" + "rgba(155,50,0,1)") + + +(def ^:const srm-21 + "An SRM of 21 mapped to an RGBa color code" + "rgba(149,45,0,1)") + + +(def ^:const srm-22 + "An SRM of 22 mapped to an RGBa color code" + "rgba(142,41,0,1)") + + +(def ^:const srm-23 + "An SRM of 23 mapped to an RGBa color code" + "rgba(136,35,0,1)") + + +(def ^:const srm-24 + "An SRM of 24 mapped to an RGBa color code" + "rgba(130,30,0,1)") + + +(def ^:const srm-25 + "An SRM of 25 mapped to an RGBa color code" + "rgba(123,26,0,1)") + + +(def ^:const srm-26 + "An SRM of 26 mapped to an RGBa color code" + "rgba(119,25,0,1)") + + +(def ^:const srm-27 + "An SRM of 27 mapped to an RGBa color code" + "rgba(112,20,0,1)") + + +(def ^:const srm-28 + "An SRM of 28 mapped to an RGBa color code" + "rgba(106,14,0,1)") + + +(def ^:const srm-29 + "An SRM of 29 mapped to an RGBa color code" + "rgba(102,13,0,1)") + + +(def ^:const srm-30 + "An SRM of 30 mapped to an RGBa color code" + "rgba(94,11,0,1)") + + +(def ^:const srm-31 + "An SRM of 31 mapped to an RGBa color code" + "rgba(90,10,2,1)") + + +(def ^:const srm-32 + "An SRM of 32 mapped to an RGBa color code" + "rgba(96,9,3,1)") + + +(def ^:const srm-33 + "An SRM of 33 mapped to an RGBa color code" + "rgba(82,9,7,1)") + + +(def ^:const srm-34 + "An SRM of 34 mapped to an RGBa color code" + "rgba(76,5,5,1)") + + +(def ^:const srm-35 + "An SRM of 35 mapped to an RGBa color code" + "rgba(71,6,6,1)") + + +(def ^:const srm-36 + "An SRM of 36 mapped to an RGBa color code" + "rgba(68,6,7,1)") + + +(def ^:const srm-37 + "An SRM of 37 mapped to an RGBa color code" + "rgba(63,7,8,1)") + + +(def ^:const srm-38 + "An SRM of 38 mapped to an RGBa color code" + "rgba(59,6,7,1)") + + +(def ^:const srm-39 + "An SRM of 39 mapped to an RGBa color code" + "rgba(58,7,11,1)") + + +(def ^:const srm-40 + "An SRM of 40 mapped to an RGBa color code" + "rgba(3,4,3,1)") + + +(def srm-color-map + "A map of integer values to their closest SRM value as an RGBa color code" + {1 srm-1 + 2 srm-2 + 3 srm-3 + 4 srm-4 + 5 srm-5 + 6 srm-6 + 7 srm-7 + 8 srm-8 + 9 srm-9 + 10 srm-10 + 11 srm-11 + 12 srm-12 + 13 srm-13 + 14 srm-14 + 15 srm-15 + 16 srm-16 + 17 srm-17 + 18 srm-18 + 19 srm-19 + 20 srm-20 + 21 srm-21 + 22 srm-22 + 23 srm-23 + 24 srm-24 + 25 srm-25 + 26 srm-26 + 27 srm-27 + 28 srm-28 + 29 srm-29 + 30 srm-30 + 31 srm-31 + 32 srm-32 + 33 srm-33 + 34 srm-34 + 35 srm-35 + 36 srm-36 + 37 srm-37 + 38 srm-38 + 39 srm-39 + 40 srm-40}) + + +(defn lovibond->srm + "Convert the color described in degrees `lovibond` to the equivalent SRM color" + {:added "1.0"} + [lovibond] + (- (* lovibond 1.3546) 0.76)) + + +(defn srm->ebc + "Convert the color described by the `srm` to the equivalent EBC color" + {:added "1.0"} + [srm] + (* srm 1.97)) + + +(defn ebc->srm + "Convert the color described by the `ebc` to the equivalent SRM color" + {:added "1.0"} + [ebc] + (* ebc 0.508)) + + +(defn srm->lovibond + "Convert the color described in 'srm` to the equivalent degrees Lovibond" + {:added "1.0"} + [srm] + (/ (+ srm 0.76) 1.3546)) + + +(def lovibond->ebc + "Convert the color described in degrees 'lovibond` to the equivalent EBC color" + (comp srm->ebc lovibond->srm)) + + +(def ebc->lovibond + "Convert the color described in 'ebc` to the equivalent degrees Lovibond" + (comp srm->lovibond ebc->srm)) + + +(defn srm->rgba + "Given `srm-number`, return the closest, bounded applicable RGBA color string. + OPINIONATED: The provided `srm-number` will be bound to the common range from 1 to 40 + Decimal-like values are trimmed, not rounded." + {:added "1.0"} + [srm-number] + (let [srm-color (min (max (int srm-number) 1) 40)] + (get srm-color-map srm-color))) + + +(def lovibond->rgba + "Given `lovibond-number`, return the closest, bounded applicable RGBA color string." + (comp srm->rgba lovibond->srm)) + + +(def ebc->rgba + "Given `ebc-number`, return the closest, bounded applicable RGBA color string." + (comp srm->rgba ebc->srm)) diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc new file mode 100644 index 0000000..071727f --- /dev/null +++ b/src/brewtility/enrich/fermentables.cljc @@ -0,0 +1,374 @@ +(ns brewtility.enrich.fermentables + "Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.color :as color] + [brewtility.predicates.fermentables :as fermentables.predicate])) + + +(defn enrich-add-after-boil + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the :add-after-boil field is not present, this function will explicitly set it to false." + {:added "1.3" + :see-also ["enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-add-after-boil fermentable {})) + ([fermentable _opts] + (if (contains? fermentable :add-after-boil) + fermentable + (assoc fermentable :add-after-boil false)))) + + +(defn enrich-coarse-fine-diff + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a coarse/fine differential. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:coarse-fine-diff` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-coarse-fine-diff fermentable {})) + ([fermentable opts] + (if (or (fermentables.predicate/grain? fermentable opts) + (fermentables.predicate/adjunct? fermentable opts)) + fermentable + (dissoc fermentable :coarse-fine-diff)))) + + +(defn enrich-moisture + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a moisture content. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:moisture` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-moisture fermentable {})) + ([fermentable opts] + (if (or (fermentables.predicate/grain? fermentable opts) + (fermentables.predicate/adjunct? fermentable opts)) + fermentable + (dissoc fermentable :moisture)))) + + +(defn enrich-diastatic-power + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a listed Diastatic Power. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:diastatic-power` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-diastatic-power fermentable {})) + ([fermentable opts] + (if (or (fermentables.predicate/grain? fermentable opts) + (fermentables.predicate/adjunct? fermentable opts)) + fermentable + (dissoc fermentable :diastatic-power)))) + + +(defn enrich-protein + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have protein. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:protein` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-protein fermentable {})) + ([fermentable opts] + (if (or (fermentables.predicate/grain? fermentable opts) + (fermentables.predicate/adjunct? fermentable opts)) + fermentable + (dissoc fermentable :protein)))) + + +(defn enrich-recommend-mash + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:recommend-mash` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-recommend-mash fermentable {})) + ([fermentable opts] + (if (or (fermentables.predicate/grain? fermentable opts) + (fermentables.predicate/adjunct? fermentable opts)) + fermentable + (dissoc fermentable :recommend-mash)))) + + +(defn enrich-ibu-gallons-per-pound + "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `extract`. + When the fermetable is not a grain or adjunct, this function will dissoc `:ibu-gal-per-lb` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-ibu-gallons-per-pound fermentable {})) + ([fermentable opts] + (if (fermentables.predicate/extract? fermentable opts) + fermentable + (dissoc fermentable :ibu-gal-per-lb)))) + + +(defn enrich-display-color + "An enricher pattern function to determine what color a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + In the BeerXML spec, color is assumed to be in Lovibond for the `:type` of `grain`, and SRM for all other fermentables. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-display-color fermentable {})) + ([fermentable {:keys [color-system suffix] + :as opts}] + (let [source-color-system (if (fermentables.predicate/grain? fermentable opts) + :lovibond + :srm) + target-color-system (or color-system source-color-system) + suffix (or suffix :short)] + (if (and (contains? color/color-systems target-color-system) + (contains? #{:full :short} suffix)) + (let [source-color (if (fermentables.predicate/grain? fermentable opts) + (:color fermentable) + (color/srm->lovibond (:color fermentable))) + target-color (case target-color-system + :lovibond source-color + :srm (color/lovibond->srm source-color) + :ebc (color/lovibond->ebc source-color) + :rgba (color/lovibond->rgba source-color)) + suffix-string (get-in color/color-system->display-name [target-color-system suffix]) + display-value (str target-color suffix-string)] + (assoc fermentable :display-color display-value)) + (throw (ex-info "Invalid options for displaying fermentable color" {:color-system target-color-system + :allowed-color-systems color/color-systems + :suffix suffix + :allowed-suffixes #{:full :short}})))))) + + +(defn enrich-fermentable + "An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + {:added "1.3" + :see-also ["enrich-add-after-boil" + "enrich-coarse-fine-diff" + "enrich-moisture" + "enrich-diastatic-power" + "enrich-protein" + "enrich-recommend-mash" + "enrich-ibu-gallons-per-pound" + "enrich-display-color" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-fermentable fermentable {})) + ([fermentable opts] + (-> fermentable + (enrich-add-after-boil opts) + (enrich-coarse-fine-diff opts) + (enrich-moisture opts) + (enrich-diastatic-power opts) + (enrich-protein opts) + (enrich-recommend-mash opts) + (enrich-ibu-gallons-per-pound opts) + (enrich-display-color opts)))) + + +(defn enrich-fermentable-wrapper + "An enricher pattern function to derive as many values from an [fermentable-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + {:added "1.3" + :see-also ["enrich-add-after-boil" + "enrich-coarse-fine-diff" + "enrich-moisture" + "enrich-diastatic-power" + "enrich-protein" + "enrich-recommend-mash" + "enrich-ibu-gallons-per-pound" + "enrich-display-color" + "enrich-fermentable" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-fermentable-wrapper fermentable {})) + ([fermentable opts] + (update fermentable :fermentable enrich-fermentable opts))) + + +(defn enrich-fermentables + "An enricher pattern function to derive as many values from an [fermentables record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + {:added "1.3" + :see-also ["enrich-add-after-boil" + "enrich-coarse-fine-diff" + "enrich-moisture" + "enrich-diastatic-power" + "enrich-protein" + "enrich-recommend-mash" + "enrich-ibu-gallons-per-pound" + "enrich-display-color" + "enrich-fermentable-wrapper" + "enrich-fermentable" + "enrich-fermentables-wrapper"]} + ([fermentables] (enrich-fermentables fermentables {})) + ([fermentables opts] + (map #(enrich-fermentable-wrapper % opts) fermentables))) + + +(defn enrich-fermentables-wrapper + "An enricher pattern function to derive as many values from an [fermentables-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + {:added "1.3" + :see-also ["enrich-add-after-boil" + "enrich-coarse-fine-diff" + "enrich-moisture" + "enrich-diastatic-power" + "enrich-protein" + "enrich-recommend-mash" + "enrich-ibu-gallons-per-pound" + "enrich-display-color" + "enrich-fermentable" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentables] (enrich-fermentables-wrapper fermentables {})) + ([fermentables opts] + (update fermentables :fermentables enrich-fermentables opts))) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 2b90334..975e595 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -1,50 +1,54 @@ (ns brewtility.enrich.impl {:no-doc true} - (:require [brewtility.precision :as precision] - [brewtility.units :as units])) + (:require [brewtility.units :as units] + [brewtility.units.options :as options] + [brewtility.units.volume :as volume] + [brewtility.units.weight :as weight])) +(def default-display-options + "The default display options used for all enrichers." + {options/precision 3 + options/suffix options/short}) ;; TODO: Pluralize strings (defn ->displayable-volume + "Convert a volume then render it to a displayable value." {:added "1.3.0" :no-doc true :see-also ["->displayable-weight"]} ([source-value source-units target-units] - (->displayable-volume source-value source-units target-units {:precision 3 - :suffix :short})) - ([source-value source-units target-units {:keys [precision suffix]}] + (->displayable-volume source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] (-> source-value - (units/convert-volume source-units target-units) - (precision/->precision precision) - (str " " (get-in units/volume-measurements->display-name [target-units suffix]))))) + (volume/convert source-units target-units) + (volume/display target-units opts)))) (defn ->displayable-weight + "Convert a weight then render it to a displayable value." {:added "1.3.0" :no-doc true :see-also ["->displayable-volume"]} ([source-value source-units target-units] - (->displayable-weight source-value source-units target-units {:precision 3 - :suffix :short})) - ([source-value source-units target-units {:keys [precision suffix]}] + (->displayable-weight source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] (-> source-value - (units/convert-weight source-units target-units) - (precision/->precision precision) - (str " " (get-in units/weight-measurements->display-name [target-units suffix]))))) + (weight/convert source-units target-units) + (weight/display target-units opts)))) (def ^:private default-volume-by-system - {:imperial :imperial-gallon - :metric :litre - :us :american-gallon - :si :litre}) + {options/imperial options/imperial-gallon + options/metric options/litre + options/us-customary options/american-gallon + options/international-system options/litre}) (def ^:private default-weight-by-system - {:imperial :pound - :metric :kilogram - :us :pound - :si :kilogram}) + {options/imperial options/pound + options/metric options/kilogram + options/us-customary options/pound + options/international-system options/kilogram}) (defn target-unit-error @@ -55,7 +59,7 @@ (let [error-msg (format "Invalid unit for %s conversion : %s. Allowed values are: %s" (name conversion-type) target-units - units/volume-measurements)] + volume/measurements)] (assoc error-map :units error-msg))) @@ -67,7 +71,7 @@ (let [error-msg (format "Invalid system of measure for %s conversion : %s. Allowed values are: %s" (name conversion-type) system-of-measure - units/systems-of-meaure)] + options/systems-of-measure)] (assoc error-map :system-of-measure error-msg))) @@ -90,7 +94,7 @@ (let [error-msg (format "Invalid suffix type for %s conversion : %s. Allowed values are: %s" (name conversion-type) suffix - units/suffix-types)] + options/supported-suffixes)] (assoc error-map :suffix error-msg))) @@ -100,10 +104,10 @@ :see-also ["enrich-displayable-volume"]} [{:keys [target-units system-of-measure precision suffix] :as opts}] - (let [valid-target? (contains? units/volume-measurements target-units) - valid-system? (contains? units/systems-of-meaure system-of-measure) + (let [valid-target? (contains? volume/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) valid-precision? (int? precision) - valid-suffix? (contains? units/suffix-types suffix) + valid-suffix? (contains? options/supported-suffixes suffix) errors (cond-> {} (not valid-target?) (target-unit-error :volume target-units) (not valid-system?) (systems-of-meaure-error :volume system-of-measure) @@ -144,10 +148,10 @@ :see-also ["enrich-displayable-weight"]} [{:keys [target-units system-of-measure precision suffix] :as opts}] - (let [valid-target? (contains? units/weight-measurements target-units) - valid-system? (contains? units/systems-of-meaure system-of-measure) + (let [valid-target? (contains? weight/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) valid-precision? (int? precision) - valid-suffix? (contains? units/suffix-types suffix) + valid-suffix? (contains? options/supported-suffixes suffix) errors (cond-> {} (not valid-target?) (target-unit-error :weight target-units) (not valid-system?) (systems-of-meaure-error :weight system-of-measure) @@ -164,8 +168,8 @@ :see-also ["enrich-displayable-volume"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] - :or {system-of-measure :us - suffix :short + :or {system-of-measure options/us-customary + suffix options/short precision 3}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-weight (get default-weight-by-system system-of-measure) @@ -173,9 +177,9 @@ precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-weight-opts - {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc new file mode 100644 index 0000000..f8fc112 --- /dev/null +++ b/src/brewtility/string.cljc @@ -0,0 +1,55 @@ +(ns brewtility.string + "String comparison utilities" + {:added "1.3"} + (:require [clojure.string :as str])) + + +(defn prepare-for-compare + "Takes a string `s`, trims it, and coerces it to lower case. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s` will be cast to a string via `str`. Defaults to false." + {:added "1.3" + :see-also ["same?" "includes?"]} + ([s] (prepare-for-compare s {})) + + ([s {:keys [uppercase? coerce?]}] + (let [casing-fn (if uppercase? str/upper-case str/lower-case) + s' (if coerce? (str s) s)] + (-> s' str/trim casing-fn)))) + + +(defn same? + "Checks to see if `s1` and `s2` are equal after each string has been modified by `prepare-for-compare`. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." + {:added "1.3" + :see-also ["includes?"]} + ([s1 s2] (same? s1 s2 {})) + + ([s1 s2 opts] + (= (prepare-for-compare s1 opts) + (prepare-for-compare s2 opts)))) + + +(defn includes? + "Checks to see if `s1` includes `s2` after each string has been modified by `prepare-for-compare`. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." + {:added "1.3" + :see-also ["includes?"]} + ([s1 s2] (includes? s1 s2 {})) + + ([s1 s2 opts] + (str/includes? (prepare-for-compare s1 opts) (prepare-for-compare s2 opts)))) diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index b1f2676..8d9fc37 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -69,6 +69,10 @@ Commonly used with `brewtility.units` and in argument/option maps." :si) +(def systems-of-measure + "The set of supported measurement systems" + #{imperial metric us-customary international-system}) + ;; Enricher Setting Keys diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index 76b7864..2d48558 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -41,6 +41,7 @@ (gen/generate (spec/gen ::equipment.format/equipment))) + (defn generate-equipment-wrapper "Generate a random equipment-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index 544030e..ba66c9e 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -49,6 +49,7 @@ (gen/generate (spec/gen ::fermentables.format/fermentable))) + (defn generate-fermentable-wrapper "Generate a random fermentable-wrapper object" {:added "1.4" @@ -57,6 +58,7 @@ (gen/generate (spec/gen ::fermentables.format/fermentable-wrapper))) + (defn generate-fermentables "Generate a random fermentables object" {:added "1.4" @@ -65,6 +67,7 @@ (gen/generate (spec/gen ::fermentables.format/fermentables))) + (defn generate-fermentables-wrapper "Generate a random fermentables-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index 0ed0a19..e9d50ce 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -75,6 +75,7 @@ (gen/generate (spec/gen ::hops.format/hop))) + (defn generate-hop-wrapper "Generate a random hop-wrapper object" {:added "1.4" @@ -83,6 +84,7 @@ (gen/generate (spec/gen ::hops.format/hop-wrapper))) + (defn generate-hops "Generate a random hops object" {:added "1.4" @@ -91,6 +93,7 @@ (gen/generate (spec/gen ::hops.format/hops))) + (defn generate-hops-wrapper "Generate a random hops-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index 99f3234..9895cc7 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -49,6 +49,7 @@ (gen/generate (spec/gen ::mash.format/mash-step))) + (defn generate-mash-step-wrapper "Generate a random mash-step-wrapper object" {:added "1.4" @@ -57,6 +58,7 @@ (gen/generate (spec/gen ::mash.format/mash-step-wrapper))) + (defn generate-mash-steps "Generate a random mash-steps object" {:added "1.4" @@ -65,6 +67,7 @@ (gen/generate (spec/gen ::mash.format/mash-steps))) + (defn generate-mash "Generate a random mash object" {:added "1.4" @@ -73,6 +76,7 @@ (gen/generate (spec/gen ::mash.format/mash))) + (defn generate-mash-wrapper "Generate a random mash-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index b40f46f..771eed7 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -42,6 +42,7 @@ (gen/generate (spec/gen ::miscs.format/misc))) + (defn generate-misc-wrapper "Generate a random misc-wrapper object" {:added "1.4" @@ -50,6 +51,7 @@ (gen/generate (spec/gen ::miscs.format/misc-wrapper))) + (defn generate-miscs "Generate a random miscs object" {:added "1.4" @@ -58,6 +60,7 @@ (gen/generate (spec/gen ::miscs.format/miscs))) + (defn generate-miscs-wrapper "Generate a random miscs-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index d7f6fe5..ae339d1 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -86,6 +86,7 @@ (gen/generate (spec/gen ::recipes.format/recipe))) + (defn generate-recipe-wrapper "Generate a random recipe-wrapper object" {:added "1.4" @@ -94,6 +95,7 @@ (gen/generate (spec/gen ::recipes.format/recipe-wrapper))) + (defn generate-recipes "Generate a random recipes object" {:added "1.4" @@ -102,6 +104,7 @@ (gen/generate (spec/gen ::recipes.format/recipes))) + (defn generate-recipes-wrapper "Generate a random recipes-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 41c744b..12c8f64 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -55,6 +55,7 @@ (gen/generate (spec/gen ::style.format/style))) + (defn generate-style-wrapper "Generate a random style-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 19b7144..489303e 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -59,6 +59,7 @@ (gen/generate (spec/gen ::waters.format/water))) + (defn generate-water-wrapper "Generate a random water-wrapper object" {:added "1.4" @@ -67,6 +68,7 @@ (gen/generate (spec/gen ::waters.format/water-wrapper))) + (defn generate-waters "Generate a random waters object" {:added "1.4" @@ -75,6 +77,7 @@ (gen/generate (spec/gen ::waters.format/waters))) + (defn generate-waters-wrapper "Generate a random waters-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 1095176..135aecd 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -65,6 +65,7 @@ (gen/generate (spec/gen ::yeasts.format/yeast))) + (defn generate-yeast-wrapper "Generate a random yeast-wrapper object" {:added "1.4" @@ -73,6 +74,7 @@ (gen/generate (spec/gen ::yeasts.format/yeast-wrapper))) + (defn generate-yeasts "Generate a random yeasts object" {:added "1.4" @@ -81,6 +83,7 @@ (gen/generate (spec/gen ::yeasts.format/yeasts))) + (defn generate-yeasts-wrapper "Generate a random yeasts-wrapper object" {:added "1.4" diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index b26d448..9124c42 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -1,70 +1,39 @@ (ns brewtility.enrich.equipment-test - (:require [brewtility.enrich.equipment :as equipment.enrich] + (:require [brewtility.data.equipment :as equipment.data] + [brewtility.enrich.equipment :as equipment.enrich] [clojure.spec.alpha :as s] - [clojure.spec.gen.alpha :as gen] [common-beer-format.equipment :as equipment.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) -(def ^:const sample-equipment - {:lauter-deadspace 0.8 - :calc-boil-volume true - :top-up-water 0.5 - :hop-utilization 100.5 - :name "8 Gal pot with 5 gal Igloo Cooler" - :boil-size 26.2 - :trub-chiller-loss 0.8 - :boil-time 60.5 - :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." - :tun-volume 19.9 - :top-up-kettle 0.5 - :tun-weight 2.5 - :version 1 - :tun-specific-heat 0.3 - :batch-size 19.9 - :evap-rate 9.0}) - - -(def ^:const sample-equipment-wrapper - {:equipment sample-equipment}) - - -(deftest static-test-data-check - (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" - (is (s/valid? ::equipment.format/equipment sample-equipment) - "Static test data should conform to common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment-wrapper sample-equipment-wrapper) - "Static test data should conform to common-beer-format.equipment/equipment-wrapper"))) - - (deftest enrich-calculated-boil-size-tests (testing "Ensure enrichment pattern works for calculating boil size" (is (= 20.288 - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-calculated-boil-size :boil-size)) "Boil size can be derived in liters when sufficient data is present") - (is (= (:boil-size sample-equipment) - (-> sample-equipment + (is (= (:boil-size equipment.data/sample-equipment) + (-> equipment.data/sample-equipment (dissoc :batch-size) (equipment.enrich/enrich-calculated-boil-size {:safe-calculating-boil-size true}) :boil-size)) "Boil size will not be modified when required data for calculations are missing and `safe-calculating-boil-size` is true") #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate boil volume with non-numeric values" - (-> sample-equipment + (-> equipment.data/sample-equipment (dissoc :batch-size) equipment.enrich/enrich-calculated-boil-size :boil-size)) "Computation will throw an Exception when required data for calculations are missing and `safe-calculating-boil-size` is missing/false")) #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate boil volume with non-numeric values" - (-> sample-equipment + (-> equipment.data/sample-equipment (dissoc :batch-size) equipment.enrich/enrich-calculated-boil-size :boil-size)) "Computation will throw an Exception when required data for calculations are missing and `safe-calculating-boil-size` is missing/false")) (is (= "5.36 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-calculated-boil-size equipment.enrich/enrich-display-boil-size :display-boil-size))))) @@ -73,240 +42,240 @@ (deftest enrich-display-boil-size-tests (testing "Ensure enrichment pattern works for all displayable boil sizes" (is (= "6.921 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-boil-size :display-boil-size)) "Boil size conversion defaults to US gallons and 3 significant figures of precision") (is (= "6.92 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-boil-size {:precision 2}) :display-boil-size)) "Boil size precision can be set to 2 significant figures") (is (= "6.921 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-boil-size {:suffix :full}) :display-boil-size)) "Boil size suffix can be set to full descriptive text") (is (= "26.2 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-boil-size {:system-of-measure :metric}) :display-boil-size))) (is (= "110.7 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-boil-size {:boil-size-target-units :cup :boil-size-precision 1 :boil-size-suffix :full}) :display-boil-size)) "Broad settings can be overriden with boil-size specific settings") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-boil-size sample-equipment)) + (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-batch-size-tests (testing "Ensure enrichment pattern works for all displayable batch-sizes" (is (= "5.257 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-batch-size :display-batch-size)) "batch-size conversion defaults to US gallons and 3 significant figures of precision") (is (= "5.26 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-batch-size {:precision 2}) :display-batch-size)) "batch-size precision can be set to 2 significant figures") (is (= "5.257 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-batch-size {:suffix :full}) :display-batch-size)) "batch-size suffix can be set to full descriptive text") (is (= "19.9 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-batch-size {:system-of-measure :metric}) :display-batch-size))) (is (= "84.1 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-batch-size {:batch-size-target-units :cup :batch-size-precision 1 :batch-size-suffix :full}) :display-batch-size)) "Broad settings can be overriden with batch-size specific settings") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-batch-size sample-equipment)) + (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-tun-volume-tests (testing "Ensure enrichment pattern works for all displayable tun-volumes" (is (= "5.257 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-tun-volume :display-tun-volume)) "tun-volume conversion defaults to US gallons and 3 significant figures of precision") (is (= "5.26 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-volume {:precision 2}) :display-tun-volume)) "tun-volume precision can be set to 2 significant figures") (is (= "5.257 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-volume {:suffix :full}) :display-tun-volume)) "tun-volume suffix can be set to full descriptive text") (is (= "19.9 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-volume {:system-of-measure :metric}) :display-tun-volume))) (is (= "84.1 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-volume {:tun-volume-target-units :cup :tun-volume-precision 1 :tun-volume-suffix :full}) :display-tun-volume)) "Broad settings can be overriden with tun-volume specific settings") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-volume sample-equipment)) + (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-tun-weight-tests (testing "Ensure enrichment pattern works for all displayable tun-weights" (is (= "5.512 lb" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-tun-weight :display-tun-weight)) "tun-weight conversion defaults to US gallons and 3 significant figures of precision") (is (= "5.51 lb" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-weight {:precision 2}) :display-tun-weight)) "tun-weight precision can be set to 2 significant figures") (is (= "5.512 pound" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-weight {:suffix :full}) :display-tun-weight)) "tun-weight suffix can be set to full descriptive text") (is (= "2.5 kg" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-weight {:system-of-measure :metric}) :display-tun-weight))) (is (= "88.2 ounce" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-tun-weight {:tun-weight-target-units :ounce :tun-weight-precision 1 :tun-weight-suffix :full}) :display-tun-weight)) "Broad settings can be overriden with tun-weight specific settings") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-weight sample-equipment)) + (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-top-up-water-tests (testing "Ensure enrichment pattern works for all displayable top-up-waters" (is (= "0.132 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-top-up-water :display-top-up-water)) "top-up-water conversion defaults to US gallons and 3 significant figures of precision") (is (= "0.13 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-water {:precision 2}) :display-top-up-water)) "top-up-water precision can be set to 2 significant figures") (is (= "0.132 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-water {:suffix :full}) :display-top-up-water)) "top-up-water suffix can be set to full descriptive text") (is (= "0.5 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-water {:system-of-measure :metric}) :display-top-up-water))) (is (= "2.1 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-water {:top-up-water-target-units :cup :top-up-water-precision 1 :top-up-water-suffix :full}) :display-top-up-water)) "Broad settings can be overriden with top-up-water specific settings") - (is (nil? (-> sample-equipment + (is (nil? (-> equipment.data/sample-equipment (dissoc :top-up-water) equipment.enrich/enrich-display-top-up-water :display-top-up-water)) ":display-top-up-water is not added if trub-chiller-loss is not present") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-water sample-equipment)) + (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-trub-chiller-loss-tests (testing "Ensure enrichment pattern works for all displayable trub-chiller-losss" (is (= "0.211 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-trub-chiller-loss :display-trub-chiller-loss)) "trub-chiller-loss conversion defaults to US gallons and 3 significant figures of precision") (is (= "0.21 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-trub-chiller-loss {:precision 2}) :display-trub-chiller-loss)) "trub-chiller-loss precision can be set to 2 significant figures") (is (= "0.211 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-trub-chiller-loss {:suffix :full}) :display-trub-chiller-loss)) "trub-chiller-loss suffix can be set to full descriptive text") (is (= "0.8 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-trub-chiller-loss {:system-of-measure :metric}) :display-trub-chiller-loss))) (is (= "3.4 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-trub-chiller-loss {:trub-chiller-loss-target-units :cup :trub-chiller-loss-precision 1 :trub-chiller-loss-suffix :full}) :display-trub-chiller-loss)) "Broad settings can be overriden with trub-chiller-loss specific settings") - (is (nil? (-> sample-equipment + (is (nil? (-> equipment.data/sample-equipment (dissoc :trub-chiller-loss) equipment.enrich/enrich-display-lauter-deadspace :display-trub-chiller-loss)) ":display-trub-chiller-loss is not added if trub-chiller-loss is not present") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-trub-chiller-loss sample-equipment)) + (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-lauter-deadspace-tests (testing "Ensure enrichment pattern works for all displayable lauter-deadspaces" (is (= "0.211 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-lauter-deadspace :display-lauter-deadspace)) "lauter-deadspace conversion defaults to US gallons and 3 significant figures of precision") (is (= "0.21 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-lauter-deadspace {:precision 2}) :display-lauter-deadspace)) "lauter-deadspace precision can be set to 2 significant figures") (is (= "0.211 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-lauter-deadspace {:suffix :full}) :display-lauter-deadspace)) "lauter-deadspace suffix can be set to full descriptive text") (is (= "0.8 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-lauter-deadspace {:system-of-measure :metric}) :display-lauter-deadspace))) (is (= "3.4 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-lauter-deadspace {:lauter-deadspace-target-units :cup :lauter-deadspace-precision 1 :lauter-deadspace-suffix :full}) :display-lauter-deadspace)) "Broad settings can be overriden with lauter-deadspace specific settings") - (is (nil? (-> sample-equipment + (is (nil? (-> equipment.data/sample-equipment (dissoc :lauter-deadspace) (equipment.enrich/enrich-display-lauter-deadspace {:lauter-deadspace-target-units :cup :lauter-deadspace-precision 1 @@ -314,52 +283,52 @@ :display-lauter-deadspace)) "Display value will not be set if lauter-deadspace is not present") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-lauter-deadspace sample-equipment)) + (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-display-top-up-kettle-tests (testing "Ensure enrichment pattern works for all displayable top-up-kettles" (is (= "0.132 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment equipment.enrich/enrich-display-top-up-kettle :display-top-up-kettle)) "top-up-kettle conversion defaults to US gallons and 3 significant figures of precision") (is (= "0.13 gal" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-kettle {:precision 2}) :display-top-up-kettle)) "top-up-kettle precision can be set to 2 significant figures") (is (= "0.132 US gallon" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-kettle {:suffix :full}) :display-top-up-kettle)) "top-up-kettle suffix can be set to full descriptive text") (is (= "0.5 l" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-kettle {:system-of-measure :metric}) :display-top-up-kettle))) (is (= "2.1 cup" - (-> sample-equipment + (-> equipment.data/sample-equipment (equipment.enrich/enrich-display-top-up-kettle {:top-up-kettle-target-units :cup :top-up-kettle-precision 1 :top-up-kettle-suffix :full}) :display-top-up-kettle)) "Broad settings can be overriden with top-up-kettle specific settings") - (is (nil? (-> sample-equipment + (is (nil? (-> equipment.data/sample-equipment (dissoc :top-up-kettle) equipment.enrich/enrich-display-top-up-kettle :display-top-up-kettle)) ":display-top-up-kettle is not added if top-up-kettle is not present") (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-kettle sample-equipment)) + (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-equipment-tests (testing "Ensure enrichment pattern works for all equipment" (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-equipment sample-equipment)) + (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object") (is (= {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -385,7 +354,7 @@ :tun-specific-heat 0.3 :batch-size 19.9 :evap-rate 9.0} - (equipment.enrich/enrich-equipment sample-equipment))) + (equipment.enrich/enrich-equipment equipment.data/sample-equipment))) (is (= {:display-top-up-kettle "0.5 litre" :display-batch-size "19.9 litre" :lauter-deadspace 0.8 @@ -410,16 +379,16 @@ :tun-specific-heat 0.3 :batch-size 19.9 :evap-rate 9.0} - (equipment.enrich/enrich-equipment sample-equipment {:system-of-measure :si - :precision 1 - :suffix :full})) + (equipment.enrich/enrich-equipment equipment.data/sample-equipment {:system-of-measure :si + :precision 1 + :suffix :full})) "Composed enrichment pattern global settings set default behavior for all enrichers"))) (deftest enrich-equipment-wrapper-tests (testing "Ensure enrichment pattern works for all equipment-wrapper" (is (s/valid? ::equipment.format/equipment-wrapper - (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper)) + (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) "Enrichment pattern should produce a valid equipment-wrapper object") (is (= {:equipment {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -445,7 +414,7 @@ :tun-specific-heat 0.3 :batch-size 19.9 :evap-rate 9.0}} - (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper))) + (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper))) (is (= {:equipment {:display-top-up-kettle "0.5 litre" :display-batch-size "19.9 litre" :lauter-deadspace 0.8 @@ -470,9 +439,9 @@ :tun-specific-heat 0.3 :batch-size 19.9 :evap-rate 9.0}} - (equipment.enrich/enrich-equipment-wrapper sample-equipment-wrapper {:system-of-measure :si - :precision 1 - :suffix :full})) + (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper {:system-of-measure :si + :precision 1 + :suffix :full})) "Composed enrichment pattern global settings set default behavior for all enrichers"))) @@ -481,7 +450,7 @@ ;; We disable boil voulme calculation in generative tests because :boil-size must be positive ;; Which puts tight constraints on the test data, meaning actual generation of values would be ;; extremely unlikely or require highly complex generators. - (letfn [(gen-equipment [] (assoc (gen/generate (s/gen ::equipment.format/equipment)) :calc-boil-volume false))] + (letfn [(gen-equipment [] (assoc (equipment.data/generate-equipment) :calc-boil-volume false))] (is (s/valid? ::equipment.format/equipment (equipment.enrich/enrich-display-boil-size (gen-equipment))) "enrich-display-boil-size is a function to and from common-beer-format.equipment/equipment") @@ -512,6 +481,6 @@ (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" (is (s/valid? ::equipment.format/equipment-wrapper (equipment.enrich/enrich-equipment-wrapper - (assoc-in (gen/generate (s/gen ::equipment.format/equipment-wrapper)) [:equipment :calc-boil-volume] false))) + (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc new file mode 100644 index 0000000..117c58a --- /dev/null +++ b/test/brewtility/string_test.cljc @@ -0,0 +1,47 @@ +(ns brewtility.string-test + (:require [brewtility.string :as sut] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(deftest prepare-for-compare-test + (testing "Strings are appropriately re-cased and trimmed of whitespace" + (is (= "" (sut/prepare-for-compare " "))) + (is (= "clojure" (sut/prepare-for-compare "ClOjUrE "))) + (is (= "clojure" (sut/prepare-for-compare "clojure"))) + (is (= "100 lines of code" (sut/prepare-for-compare " 100 lines of CODE"))) + (is (= "a b" (sut/prepare-for-compare " a b "))) + (is (= "CLOJURE" (sut/prepare-for-compare "ClOjUrE " {:uppercase? true}))) + (is (= "CLOJURE" (sut/prepare-for-compare "clojure" {:uppercase? true}))) + (is (= "100 LINES OF CODE" (sut/prepare-for-compare " 100 lines of CODE" {:uppercase? true}))) + (is (= "A B" (sut/prepare-for-compare " a b " {:uppercase? true}))) + (is (= ":CLOJURE" (sut/prepare-for-compare :ClOjUrE {:uppercase? true :coerce? true}))) + (is (= "CLOJURE" (sut/prepare-for-compare "clojure" {:uppercase? true :coerce? true}))) + (is (= "100" (sut/prepare-for-compare 100 {:uppercase? true :coerce? true}))) + (is (= "true" (sut/prepare-for-compare true {:coerce? true}))) + (is (= "" (sut/prepare-for-compare nil {:coerce? true}))))) + + +(deftest same?-test + (testing "Strings containing matching characters after perparation match" + (is (true? (sut/same? " clojure" "CLOJURE "))) + (is (true? (sut/same? "clojure " " CLOJURE " {:uppercase? true}))) + (is (true? (sut/same? " 100 LINES OF CODE" "100 LINES OF CODE "))) + (is (false? (sut/same? "clo jure" "CLOJURE"))) + (is (false? (sut/same? "100" "!))" {:uppercase? true}))) + (is (true? (sut/same? true "true" {:coerce? true}))) + (is (true? (sut/same? nil "" {:coerce? true}))) + (is (true? (sut/same? :carrot ":CARROT" {:coerce? true}))))) + + +(deftest includes?-test + (testing "Strings containing matching characters after perparation match" + (is (true? (sut/includes? " clojure" "CLOJURE "))) + (is (true? (sut/includes? "CLOJURE " "c"))) + (is (true? (sut/includes? "clojure " " CLOJURE " {:uppercase? true}))) + (is (true? (sut/includes? "100 LINES OF CODE " " 100 "))) + (is (false? (sut/includes? "clo" "CLOJURE"))) + (is (false? (sut/includes? "100" "!))" {:uppercase? true}))) + (is (true? (sut/includes? "falsefaasetrue" true {:coerce? true}))) + (is (true? (sut/includes? nil "" {:coerce? true}))) + (is (true? (sut/includes? :carrot ":CARROT" {:coerce? true}))))) From 122674b5f9dad64e0b8cddcb1a9eeb0a7855d1e3 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 7 Aug 2022 19:46:36 -0500 Subject: [PATCH 04/44] Add hop predicates --- src/brewtility/string.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index f8fc112..7689ae1 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -31,7 +31,7 @@ - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." {:added "1.3" - :see-also ["includes?"]} + :see-also ["includes?" "prepare-for-compare"]} ([s1 s2] (same? s1 s2 {})) ([s1 s2 opts] @@ -48,7 +48,7 @@ - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." {:added "1.3" - :see-also ["includes?"]} + :see-also ["includes?" "prepare-for-compare"]} ([s1 s2] (includes? s1 s2 {})) ([s1 s2 opts] From 15628d116258f925b9805f12c05495e78d3d8425 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 8 Aug 2022 20:02:08 -0500 Subject: [PATCH 05/44] Add (un)wrapping functions --- test/brewtility/data/mash.cljc | 11 +++++++++++ test/brewtility/data/styles.cljc | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index 9895cc7..d5072ba 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -27,6 +27,10 @@ "A hard-coded sample mash-steps for static unit tests" [sample-mash-step-wrapper]) +(def ^:const sample-mash-steps-wrapper + "A hard-coded sample mash-steps-wrapper for static unit tests" + {:mash-steps sample-mash-steps}) + (def sample-mash "A hard-coded sample mash for static unit tests" @@ -67,6 +71,13 @@ (gen/generate (spec/gen ::mash.format/mash-steps))) +(defn generate-mash-steps-wrapper + "Generate a random mash-steps object" + {:added "1.3" + :no-doc true} + [] + {:mash-steps (gen/generate (s/gen ::mash.format/mash-steps))}) + (defn generate-mash "Generate a random mash object" diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 12c8f64..e3bc533 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -36,6 +36,14 @@ "A hard-coded sample style-wrapper for static unit tests" {:style sample-style}) +(def ^:const sample-styles + "A hard-coded sample styles for static unit tests" + [sample-style-wrapper]) + +(def ^:const sample-styles-wrapper + "A hard-coded sample styles-wrapper for static unit tests" + {:styles sample-styles}) + (def sample-styles "A hard-coded sample styles for static unit tests" @@ -79,6 +87,21 @@ [] (gen/generate (spec/gen ::style.format/styles-wrapper))) +(defn generate-styles + "Generate a random styles object" + {:added "1.3" + :no-doc true} + [] + (gen/generate (s/gen ::style.format/styles))) + + +(defn generate-styles-wrapper + "Generate a random styles-wrapper object" + {:added "1.3" + :no-doc true} + [] + (gen/generate (s/gen ::style.format/styles-wrapper))) + (deftest static-test-data-check (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" From ebf92e2a00b1881796140b5e945bdf0c4294fdaa Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Tue, 9 Aug 2022 07:15:51 -0500 Subject: [PATCH 06/44] Expand predicates to include recipes, styles, and waters --- test/brewtility/data/mash.cljc | 2 ++ test/brewtility/data/styles.cljc | 3 +++ test/brewtility/wrapping_test.cljc | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index d5072ba..f014c12 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -27,6 +27,7 @@ "A hard-coded sample mash-steps for static unit tests" [sample-mash-step-wrapper]) + (def ^:const sample-mash-steps-wrapper "A hard-coded sample mash-steps-wrapper for static unit tests" {:mash-steps sample-mash-steps}) @@ -71,6 +72,7 @@ (gen/generate (spec/gen ::mash.format/mash-steps))) + (defn generate-mash-steps-wrapper "Generate a random mash-steps object" {:added "1.3" diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index e3bc533..ae39466 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -36,10 +36,12 @@ "A hard-coded sample style-wrapper for static unit tests" {:style sample-style}) + (def ^:const sample-styles "A hard-coded sample styles for static unit tests" [sample-style-wrapper]) + (def ^:const sample-styles-wrapper "A hard-coded sample styles-wrapper for static unit tests" {:styles sample-styles}) @@ -87,6 +89,7 @@ [] (gen/generate (spec/gen ::style.format/styles-wrapper))) + (defn generate-styles "Generate a random styles object" {:added "1.3" diff --git a/test/brewtility/wrapping_test.cljc b/test/brewtility/wrapping_test.cljc index eafc330..f768e1e 100644 --- a/test/brewtility/wrapping_test.cljc +++ b/test/brewtility/wrapping_test.cljc @@ -23,6 +23,7 @@ [common-beer-format.yeasts :as yeasts.format])) + (deftest equipment-tests (testing "Wrapped equipment is a valid equipment-wrapper" (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper @@ -154,6 +155,26 @@ sut/unwrap-mash-step sut/wrap-mash-step))))) +<<<<<<< HEAD +======= + +(deftest mash-steps-tests + (testing "Unwrapped mash-steps is a valid mash-step" + (is (s/valid? ::mash.format/mash-steps + (sut/unwrap-mash-steps mash.data/sample-mash-steps-wrapper))) + (is (s/valid? ::mash.format/mash-steps + (sut/unwrap-mash-steps (mash.data/generate-mash-steps-wrapper))))) + (testing "(Un)wrapping is reversible" + (is (= mash.data/sample-mash-steps + (-> mash.data/sample-mash-steps + sut/wrap-mash-steps + sut/unwrap-mash-steps))) + (is (= mash.data/sample-mash-steps-wrapper + (-> mash.data/sample-mash-steps-wrapper + sut/unwrap-mash-steps + sut/wrap-mash-steps))))) +>>>>>>> e98f9f7 (Expand predicates to include recipes, styles, and waters) + (deftest mash-tests (testing "Wrapped mash is a valid mash-wrapper" From 2a5c3dbd048908b62d6bcc554d208c489f9fec24 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 21 Aug 2022 18:25:52 -0500 Subject: [PATCH 07/44] Finish predicate functions --- src/brewtility/enrich/fermentables.cljc | 2 +- src/brewtility/enrich/impl.cljc | 10 ++- src/brewtility/predicates/impl.clj | 20 +++++ src/brewtility/string.cljc | 40 +++++++++ src/brewtility/units/options.cljc | 1 + test/brewtility/data/equipment.cljc | 1 - test/brewtility/data/fermentables.cljc | 3 - test/brewtility/data/hops.cljc | 3 - test/brewtility/data/mash.cljc | 6 +- test/brewtility/data/miscs.cljc | 3 - test/brewtility/data/recipes.cljc | 14 +++- test/brewtility/data/styles.cljc | 7 +- test/brewtility/data/waters.cljc | 3 - test/brewtility/data/yeasts.cljc | 3 - test/brewtility/enrich/equipment_test.cljc | 84 +++++++++---------- test/brewtility/precision_test.cljc | 12 ++- .../predicates/fermentables_test.cljc | 1 + test/brewtility/string_test.cljc | 24 ++++++ test/brewtility/wrapping_test.cljc | 21 ----- 19 files changed, 160 insertions(+), 98 deletions(-) create mode 100644 src/brewtility/predicates/impl.clj diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 071727f..7604f18 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -208,7 +208,7 @@ (let [source-color (if (fermentables.predicate/grain? fermentable opts) (:color fermentable) (color/srm->lovibond (:color fermentable))) - target-color (case target-color-system + target-color (case target-color-system ; TODO: Add this functionality to the `units` namespace :lovibond source-color :srm (color/lovibond->srm source-color) :ebc (color/lovibond->ebc source-color) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 975e595..a3e6be0 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -5,11 +5,13 @@ [brewtility.units.volume :as volume] [brewtility.units.weight :as weight])) + (def default-display-options "The default display options used for all enrichers." {options/precision 3 options/suffix options/short}) + ;; TODO: Pluralize strings (defn ->displayable-volume "Convert a volume then render it to a displayable value." @@ -80,9 +82,11 @@ :no-doc true :see-also ["target-unit-error" "systems-of-meaure-error" "suffix-error"]} [error-map conversion-type precision] - (let [error-msg (format "Invalid precision for %s conversion : %s. Must be an integer." - (name conversion-type) - precision)] + (let [error-msg (str "Invalid precision for " + (name conversion-type) + " conversion : " + precision + ". Must be an integer.")] (assoc error-map :precision error-msg))) diff --git a/src/brewtility/predicates/impl.clj b/src/brewtility/predicates/impl.clj new file mode 100644 index 0000000..557d7b1 --- /dev/null +++ b/src/brewtility/predicates/impl.clj @@ -0,0 +1,20 @@ +(ns brewtility.predicates.impl + "Function to help minimize repeated code in predicate functions." + {:added "1.3" + :no-doc true}) + + +(defn fetch-or-throw! + "A helper function to fetch a value from a map or throw an exception. + Many predicates require information that is not automatically inferable, and no sane default may be assumed. + + Exception metadata is added to indicate the missing key and the map that was searched." + {:added "1.3" + :no-doc true} + [map' key' message] + (let [value (get map' key' ::not-found)] + (if (and (some? value) (not= value ::not-found)) + value + (throw (ex-info message {:error-type :missing-key + :missing-key key' + :original-value map'}))))) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index 7689ae1..821d1d0 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -53,3 +53,43 @@ ([s1 s2 opts] (str/includes? (prepare-for-compare s1 opts) (prepare-for-compare s2 opts)))) + + +(defn ->sporadic-case + "Take a string `s` and randomly coerce characters to either lower or upper case. + + For example: + + ```clj + (->sporadic-case \"hello world\") ;; => \"hElLo wOrLd\" + ```" + {:added "1.3" + :see-also ["->spongebob-case"]} + [^String s] + (letfn [(random-case + [l] + (if (rand-nth [true false]) + (str/upper-case l) + (str/lower-case l)))] + (->> s + seq + (map random-case) + (apply str)))) + + +(defn ->spongebob-case + "Take a string `s` and coerce characters alternatively between lower and upper case. + + For example: + + ```clj + (->spongebob-case \"spongebob\") ;; => \"sPoNgEbOb\" + ```" + {:added "1.3" + :see-also ["->sporadic-case"]} + [^String s] + (letfn [(spongebob-case + [acc l] + (let [casing-fn (if (odd? (count acc)) str/upper-case str/lower-case)] + (str acc (casing-fn l))))] + (reduce spongebob-case "" (seq s)))) diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 8d9fc37..0e5a9b1 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -69,6 +69,7 @@ Commonly used with `brewtility.units` and in argument/option maps." :si) + (def systems-of-measure "The set of supported measurement systems" #{imperial metric us-customary international-system}) diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index 2d48558..76b7864 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -41,7 +41,6 @@ (gen/generate (spec/gen ::equipment.format/equipment))) - (defn generate-equipment-wrapper "Generate a random equipment-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index ba66c9e..544030e 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -49,7 +49,6 @@ (gen/generate (spec/gen ::fermentables.format/fermentable))) - (defn generate-fermentable-wrapper "Generate a random fermentable-wrapper object" {:added "1.4" @@ -58,7 +57,6 @@ (gen/generate (spec/gen ::fermentables.format/fermentable-wrapper))) - (defn generate-fermentables "Generate a random fermentables object" {:added "1.4" @@ -67,7 +65,6 @@ (gen/generate (spec/gen ::fermentables.format/fermentables))) - (defn generate-fermentables-wrapper "Generate a random fermentables-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index e9d50ce..0ed0a19 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -75,7 +75,6 @@ (gen/generate (spec/gen ::hops.format/hop))) - (defn generate-hop-wrapper "Generate a random hop-wrapper object" {:added "1.4" @@ -84,7 +83,6 @@ (gen/generate (spec/gen ::hops.format/hop-wrapper))) - (defn generate-hops "Generate a random hops object" {:added "1.4" @@ -93,7 +91,6 @@ (gen/generate (spec/gen ::hops.format/hops))) - (defn generate-hops-wrapper "Generate a random hops-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index f014c12..cb4f108 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -54,7 +54,6 @@ (gen/generate (spec/gen ::mash.format/mash-step))) - (defn generate-mash-step-wrapper "Generate a random mash-step-wrapper object" {:added "1.4" @@ -63,7 +62,6 @@ (gen/generate (spec/gen ::mash.format/mash-step-wrapper))) - (defn generate-mash-steps "Generate a random mash-steps object" {:added "1.4" @@ -72,13 +70,12 @@ (gen/generate (spec/gen ::mash.format/mash-steps))) - (defn generate-mash-steps-wrapper "Generate a random mash-steps object" {:added "1.3" :no-doc true} [] - {:mash-steps (gen/generate (s/gen ::mash.format/mash-steps))}) + {:mash-steps (gen/generate (spec/gen ::mash.format/mash-steps))}) (defn generate-mash @@ -89,7 +86,6 @@ (gen/generate (spec/gen ::mash.format/mash))) - (defn generate-mash-wrapper "Generate a random mash-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index 771eed7..b40f46f 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -42,7 +42,6 @@ (gen/generate (spec/gen ::miscs.format/misc))) - (defn generate-misc-wrapper "Generate a random misc-wrapper object" {:added "1.4" @@ -51,7 +50,6 @@ (gen/generate (spec/gen ::miscs.format/misc-wrapper))) - (defn generate-miscs "Generate a random miscs object" {:added "1.4" @@ -60,7 +58,6 @@ (gen/generate (spec/gen ::miscs.format/miscs))) - (defn generate-miscs-wrapper "Generate a random miscs-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index ae339d1..e213cd4 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -17,6 +17,17 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) +(defn random-ibu-method + "Return a random valid hop type." + {:added "1.3" + :no-doc true} + [] + (-> recipes.format/ibu-method-types + vec + rand-nth + b-str/->sporadic-case)) + + (defn random-ibu-method "Return a random valid hop type." {:added "1.4" @@ -86,7 +97,6 @@ (gen/generate (spec/gen ::recipes.format/recipe))) - (defn generate-recipe-wrapper "Generate a random recipe-wrapper object" {:added "1.4" @@ -95,7 +105,6 @@ (gen/generate (spec/gen ::recipes.format/recipe-wrapper))) - (defn generate-recipes "Generate a random recipes object" {:added "1.4" @@ -104,7 +113,6 @@ (gen/generate (spec/gen ::recipes.format/recipes))) - (defn generate-recipes-wrapper "Generate a random recipes-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index ae39466..22d7747 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -1,5 +1,5 @@ (ns brewtility.data.styles - "Namespace for static and generative test data for `common-beer-format.styles/*` specs." + "Namespace for static and generative test data for `common-beer-format.stylespec/*` specs." (:require [clojure.spec.alpha :as spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] @@ -65,7 +65,6 @@ (gen/generate (spec/gen ::style.format/style))) - (defn generate-style-wrapper "Generate a random style-wrapper object" {:added "1.4" @@ -95,7 +94,7 @@ {:added "1.3" :no-doc true} [] - (gen/generate (s/gen ::style.format/styles))) + (gen/generate (spec/gen ::style.format/styles))) (defn generate-styles-wrapper @@ -103,7 +102,7 @@ {:added "1.3" :no-doc true} [] - (gen/generate (s/gen ::style.format/styles-wrapper))) + (gen/generate (spec/gen ::style.format/styles-wrapper))) (deftest static-test-data-check diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 489303e..19b7144 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -59,7 +59,6 @@ (gen/generate (spec/gen ::waters.format/water))) - (defn generate-water-wrapper "Generate a random water-wrapper object" {:added "1.4" @@ -68,7 +67,6 @@ (gen/generate (spec/gen ::waters.format/water-wrapper))) - (defn generate-waters "Generate a random waters object" {:added "1.4" @@ -77,7 +75,6 @@ (gen/generate (spec/gen ::waters.format/waters))) - (defn generate-waters-wrapper "Generate a random waters-wrapper object" {:added "1.4" diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 135aecd..1095176 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -65,7 +65,6 @@ (gen/generate (spec/gen ::yeasts.format/yeast))) - (defn generate-yeast-wrapper "Generate a random yeast-wrapper object" {:added "1.4" @@ -74,7 +73,6 @@ (gen/generate (spec/gen ::yeasts.format/yeast-wrapper))) - (defn generate-yeasts "Generate a random yeasts object" {:added "1.4" @@ -83,7 +81,6 @@ (gen/generate (spec/gen ::yeasts.format/yeasts))) - (defn generate-yeasts-wrapper "Generate a random yeasts-wrapper object" {:added "1.4" diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index 9124c42..e928205 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.equipment-test (:require [brewtility.data.equipment :as equipment.data] [brewtility.enrich.equipment :as equipment.enrich] - [clojure.spec.alpha :as s] + [clojure.spec.alpha :as spec] [common-beer-format.equipment :as equipment.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -67,8 +67,8 @@ :boil-size-suffix :full}) :display-boil-size)) "Broad settings can be overriden with boil-size specific settings") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -100,8 +100,8 @@ :batch-size-suffix :full}) :display-batch-size)) "Broad settings can be overriden with batch-size specific settings") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -133,8 +133,8 @@ :tun-volume-suffix :full}) :display-tun-volume)) "Broad settings can be overriden with tun-volume specific settings") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -166,8 +166,8 @@ :tun-weight-suffix :full}) :display-tun-weight)) "Broad settings can be overriden with tun-weight specific settings") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -204,8 +204,8 @@ equipment.enrich/enrich-display-top-up-water :display-top-up-water)) ":display-top-up-water is not added if trub-chiller-loss is not present") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -242,8 +242,8 @@ equipment.enrich/enrich-display-lauter-deadspace :display-trub-chiller-loss)) ":display-trub-chiller-loss is not added if trub-chiller-loss is not present") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -282,8 +282,8 @@ :lauter-deadspace-suffix :full}) :display-lauter-deadspace)) "Display value will not be set if lauter-deadspace is not present") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -320,15 +320,15 @@ equipment.enrich/enrich-display-top-up-kettle :display-top-up-kettle)) ":display-top-up-kettle is not added if top-up-kettle is not present") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-equipment-tests (testing "Ensure enrichment pattern works for all equipment" - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object") (is (= {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -387,8 +387,8 @@ (deftest enrich-equipment-wrapper-tests (testing "Ensure enrichment pattern works for all equipment-wrapper" - (is (s/valid? ::equipment.format/equipment-wrapper - (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) + (is (spec/valid? ::equipment.format/equipment-wrapper + (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) "Enrichment pattern should produce a valid equipment-wrapper object") (is (= {:equipment {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -451,36 +451,36 @@ ;; Which puts tight constraints on the test data, meaning actual generation of values would be ;; extremely unlikely or require highly complex generators. (letfn [(gen-equipment [] (assoc (equipment.data/generate-equipment) :calc-boil-volume false))] - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-boil-size (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-boil-size (gen-equipment))) "enrich-display-boil-size is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-batch-size (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-batch-size (gen-equipment))) "enrich-display-batch-size is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-volume (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-volume (gen-equipment))) "enrich-display-tun-volume is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-weight (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-tun-weight (gen-equipment))) "enrich-display-tun-weight is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-water (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-water (gen-equipment))) "enrich-display-top-up-water is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) "enrich-display-trub-chiller-loss is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) "enrich-display-lauter-deadspace is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) "enrich-display-top-up-kettle is a function to and from common-beer-format.equipment/equipment") - (is (s/valid? ::equipment.format/equipment - (equipment.enrich/enrich-equipment (gen-equipment))) + (is (spec/valid? ::equipment.format/equipment + (equipment.enrich/enrich-equipment (gen-equipment))) "enrich-equipment is a function to and from common-beer-format.equipment/equipment"))) (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" - (is (s/valid? ::equipment.format/equipment-wrapper - (equipment.enrich/enrich-equipment-wrapper - (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) + (is (spec/valid? ::equipment.format/equipment-wrapper + (equipment.enrich/enrich-equipment-wrapper + (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) diff --git a/test/brewtility/precision_test.cljc b/test/brewtility/precision_test.cljc index e0146b3..9ab803a 100644 --- a/test/brewtility/precision_test.cljc +++ b/test/brewtility/precision_test.cljc @@ -6,9 +6,15 @@ (deftest approximates?-test (testing "Ensure approximation works as expected" - (is (true? (sut/approximates? 100 100 0.00001))) - (is (true? (sut/approximates? 100 90 0.1))) - (is (false? (sut/approximates? 100 90 0.01))))) + (is (true? (sut/approximates? 100 100 0.00001)) + "Equal numbers will always return true") + (is (let [r-int (rand-int 1000000)] + (true? (sut/approximates? r-int r-int 0.00001))) + "Equal integers will always return true") + (is (true? (sut/approximates? 100 90 0.1)) + "90 is within 10% of 100") + (is (false? (sut/approximates? 100 90 0.01)) + "90 is not within 1% of 100"))) (deftest ->1dp-test diff --git a/test/brewtility/predicates/fermentables_test.cljc b/test/brewtility/predicates/fermentables_test.cljc index d9bebbd..e5a14c2 100644 --- a/test/brewtility/predicates/fermentables_test.cljc +++ b/test/brewtility/predicates/fermentables_test.cljc @@ -141,3 +141,4 @@ #?(:cljs (is (thrown-with-msg? js/Error #"Fermentable :type" (sut/adjunct? (dissoc fermentables/sample-fermentable :type))))))) + diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc index 117c58a..e4ea9f1 100644 --- a/test/brewtility/string_test.cljc +++ b/test/brewtility/string_test.cljc @@ -4,6 +4,12 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) +(defn rand-str + "Generate a random string of length `len`." + [len] + (apply str (take len (repeatedly #(char (+ (rand 26) 65)))))) + + (deftest prepare-for-compare-test (testing "Strings are appropriately re-cased and trimmed of whitespace" (is (= "" (sut/prepare-for-compare " "))) @@ -45,3 +51,21 @@ (is (true? (sut/includes? "falsefaasetrue" true {:coerce? true}))) (is (true? (sut/includes? nil "" {:coerce? true}))) (is (true? (sut/includes? :carrot ":CARROT" {:coerce? true}))))) + + +(deftest ->sporadic-case-tests + (testing "Re-cased strings are the `same` as their original value" + (is (sut/same? "clojure" (sut/->sporadic-case "clojure"))) + (is (sut/same? "100 lines of clojure" (sut/->sporadic-case "100 lines of clojure"))) + (is (sut/same? "clojure" (sut/->sporadic-case "CLOJURE")))) + (testing "Re-cased strings are stings" + (is (string? (sut/->sporadic-case (rand-str 1000)))))) + + +(deftest ->spongebob-case-tests + (testing "Re-cased strings are the `same` as their original value" + (is (sut/same? "clojure" (sut/->spongebob-case "clojure"))) + (is (sut/same? "100 lines of clojure" (sut/->spongebob-case "100 lines of clojure"))) + (is (sut/same? "clojure" (sut/->spongebob-case "CLOJURE")))) + (testing "Re-cased strings are stings" + (is (string? (sut/->spongebob-case (rand-str 1000)))))) diff --git a/test/brewtility/wrapping_test.cljc b/test/brewtility/wrapping_test.cljc index f768e1e..eafc330 100644 --- a/test/brewtility/wrapping_test.cljc +++ b/test/brewtility/wrapping_test.cljc @@ -23,7 +23,6 @@ [common-beer-format.yeasts :as yeasts.format])) - (deftest equipment-tests (testing "Wrapped equipment is a valid equipment-wrapper" (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper @@ -155,26 +154,6 @@ sut/unwrap-mash-step sut/wrap-mash-step))))) -<<<<<<< HEAD -======= - -(deftest mash-steps-tests - (testing "Unwrapped mash-steps is a valid mash-step" - (is (s/valid? ::mash.format/mash-steps - (sut/unwrap-mash-steps mash.data/sample-mash-steps-wrapper))) - (is (s/valid? ::mash.format/mash-steps - (sut/unwrap-mash-steps (mash.data/generate-mash-steps-wrapper))))) - (testing "(Un)wrapping is reversible" - (is (= mash.data/sample-mash-steps - (-> mash.data/sample-mash-steps - sut/wrap-mash-steps - sut/unwrap-mash-steps))) - (is (= mash.data/sample-mash-steps-wrapper - (-> mash.data/sample-mash-steps-wrapper - sut/unwrap-mash-steps - sut/wrap-mash-steps))))) ->>>>>>> e98f9f7 (Expand predicates to include recipes, styles, and waters) - (deftest mash-tests (testing "Wrapped mash is a valid mash-wrapper" From 2e470e034b1dfd36d56c5e058a17e3a2163688fd Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 21 Aug 2022 18:28:17 -0500 Subject: [PATCH 08/44] Fix predicate impl file extension --- src/brewtility/predicates/impl.clj | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/brewtility/predicates/impl.clj diff --git a/src/brewtility/predicates/impl.clj b/src/brewtility/predicates/impl.clj deleted file mode 100644 index 557d7b1..0000000 --- a/src/brewtility/predicates/impl.clj +++ /dev/null @@ -1,20 +0,0 @@ -(ns brewtility.predicates.impl - "Function to help minimize repeated code in predicate functions." - {:added "1.3" - :no-doc true}) - - -(defn fetch-or-throw! - "A helper function to fetch a value from a map or throw an exception. - Many predicates require information that is not automatically inferable, and no sane default may be assumed. - - Exception metadata is added to indicate the missing key and the map that was searched." - {:added "1.3" - :no-doc true} - [map' key' message] - (let [value (get map' key' ::not-found)] - (if (and (some? value) (not= value ::not-found)) - value - (throw (ex-info message {:error-type :missing-key - :missing-key key' - :original-value map'}))))) From 094cdb2775396b75f01014dea536732955db6930 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 21 Aug 2022 20:33:09 -0500 Subject: [PATCH 09/44] Add hop enrichers --- src/brewtility/enrich/fermentables.cljc | 203 +++++++++++---- src/brewtility/enrich/hops.cljc | 232 ++++++++++++++++++ src/brewtility/enrich/impl.cljc | 126 +++++++++- src/brewtility/units.cljc | 3 + test/brewtility/enrich/fermentables_test.cljc | 198 +++++++++++++++ test/brewtility/enrich/hops_test.cljc | 60 +++++ 6 files changed, 764 insertions(+), 58 deletions(-) create mode 100644 src/brewtility/enrich/hops.cljc create mode 100644 test/brewtility/enrich/fermentables_test.cljc create mode 100644 test/brewtility/enrich/hops_test.cljc diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 7604f18..ca435d7 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -10,6 +10,7 @@ "brewtility.enrich.waters" "brewtility.enrich.yeast"]} (:require [brewtility.color :as color] + [brewtility.enrich.impl :as impl] [brewtility.predicates.fermentables :as fermentables.predicate])) @@ -40,7 +41,8 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/grain?" + "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -64,7 +66,8 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/grain?" + "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -88,7 +91,8 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/grain?" + "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -112,7 +116,8 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/grain?" + "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -127,8 +132,8 @@ (defn enrich-recommend-mash "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will dissoc `:recommend-mash` from the fermentable. + In the BeerXML spec, this field should only be `true` if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will set `:recommend-mash` to false in the fermentable. An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: @@ -136,7 +141,8 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/grain?" + "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -145,14 +151,14 @@ ([fermentable opts] (if (or (fermentables.predicate/grain? fermentable opts) (fermentables.predicate/adjunct? fermentable opts)) - fermentable - (dissoc fermentable :recommend-mash)))) + (assoc fermentable :recommend-mash true) + (assoc fermentable :recommend-mash false)))) (defn enrich-ibu-gallons-per-pound "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `extract`. - When the fermetable is not a grain or adjunct, this function will dissoc `:ibu-gal-per-lb` from the fermentable. + When the fermetable is not an extract, this function will dissoc `:ibu-gal-per-lb` from the fermentable. An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: @@ -160,7 +166,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." {:added "1.3" - :see-also ["brewtility.string/same?" + :see-also ["brewtility.predicates.fermentables/extract?" "enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -179,8 +185,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:precision`: The number of significant decimal places to display. Defaults to 3. - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. @@ -188,14 +193,19 @@ - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained selections within the context of `enrich-fermentable` and `enrich-fermentable-wrapper`, this function also supports the following keys: + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" - :see-also ["brewtility.string/same?" - "enrich-fermentable" + :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" "enrich-fermentables-wrapper"]} ([fermentable] (enrich-display-color fermentable {})) + ;; TODO: Port this color conversion into the `units` namespace ([fermentable {:keys [color-system suffix] :as opts}] (let [source-color-system (if (fermentables.predicate/grain? fermentable opts) @@ -221,6 +231,44 @@ :suffix suffix :allowed-suffixes #{:full :short}})))))) +(defn enrich-display-amount + "An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + In the BeerXML spec, the amount of a liquid extract is computed by its weight. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-fermentable` and `enrich-fermentable-wrapper`, this function also supports the following keys: + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-fermentable" + "enrich-fermentable-wrapper" + "enrich-fermentables" + "enrich-fermentables-wrapper"]} + ([fermentable] (enrich-display-amount fermentable {})) + ([fermentable {:keys [fermentable-amount-target-units + fermentable-amount-precision + fermentable-amount-suffix] + :as opts}] + (let [options (merge opts {:value-key :amount + :display-key :display-amount + :fine-grain-target-units fermentable-amount-target-units + :fine-grain-precision fermentable-amount-precision + :fine-grain-suffix fermentable-amount-suffix})] + (impl/enrich-displayable-weight fermentable options)))) + (defn enrich-fermentable "An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). @@ -230,17 +278,30 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - [[enrich-display-color]] - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" @@ -250,6 +311,7 @@ "enrich-recommend-mash" "enrich-ibu-gallons-per-pound" "enrich-display-color" + "enrich-display-amount" "enrich-fermentable-wrapper" "enrich-fermentables" "enrich-fermentables-wrapper"]} @@ -263,7 +325,8 @@ (enrich-protein opts) (enrich-recommend-mash opts) (enrich-ibu-gallons-per-pound opts) - (enrich-display-color opts)))) + (enrich-display-color opts) + (enrich-display-amount opts)))) (defn enrich-fermentable-wrapper @@ -274,17 +337,30 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - [[enrich-display-color]] - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" @@ -294,6 +370,7 @@ "enrich-recommend-mash" "enrich-ibu-gallons-per-pound" "enrich-display-color" + "enrich-display-amount" "enrich-fermentable" "enrich-fermentables" "enrich-fermentables-wrapper"]} @@ -310,17 +387,30 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - [[enrich-display-color]] - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" @@ -330,6 +420,7 @@ "enrich-recommend-mash" "enrich-ibu-gallons-per-pound" "enrich-display-color" + "enrich-display-amount" "enrich-fermentable-wrapper" "enrich-fermentable" "enrich-fermentables-wrapper"]} @@ -346,17 +437,30 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - [[enrich-display-color]] - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`." + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" @@ -366,6 +470,7 @@ "enrich-recommend-mash" "enrich-ibu-gallons-per-pound" "enrich-display-color" + "enrich-display-amount" "enrich-fermentable" "enrich-fermentables" "enrich-fermentables-wrapper"]} diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc new file mode 100644 index 0000000..fc3797c --- /dev/null +++ b/src/brewtility/enrich/hops.cljc @@ -0,0 +1,232 @@ +(ns brewtility.enrich.hops + "Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + +(defn enrich-display-amount + "An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-hop" + "enrich-hop-wrapper" + "enrich-hops" + "enrich-hops-wrapper"]} + ([hop] (enrich-display-amount hop {})) + ([hop {:keys [hop-amount-target-units + hop-amount-precision + hop-amount-suffix] + :as opts}] + (let [options (merge opts {:value-key :amount + :display-key :display-amount + :fine-grain-target-units hop-amount-target-units + :fine-grain-precision hop-amount-precision + :fine-grain-suffix hop-amount-suffix})] + (impl/enrich-displayable-weight hop options)))) + +(defn enrich-display-time + "An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: + - `:hop-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:hop-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-hop" + "enrich-hop-wrapper" + "enrich-hops" + "enrich-hops-wrapper"]} + ([hop] (enrich-display-time hop {})) + ([hop {:keys [hop-time-target-units + hop-time-precision + hop-time-suffix] + :as opts}] + (let [options (merge opts {:value-key :time + :display-key :display-time + :fine-grain-target-units hop-time-target-units + :fine-grain-precision hop-time-precision + :fine-grain-suffix hop-time-suffix})] + (impl/enrich-displayable-time hop options)))) + +(defn enrich-hop + "An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-hop-wrapper" + "enrich-hops" + "enrich-hops-wrapper"]} + ([hop] (enrich-hop hop {})) + ([hop opts] + (-> hop + (enrich-display-amount opts) + (enrich-display-time opts)))) + +(defn enrich-hop-wrapper + "An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-hop" + "enrich-hops" + "enrich-hops-wrapper"]} + ([hop] (enrich-hop-wrapper hop {})) + ([hop opts] + (update hop :hop enrich-hop opts))) + + +(defn enrich-hops + "An enricher pattern function to derive as many values from an [hops record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-hop-wrapper" + "enrich-hop" + "enrich-hops-wrapper"]} + ([hops] (enrich-hops hops {})) + ([hops opts] + (map #(enrich-hop-wrapper % opts) hops))) + + +(defn enrich-hops-wrapper + "An enricher pattern function to derive as many values from an [hops-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-hop-wrapper" + "enrich-hops" + "enrich-hop"]} + ([hops] (enrich-hops-wrapper hops {})) + ([hops opts] + (update hops :hops enrich-hops opts))) + diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index a3e6be0..e4bde32 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -1,7 +1,9 @@ (ns brewtility.enrich.impl - {:no-doc true} - (:require [brewtility.units :as units] - [brewtility.units.options :as options] + {:no-doc true + :added "2.1" + :implementation-only true} + (:require [brewtility.units.options :as options] + [brewtility.units.time :as time] [brewtility.units.volume :as volume] [brewtility.units.weight :as weight])) @@ -17,7 +19,7 @@ "Convert a volume then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-weight"]} + :see-also ["->displayable-weight" "->displayable-time"]} ([source-value source-units target-units] (->displayable-volume source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -26,11 +28,12 @@ (volume/display target-units opts)))) +;; TODO: Pluralize strings (defn ->displayable-weight "Convert a weight then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-volume"]} + :see-also ["->displayable-volume" "->displayable-time"]} ([source-value source-units target-units] (->displayable-weight source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -38,6 +41,18 @@ (weight/convert source-units target-units) (weight/display target-units opts)))) +;; TODO: Pluralize strings +(defn ->displayable-time + "Convert a time then render it to a displayable value." + {:added "1.3.0" + :no-doc true + :see-also ["->displayable-volume" "->displayable-time"]} + ([source-value source-units target-units] + (->displayable-time source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] + (-> source-value + (time/convert source-units target-units) + (time/display target-units opts)))) (def ^:private default-volume-by-system {options/imperial options/imperial-gallon @@ -52,8 +67,15 @@ options/us-customary options/pound options/international-system options/kilogram}) +(def ^:private ^:const default-time-by-system + {:imperial :minute + :metric :minute + :us :minute + :si :minute}) + (defn target-unit-error + "A function to accumulate error messages in `error-map` if `target-units` is not a valid unit for `conversion-type`" {:added "1.3.0" :no-doc true :see-also ["systems-of-meaure-error" "precision-error" "suffix-error"]} @@ -66,6 +88,7 @@ (defn systems-of-meaure-error + "A function to accumulate error messages in `error-map` if `system-of-measure` is not valid for `conversion-type`" {:added "1.3.0" :no-doc true :see-also ["target-unit-error" "precision-error" "suffix-error"]} @@ -78,6 +101,7 @@ (defn precision-error + "A function to accumulate error messages in `error-map` if `precision` is not an integer" {:added "1.3.0" :no-doc true :see-also ["target-unit-error" "systems-of-meaure-error" "suffix-error"]} @@ -91,6 +115,7 @@ (defn suffix-error + "A function to accumulate error messages in `error-map` if `suffix` is not a valid choice" {:added "1.3.0" :no-doc true :see-also ["target-unit-error" "systems-of-meaure-error" "precision-error"]} @@ -103,6 +128,9 @@ (defn verify-enrich-displayable-volume-opts + "A function to verify the options map passed to `->displayable-volume` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, an Exception is thrown with information on the invalid options." {:added "1.3.0" :no-doc true :see-also ["enrich-displayable-volume"]} @@ -119,13 +147,24 @@ (not valid-suffix?) (suffix-error :volume suffix))] (if (empty? errors) opts - (throw (ex-info "Invalid enrichment options: " errors))))) + (throw (ex-info "Invalid displayable volume enrichment options: " errors))))) (defn enrich-displayable-volume + "A function to enrich a map with a human-readable version of a volume at `value-key`. + If invalid options are passed, the function throws an Exception with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `:fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the volume to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-weight"]} + :see-also ["enrich-displayable-weight" "enrich-displayable-time"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] :or {system-of-measure :us @@ -147,6 +186,9 @@ (defn verify-enrich-displayable-weight-opts + "A function to verify the options map passed to `->displayable-weight` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, an Exception is thrown with information on the invalid options." {:added "1.3.0" :no-doc true :see-also ["enrich-displayable-weight"]} @@ -163,13 +205,24 @@ (not valid-suffix?) (suffix-error :weight suffix))] (if (empty? errors) opts - (throw (ex-info "Invalid enrichment options: " errors))))) + (throw (ex-info "Invalid displayable weight enrichment options: " errors))))) (defn enrich-displayable-weight + "A function to enrich a map with a human-readable version of a weight at `value-key`. + If invalid options are passed, the function throws an Exception with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `:fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the weight to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-volume"]} + :see-also ["enrich-displayable-volume" "enrich-displayable-time"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] :or {system-of-measure options/us-customary @@ -187,3 +240,58 @@ :suffix suffix})] (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) + +(defn verify-enrich-displayable-time-opts + "A function to verify the options map passed to `->displayable-time` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, an Exception is thrown with information on the invalid options." + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-time"]} + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? time/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :time target-units) + (not valid-system?) (systems-of-meaure-error :time system-of-measure) + (not valid-precision?) (precision-error :time precision) + (not valid-suffix?) (suffix-error :time suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable time enrichment options: " errors))))) + +(defn enrich-displayable-time + "A function to enrich a map with a human-readable version of a time at `value-key`. + If invalid options are passed, the function throws an Exception with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `:fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the time to the target units and return the original value with the new value added at `display-key`" + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} + [source-data + {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + :or {system-of-measure :us + suffix :short + precision 3}}] + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-time (get default-time-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-time) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (verify-enrich-displayable-time-opts + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] + (assoc source-data display-key (->displayable-time source-value :minute target-units opts))) + source-data)) diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 76b1735..f968f6d 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -28,6 +28,9 @@ [brewtility.units.volume :as volume] [brewtility.units.weight :as weight])) +;; +;; Weight +;; (defn convert "Given a `measurement` in `source-units`, convert it to the `target-units` in a given `measurement-type`. diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc new file mode 100644 index 0000000..2ab5bc8 --- /dev/null +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -0,0 +1,198 @@ +(ns brewtility.enrich.fermentables-test + (:require [brewtility.data.fermentables :as fermentable.data] + [brewtility.enrich.fermentables :as fermentable.enrich] + [clojure.spec.alpha :as s] + [common-beer-format.fermentables :as fermentable.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + +(deftest enrich-add-after-boil-test + (testing "add-after-boil can be derived from a fermentable" + (is (boolean? (:add-after-boil (fermentable.enrich/enrich-add-after-boil (fermentable.data/generate-fermentable)))) + "enrich-add-after-boil is a function from a fermentable to a map with a boolean add-after-boil key") + (is (boolean? (:add-after-boil (fermentable.enrich/enrich-add-after-boil fermentable.data/sample-fermentable))) + "enrich-add-after-boil is a function from a fermentable to a map with a boolean add-after-boil key") + (is (true? (-> fermentable.data/sample-fermentable + (assoc :add-after-boil true) + fermentable.enrich/enrich-add-after-boil + :add-after-boil)) + "enrich-add-after-boil adds true when the add-after-boil key is truthy") + (is (false? (-> fermentable.data/sample-fermentable + (assoc :add-after-boil false) + fermentable.enrich/enrich-add-after-boil + :add-after-boil)) + "enrich-add-after-boil adds false when the add-after-boil key is falsy") + (is (false? (-> fermentable.data/sample-fermentable + (dissoc :add-after-boil) + fermentable.enrich/enrich-add-after-boil + :add-after-boil)) + "enrich-add-after-boil adds false when the add-after-boil key is nil"))) + +(deftest enrich-coarse-fine-diff-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") + sample-extract (assoc fermentable.data/sample-fermentable :type "extract") + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract") + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar")] + (testing "coarse-fine-diff is only applicable for grains and adjuncts" + (is (some? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-grain)))) + (is (some? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-adjunct))))) + (testing "coarse-fine-diff is not applicable for any other types" + (is (nil? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-extract)))) + (is (nil? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-dry-extract)))) + (is (nil? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-sugar))))))) + +(deftest enrich-moisture-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") + sample-extract (assoc fermentable.data/sample-fermentable :type "extract") + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract") + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar")] + (testing "moisture is only applicable for grains and adjuncts" + (is (some? (:moisture (fermentable.enrich/enrich-moisture sample-grain)))) + (is (some? (:moisture (fermentable.enrich/enrich-moisture sample-adjunct))))) + (testing "moisture is not applicable for any other types" + (is (nil? (:moisture (fermentable.enrich/enrich-moisture sample-extract)))) + (is (nil? (:moisture (fermentable.enrich/enrich-moisture sample-dry-extract)))) + (is (nil? (:moisture (fermentable.enrich/enrich-moisture sample-sugar))))))) + +(deftest enrich-diastatic-power-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") + sample-extract (assoc fermentable.data/sample-fermentable :type "extract") + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract") + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar")] + (testing "diastatic-power is only applicable for grains and adjuncts" + (is (some? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-grain)))) + (is (some? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-adjunct))))) + (testing "diastatic-power is not applicable for any other types" + (is (nil? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-extract)))) + (is (nil? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-dry-extract)))) + (is (nil? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-sugar))))))) + +(deftest enrich-protein-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") + sample-extract (assoc fermentable.data/sample-fermentable :type "extract") + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract") + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar")] + (testing "protein is only applicable for grains and adjuncts" + (is (some? (:protein (fermentable.enrich/enrich-protein sample-grain)))) + (is (some? (:protein (fermentable.enrich/enrich-protein sample-adjunct))))) + (testing "protein is not applicable for any other types" + (is (nil? (:protein (fermentable.enrich/enrich-protein sample-extract)))) + (is (nil? (:protein (fermentable.enrich/enrich-protein sample-dry-extract)))) + (is (nil? (:protein (fermentable.enrich/enrich-protein sample-sugar))))))) + +(deftest enrich-recommend-mash-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") + sample-extract (assoc fermentable.data/sample-fermentable :type "extract") + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract") + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar")] + (testing "recommend-mash is only applicable for grains and adjuncts" + (is (true? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-grain)))) + (is (true? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-adjunct))))) + (testing "recommend-mash is not applicable for any other types" + (is (false? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-extract)))) + (is (false? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-dry-extract)))) + (is (false? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-sugar))))))) + +(deftest enrich-ibu-gal-per-lb-test + (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain" :ibu-gal-per-lb 0.123) + sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct" :ibu-gal-per-lb 0.123) + sample-extract (assoc fermentable.data/sample-fermentable :type "extract" :ibu-gal-per-lb 0.123) + sample-dry-extract (assoc fermentable.data/sample-fermentable :type "dry extract" :ibu-gal-per-lb 0.123) + sample-sugar (assoc fermentable.data/sample-fermentable :type "sugar" :ibu-gal-per-lb 0.123)] + (testing "ibu-gal-per-lb is only applicable for extracts" + (is (some? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-extract))))) + (testing "ibu-gal-per-lb is not applicable for any other types" + (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-grain)))) + (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-adjunct)))) + (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-dry-extract)))) + (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-sugar))))))) + +;; +;; Whole object enrichment tests +;; + +(deftest enrich-fermentable-tests + (testing "Ensure enrichment pattern functions generate conforming data" + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)) + "Enrichment pattern should produce a valid fermentable object") + (is (s/valid? ::fermentable.format/fermentable-wrapper + (fermentable.enrich/enrich-fermentable-wrapper fermentable.data/sample-fermentable-wrapper)) + "Enrichment pattern should produce a valid fermentable object") + (is (s/valid? ::fermentable.format/fermentables + (fermentable.enrich/enrich-fermentables fermentable.data/sample-fermentables)) + "Enrichment pattern should produce a valid fermentable object") + (is (s/valid? ::fermentable.format/fermentables-wrapper + (fermentable.enrich/enrich-fermentables-wrapper fermentable.data/sample-fermentables-wrapper)) + "Enrichment pattern should produce a valid fermentable object") + (testing "Static data comparison for enrichment pattern functions" + (is (= {:amount 0.45 + :yield 78.0 + :supplier "Gnome Brew" + :color 500.0 + :display-color "500.0°L" + :name "Black Barley" + :moisture 5.0 + :type "Grain" + :add-after-boil false + :display-amount "0.992 lb" + :notes "Unmalted roasted barley for stouts, porters" + :protein 13.2 + :origin "United States" + :coarse-fine-diff 1.5 + :version 1 + :max-in-batch 10.0 + :recommend-mash true + :diastatic-power 0.0} + (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary fermentable" + (letfn [(gen-fermentable [] (fermentable.data/generate-fermentable))] + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-add-after-boil (gen-fermentable))) + "enrich-add-after-boil is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-coarse-fine-diff (gen-fermentable))) + "enrich-coarse-fine-diff is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-moisture (gen-fermentable))) + "enrich-moisture is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-diastatic-power (gen-fermentable))) + "enrich-diastatic-power is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-protein (gen-fermentable))) + "enrich-protein is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-recommend-mash (gen-fermentable))) + "enrich-recommend-mash is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-ibu-gallons-per-pound (gen-fermentable))) + "enrich-ibu-gallons-per-pound is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-display-color (gen-fermentable))) + "enrich-display-color is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-display-amount (gen-fermentable))) + "enrich-display-amount is a function to and from common-beer-format.fermentable/fermentable") + (is (s/valid? ::fermentable.format/fermentable + (fermentable.enrich/enrich-fermentable (gen-fermentable))) + "enrich-fermentable is a function to and from common-beer-format.fermentable/fermentable"))) + (testing "Ensure enrichment pattern works against arbitrary fermentable wrappers" + (is (s/valid? ::fermentable.format/fermentable-wrapper + (fermentable.enrich/enrich-fermentable-wrapper (fermentable.data/generate-fermentable-wrapper))) + "enrich-fermentable-wrapper is a function to and from common-beer-format.fermentable/fermentable-wrapper") + (is (s/valid? ::fermentable.format/fermentables + (fermentable.enrich/enrich-fermentables (fermentable.data/generate-fermentables))) + "enrich-fermentables is a function to and from common-beer-format.fermentable/fermentables") + (is (s/valid? ::fermentable.format/fermentables-wrapper + (fermentable.enrich/enrich-fermentables-wrapper (fermentable.data/generate-fermentables-wrapper))) + "enrich-fermentables-wrapper is a function to and from common-beer-format.fermentable/fermentables-wrapper"))) + diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc new file mode 100644 index 0000000..d79559c --- /dev/null +++ b/test/brewtility/enrich/hops_test.cljc @@ -0,0 +1,60 @@ +(ns brewtility.enrich.hops-test + (:require [brewtility.data.hops :as hop.data] + [brewtility.enrich.hops :as hop.enrich] + [clojure.spec.alpha :as s] + [common-beer-format.hops :as hop.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +;; +;; Whole object enrichment tests +;; + +(deftest enrich-hop-tests + (testing "Ensure enrichment pattern functions generate conforming data" + (is (s/valid? ::hop.format/hop + (hop.enrich/enrich-hop hop.data/sample-hop)) + "Enrichment pattern should produce a valid hop object") + (is (s/valid? ::hop.format/hop-wrapper + (hop.enrich/enrich-hop-wrapper hop.data/sample-hop-wrapper)) + "Enrichment pattern should produce a valid hop object") + (is (s/valid? ::hop.format/hops + (hop.enrich/enrich-hops hop.data/sample-hops)) + "Enrichment pattern should produce a valid hop object") + (is (s/valid? ::hop.format/hops-wrapper + (hop.enrich/enrich-hops-wrapper hop.data/sample-hops-wrapper)) + "Enrichment pattern should produce a valid hop object") + (testing "Static data comparison for enrichment pattern functions" + (is (= {:amount 0.0638 + :display-time "60.0 m" + :use "Boil" + :name "Goldings, East Kent" + :time 60.0 + :display-amount "0.141 lb" + :notes "Great all purpose UK hop for ales, stouts, porters" + :alpha 5.0 + :version 1} + (hop.enrich/enrich-hop hop.data/sample-hop)))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary hop" + (letfn [(gen-hop [] (hop.data/generate-hop))] + (is (s/valid? ::hop.format/hop + (hop.enrich/enrich-display-amount (gen-hop))) + "enrich-display-amount is a function to and from common-beer-format.hops/hop") + (is (s/valid? ::hop.format/hop + (hop.enrich/enrich-display-time (gen-hop))) + "enrich-display-time is a function to and from common-beer-format.hops/hop"))) + (testing "Ensure enrichment pattern works against arbitrary hop wrappers" + (is (s/valid? ::hop.format/hop-wrapper + (hop.enrich/enrich-hop-wrapper (hop.data/generate-hop-wrapper))) + "enrich-hop-wrapper is a function to and from common-beer-format.hops/hop-wrapper") + (is (s/valid? ::hop.format/hops + (hop.enrich/enrich-hops (hop.data/generate-hops))) + "enrich-hops is a function to and from common-beer-format.hops/hops") + (is (s/valid? ::hop.format/hops-wrapper + (hop.enrich/enrich-hops-wrapper (hop.data/generate-hops-wrapper))) + "enrich-hops-wrapper is a function to and from common-beer-format.hops/hops-wrapper"))) + From bddea6e71a4b5690567e6a24c971f974cedc7a24 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 21 Aug 2022 20:40:54 -0500 Subject: [PATCH 10/44] Run all tests in a cljs context too --- test/brewtility/enrich/fermentables_test.cljc | 4 ++-- test/brewtility/enrich/hops_test.cljc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index 2ab5bc8..384a4d9 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -134,8 +134,8 @@ (is (= {:amount 0.45 :yield 78.0 :supplier "Gnome Brew" - :color 500.0 - :display-color "500.0°L" + :color 500.1 + :display-color "500.1°L" :name "Black Barley" :moisture 5.0 :type "Grain" diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc index d79559c..227ba9d 100644 --- a/test/brewtility/enrich/hops_test.cljc +++ b/test/brewtility/enrich/hops_test.cljc @@ -27,10 +27,10 @@ "Enrichment pattern should produce a valid hop object") (testing "Static data comparison for enrichment pattern functions" (is (= {:amount 0.0638 - :display-time "60.0 m" + :display-time "60.1 m" :use "Boil" :name "Goldings, East Kent" - :time 60.0 + :time 60.1 :display-amount "0.141 lb" :notes "Great all purpose UK hop for ales, stouts, porters" :alpha 5.0 From 7c4c078f0525f7467606576cfc596ba3aebe7753 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Wed, 7 Sep 2022 12:33:22 -0500 Subject: [PATCH 11/44] Add tests for enricher implementation --- src/brewtility/enrich/fermentables.cljc | 1 + src/brewtility/enrich/hops.cljc | 12 +- src/brewtility/enrich/impl.cljc | 114 ++++++- src/brewtility/enrich/mash.clj | 92 ++++++ src/brewtility/predicates/miscs.cljc | 1 + src/brewtility/predicates/styles.cljc | 1 + src/brewtility/predicates/yeasts.cljc | 13 + src/brewtility/units.cljc | 1 + test/brewtility/data/recipes.cljc | 11 - test/brewtility/enrich/fermentables_test.cljc | 14 +- test/brewtility/enrich/impl_test.cljc | 290 ++++++++++++++++++ test/brewtility/predicates/miscs_test.cljc | 1 + test/brewtility/predicates/styles_test.cljc | 1 + test/brewtility/predicates/yeasts_test.cljc | 1 + test/brewtility/runner.cljs | 1 + 15 files changed, 525 insertions(+), 29 deletions(-) create mode 100644 src/brewtility/enrich/mash.clj create mode 100644 test/brewtility/enrich/impl_test.cljc diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index ca435d7..85b9db3 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -231,6 +231,7 @@ :suffix suffix :allowed-suffixes #{:full :short}})))))) + (defn enrich-display-amount "An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. In the BeerXML spec, the amount of a liquid extract is computed by its weight. diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc index fc3797c..c48f642 100644 --- a/src/brewtility/enrich/hops.cljc +++ b/src/brewtility/enrich/hops.cljc @@ -2,7 +2,7 @@ "Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps" {:added "1.3" :see-also ["brewtility.enrich.equipment" - "brewtility.enrich.hops" + "brewtility.enrich.fermentables" "brewtility.enrich.mash" "brewtility.enrich.miscs" "brewtility.enrich.recipes" @@ -11,6 +11,7 @@ "brewtility.enrich.yeast"]} (:require [brewtility.enrich.impl :as impl])) + (defn enrich-display-amount "An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. @@ -39,9 +40,9 @@ "enrich-hops-wrapper"]} ([hop] (enrich-display-amount hop {})) ([hop {:keys [hop-amount-target-units - hop-amount-precision - hop-amount-suffix] - :as opts}] + hop-amount-precision + hop-amount-suffix] + :as opts}] (let [options (merge opts {:value-key :amount :display-key :display-amount :fine-grain-target-units hop-amount-target-units @@ -49,6 +50,7 @@ :fine-grain-suffix hop-amount-suffix})] (impl/enrich-displayable-weight hop options)))) + (defn enrich-display-time "An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. @@ -86,6 +88,7 @@ :fine-grain-suffix hop-time-suffix})] (impl/enrich-displayable-time hop options)))) + (defn enrich-hop "An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). @@ -123,6 +126,7 @@ (enrich-display-amount opts) (enrich-display-time opts)))) + (defn enrich-hop-wrapper "An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index e4bde32..b9e5c17 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -3,6 +3,7 @@ :added "2.1" :implementation-only true} (:require [brewtility.units.options :as options] + [brewtility.units.temperature :as temperature] [brewtility.units.time :as time] [brewtility.units.volume :as volume] [brewtility.units.weight :as weight])) @@ -14,12 +15,15 @@ options/suffix options/short}) + + + ;; TODO: Pluralize strings (defn ->displayable-volume "Convert a volume then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-weight" "->displayable-time"]} + :see-also ["->displayable-weight" "->displayable-time" "->displayable-temperature"]} ([source-value source-units target-units] (->displayable-volume source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -33,7 +37,7 @@ "Convert a weight then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-volume" "->displayable-time"]} + :see-also ["->displayable-volume" "->displayable-time" "->displayable-temperature"]} ([source-value source-units target-units] (->displayable-weight source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -41,6 +45,7 @@ (weight/convert source-units target-units) (weight/display target-units opts)))) + ;; TODO: Pluralize strings (defn ->displayable-time "Convert a time then render it to a displayable value." @@ -54,6 +59,19 @@ (time/convert source-units target-units) (time/display target-units opts)))) +;; TODO: Pluralize strings +(defn ->displayable-temperature + "Convert a temperature then render it to a displayable value." + {:added "1.3.0" + :no-doc true + :see-also ["->displayable-volume" "->displayable-time"]} + ([source-value source-units target-units] + (->displayable-temperature source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] + (-> source-value + (temperature/convert source-units target-units) + (temperature/display target-units opts)))) + (def ^:private default-volume-by-system {options/imperial options/imperial-gallon options/metric options/litre @@ -67,6 +85,7 @@ options/us-customary options/pound options/international-system options/kilogram}) + (def ^:private ^:const default-time-by-system {:imperial :minute :metric :minute @@ -74,16 +93,30 @@ :si :minute}) +(def ^:private ^:const default-temperature-by-system + {:imperial :fahrenheit + :metric :celsius + :us :fahrenheit + :si :celsius}) + + (defn target-unit-error "A function to accumulate error messages in `error-map` if `target-units` is not a valid unit for `conversion-type`" {:added "1.3.0" :no-doc true :see-also ["systems-of-meaure-error" "precision-error" "suffix-error"]} [error-map conversion-type target-units] - (let [error-msg (format "Invalid unit for %s conversion : %s. Allowed values are: %s" - (name conversion-type) - target-units - volume/measurements)] + (let [allowed-values (case conversion-type + :volume volume/measurements + :weight weight/measurements + :time time/measurements + :temperature temperature/measurements) + error-msg (str "Invalid unit for " + (name conversion-type) + " conversion : `" + target-units + "`. Allowed values are: " + allowed-values)] (assoc error-map :units error-msg))) @@ -209,7 +242,7 @@ (defn enrich-displayable-weight - "A function to enrich a map with a human-readable version of a weight at `value-key`. + "A function to enrich a map with a human-readable version of a weight at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. @@ -241,6 +274,7 @@ (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) + (defn verify-enrich-displayable-time-opts "A function to verify the options map passed to `->displayable-time` This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. @@ -263,6 +297,7 @@ opts (throw (ex-info "Invalid displayable time enrichment options: " errors))))) + (defn enrich-displayable-time "A function to enrich a map with a human-readable version of a time at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -289,9 +324,66 @@ precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-time-opts - {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] (assoc source-data display-key (->displayable-time source-value :minute target-units opts))) source-data)) + + +(defn verify-enrich-displayable-temperature-opts + "A function to verify the options map passed to `->displayable-temperature` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, an Exception is thrown with information on the invalid options." + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-temperature"]} + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? temperature/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :temperature target-units) + (not valid-system?) (systems-of-meaure-error :temperature system-of-measure) + (not valid-precision?) (precision-error :temperature precision) + (not valid-suffix?) (suffix-error :temperature suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable temperature enrichment options: " errors))))) + + +(defn enrich-displayable-temperature + "A function to enrich a map with a human-readable version of a temperature at `value-key`. + If invalid options are passed, the function throws an Exception with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `:fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the temperature to the target units and return the original value with the new value added at `display-key`" + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} + [source-data + {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + :or {system-of-measure :us + suffix :short + precision 3}}] + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-temperature) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (verify-enrich-displayable-temperature-opts + {:target-units target-units + :system-of-measure system-of-measure + :precision precision + :suffix suffix})] + (assoc source-data display-key (->displayable-temperature source-value :minute target-units opts))) + source-data)) diff --git a/src/brewtility/enrich/mash.clj b/src/brewtility/enrich/mash.clj new file mode 100644 index 0000000..3866348 --- /dev/null +++ b/src/brewtility/enrich/mash.clj @@ -0,0 +1,92 @@ +(ns brewtility.enrich.mash + "Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.hops" + "brewtility.enrich.fermentables" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + + +(defn enrich-display-step-temperature + "An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: + - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-display-step-temperature mash-step {})) + ([mash-step {:keys [display-temperature-target-units + display-temperature-precision + display-temperature-suffix] + :as opts}] + (let [options (merge opts {:value-key :step-temp + :display-key :display-step-temp + :fine-grain-target-units display-temperature-target-units + :fine-grain-precision display-temperature-precision + :fine-grain-suffix display-temperature-suffix})] + (impl/enrich-displayable-temperature mash-step options)))) + + +(defn enrich-display-infuse-amount + "An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-display-infuse-amount mash-step {})) + ([mash-step {:keys [display-infuse-amount-target-units + display-infuse-amount-precision + display-infuse-amount-suffix] + :as opts}] + (let [options (merge opts {:value-key :infuse-amount + :display-key :display-infuse-amt + :fine-grain-target-units display-infuse-amount-target-units + :fine-grain-precision display-infuse-amount-precision + :fine-grain-suffix display-infuse-amount-suffix})] + (impl/enrich-displayable-volume mash-step options)))) diff --git a/src/brewtility/predicates/miscs.cljc b/src/brewtility/predicates/miscs.cljc index 4a50b0f..4f38ac6 100644 --- a/src/brewtility/predicates/miscs.cljc +++ b/src/brewtility/predicates/miscs.cljc @@ -32,6 +32,7 @@ (spoon.string/same-text? "spice" misc-type opts)))) + (defn fining? "A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/predicates/styles.cljc b/src/brewtility/predicates/styles.cljc index fcb2d4d..a4347f1 100644 --- a/src/brewtility/predicates/styles.cljc +++ b/src/brewtility/predicates/styles.cljc @@ -32,6 +32,7 @@ (spoon.string/same-text? "lager" style-type opts)))) + (defn ale? "A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/predicates/yeasts.cljc b/src/brewtility/predicates/yeasts.cljc index 5b92adf..465766f 100644 --- a/src/brewtility/predicates/yeasts.cljc +++ b/src/brewtility/predicates/yeasts.cljc @@ -14,6 +14,7 @@ [com.wallbrew.spoon.string :as spoon.string])) + ;; ;; :type functions ;; @@ -36,6 +37,7 @@ (spoon.string/same-text? "ale" yeast-type opts)))) + (defn lager? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. An option map can be passed to this function as an optional second parameter. @@ -54,6 +56,7 @@ (spoon.string/same-text? "lager" yeast-type opts)))) + (defn wheat? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. An option map can be passed to this function as an optional second parameter. @@ -72,6 +75,7 @@ (spoon.string/same-text? "wheat" yeast-type opts)))) + (defn wine? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. An option map can be passed to this function as an optional second parameter. @@ -90,6 +94,7 @@ (spoon.string/same-text? "wine" yeast-type opts)))) + (defn champagne? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. An option map can be passed to this function as an optional second parameter. @@ -108,6 +113,7 @@ (spoon.string/same-text? "champagne" yeast-type opts)))) + ;; ;; :form functions ;; @@ -129,6 +135,7 @@ (spoon.string/same-text? "liquid" yeast-form opts)))) + (defn dry? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. An option map can be passed to this function as an optional second parameter. @@ -146,6 +153,7 @@ (spoon.string/same-text? "dry" yeast-form opts)))) + (defn slant? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. Typically, this is a solid growth of yeast cells in a test tube. @@ -164,6 +172,7 @@ (spoon.string/same-text? "slant" yeast-form opts)))) + (defn culture? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. An option map can be passed to this function as an optional second parameter. @@ -181,6 +190,7 @@ (spoon.string/same-text? "culture" yeast-form opts)))) + ;; ;; :flocculation functions ;; @@ -202,6 +212,7 @@ (spoon.string/same-text? "low" yeast-flocculation opts)))) + (defn medium-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. An option map can be passed to this function as an optional second parameter. @@ -219,6 +230,7 @@ (spoon.string/same-text? "medium" yeast-flocculation opts)))) + (defn high-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. An option map can be passed to this function as an optional second parameter. @@ -236,6 +248,7 @@ (spoon.string/same-text? "high" yeast-flocculation opts)))) + (defn very-high-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index f968f6d..6f851b1 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -28,6 +28,7 @@ [brewtility.units.volume :as volume] [brewtility.units.weight :as weight])) + ;; ;; Weight ;; diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index e213cd4..4844b90 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -22,17 +22,6 @@ {:added "1.3" :no-doc true} [] - (-> recipes.format/ibu-method-types - vec - rand-nth - b-str/->sporadic-case)) - - -(defn random-ibu-method - "Return a random valid hop type." - {:added "1.4" - :no-doc true} - [] (-> recipes.format/ibu-method-types vec rand-nth diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index 384a4d9..c662e5b 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -6,6 +6,7 @@ #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + (deftest enrich-add-after-boil-test (testing "add-after-boil can be derived from a fermentable" (is (boolean? (:add-after-boil (fermentable.enrich/enrich-add-after-boil (fermentable.data/generate-fermentable)))) @@ -18,9 +19,9 @@ :add-after-boil)) "enrich-add-after-boil adds true when the add-after-boil key is truthy") (is (false? (-> fermentable.data/sample-fermentable - (assoc :add-after-boil false) - fermentable.enrich/enrich-add-after-boil - :add-after-boil)) + (assoc :add-after-boil false) + fermentable.enrich/enrich-add-after-boil + :add-after-boil)) "enrich-add-after-boil adds false when the add-after-boil key is falsy") (is (false? (-> fermentable.data/sample-fermentable (dissoc :add-after-boil) @@ -28,6 +29,7 @@ :add-after-boil)) "enrich-add-after-boil adds false when the add-after-boil key is nil"))) + (deftest enrich-coarse-fine-diff-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") @@ -42,6 +44,7 @@ (is (nil? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-dry-extract)))) (is (nil? (:coarse-fine-diff (fermentable.enrich/enrich-coarse-fine-diff sample-sugar))))))) + (deftest enrich-moisture-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") @@ -56,6 +59,7 @@ (is (nil? (:moisture (fermentable.enrich/enrich-moisture sample-dry-extract)))) (is (nil? (:moisture (fermentable.enrich/enrich-moisture sample-sugar))))))) + (deftest enrich-diastatic-power-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") @@ -70,6 +74,7 @@ (is (nil? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-dry-extract)))) (is (nil? (:diastatic-power (fermentable.enrich/enrich-diastatic-power sample-sugar))))))) + (deftest enrich-protein-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") @@ -84,6 +89,7 @@ (is (nil? (:protein (fermentable.enrich/enrich-protein sample-dry-extract)))) (is (nil? (:protein (fermentable.enrich/enrich-protein sample-sugar))))))) + (deftest enrich-recommend-mash-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain") sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct") @@ -98,6 +104,7 @@ (is (false? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-dry-extract)))) (is (false? (:recommend-mash (fermentable.enrich/enrich-recommend-mash sample-sugar))))))) + (deftest enrich-ibu-gal-per-lb-test (let [sample-grain (assoc fermentable.data/sample-fermentable :type "grain" :ibu-gal-per-lb 0.123) sample-adjunct (assoc fermentable.data/sample-fermentable :type "adjunct" :ibu-gal-per-lb 0.123) @@ -112,6 +119,7 @@ (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-dry-extract)))) (is (nil? (:ibu-gal-per-lb (fermentable.enrich/enrich-ibu-gallons-per-pound sample-sugar))))))) + ;; ;; Whole object enrichment tests ;; diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc new file mode 100644 index 0000000..1ae5322 --- /dev/null +++ b/test/brewtility/enrich/impl_test.cljc @@ -0,0 +1,290 @@ +(ns brewtility.enrich.impl-test + (:require [brewtility.enrich.impl :as sut] + [clojure.string :as str] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(deftest ->displayable-volume-test + (testing "Ensure ->displayable-volume supports its full suite of options" + (is (= "5.678 l" + (sut/->displayable-volume 1.5 :american-gallon :liter) + (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 3 + :suffix :short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "5.7 l" + (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 1 + :suffix :short})) + "Conversion may override the default precision") + (is (= "5.678 liter" + (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 3 + :suffix :full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-weight-test + (testing "Ensure ->displayable-weight supports its full suite of options" + (is (= "0.053 oz" + (sut/->displayable-weight 1.5 :gram :ounce) + (sut/->displayable-weight 1.5 :gram :ounce {:precision 3 + :suffix :short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "0.1 oz" + (sut/->displayable-weight 1.5 :gram :ounce {:precision 1 + :suffix :short})) + "Conversion may override the default precision") + (is (= "0.053 ounce" + (sut/->displayable-weight 1.5 :gram :ounce {:precision 3 + :suffix :full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-time-test + (testing "Ensure ->displayable-time supports its full suite of options" + (is (= "0.76 m" + (sut/->displayable-time 45.6 :second :minute) + (sut/->displayable-time 45.6 :second :minute {:precision 3 + :suffix :short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "0.8 m" + (sut/->displayable-time 45.6 :second :minute {:precision 1 + :suffix :short})) + "Conversion may override the default precision") + (is (= "0.76 minute" + (sut/->displayable-time 45.6 :second :minute {:precision 3 + :suffix :full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-temperature-test + (testing "Ensure ->displayable-temperature supports its full suite of options" + (is (= "318.75 k" + (sut/->displayable-temperature 45.6 :c :k) + (sut/->displayable-temperature 45.6 :c :k {:precision 3 + :suffix :short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "318.8 k" + (sut/->displayable-temperature 45.6 :c :k {:precision 1 + :suffix :short})) + "Conversion may override the default precision") + (is (= "318.75 kelvin" + (sut/->displayable-temperature 45.6 :c :k {:precision 3 + :suffix :full})) + "Conversion may override the default suffix"))) + + +(deftest target-unit-error-test + (testing "Ensure target-unit-error sets an appropriate error for volume" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map :volume :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "volume") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "teaspoon") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for weight" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map :weight :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "weight") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "pound") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for time" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map :time :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "time") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "minute") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for temperature" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map :temperature :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "temperature") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "celsius") + "The valid units are included in the error message")))) + + +(deftest systems-of-meaure-error-test + (testing "Ensure systems-of-meaure-error sets an appropriate error" + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map :volume :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :system-of-measure) + "The new error is recorded") + (is (str/includes? (:system-of-measure new-error-map) "volume") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (:system-of-measure new-error-map) "metric") + "The valid values are included in the error message")))) + + +(deftest precision-error-test + (testing "Ensure precision-error sets an appropriate error" + (let [error-map {:some "error"} + new-error-map (sut/precision-error error-map :volume 10)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :precision) + "The new error is recorded") + (is (str/includes? (:precision new-error-map) "volume") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:precision new-error-map) "10") + "The invalid system of measure is included in the error message")))) + + +(deftest suffix-error-test + (testing "Ensure suffix-error sets an appropriate error" + (let [error-map {:some "error"} + new-error-map (sut/suffix-error error-map :volume :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :suffix) + "The new error is recorded") + (is (str/includes? (:suffix new-error-map) "volume") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:suffix new-error-map) "fake") + "The invalid suffix type is included in the error message") + (is (str/includes? (:suffix new-error-map) "full") + "The valid values are included in the error message")))) + + +(deftest verify-enrich-displayable-volume-opts-test + (let [valid-opts {:target-units :teaspoon + :system-of-measure :metric + :precision 2 + :suffix :full} + error-regex #"Invalid displayable volume enrichment options"] + (testing "Ensure verify-enrich-displayable-volume-opts returns valid opts" + (is (= valid-opts (sut/verify-enrich-displayable-volume-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake)))))))) + + +(deftest verify-enrich-displayable-weight-opts-test + (let [valid-opts {:target-units :pound + :system-of-measure :metric + :precision 2 + :suffix :full} + error-regex #"Invalid displayable weight enrichment options"] + (testing "Ensure verify-enrich-displayable-weight-opts returns valid opts" + (is (= valid-opts (sut/verify-enrich-displayable-weight-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake)))))))) + + +(deftest verify-enrich-displayable-time-opts-test + (let [valid-opts {:target-units :minute + :system-of-measure :metric + :precision 2 + :suffix :full} + error-regex #"Invalid displayable time enrichment options"] + (testing "Ensure verify-enrich-displayable-time-opts returns valid opts" + (is (= valid-opts (sut/verify-enrich-displayable-time-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :suffix :fake)))))))) + + +(deftest verify-enrich-displayable-temperature-opts-test + (let [valid-opts {:target-units :c + :system-of-measure :metric + :precision 2 + :suffix :full} + error-regex #"Invalid displayable temperature enrichment options"] + (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts" + (is (= valid-opts (sut/verify-enrich-displayable-temperature-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake)))))))) diff --git a/test/brewtility/predicates/miscs_test.cljc b/test/brewtility/predicates/miscs_test.cljc index bb1bd63..d9b591d 100644 --- a/test/brewtility/predicates/miscs_test.cljc +++ b/test/brewtility/predicates/miscs_test.cljc @@ -6,6 +6,7 @@ [common-beer-format.miscs :as cbf-miscs])) + ;; ;; :type function tests ;; diff --git a/test/brewtility/predicates/styles_test.cljc b/test/brewtility/predicates/styles_test.cljc index 38baf37..269fb70 100644 --- a/test/brewtility/predicates/styles_test.cljc +++ b/test/brewtility/predicates/styles_test.cljc @@ -6,6 +6,7 @@ [common-beer-format.styles :as cbf-styles])) + ;; ;; :type function tests ;; diff --git a/test/brewtility/predicates/yeasts_test.cljc b/test/brewtility/predicates/yeasts_test.cljc index c7b4a83..d0d77d3 100644 --- a/test/brewtility/predicates/yeasts_test.cljc +++ b/test/brewtility/predicates/yeasts_test.cljc @@ -6,6 +6,7 @@ [common-beer-format.yeasts :as cbf-yeasts])) + ;; ;; :type function tests ;; diff --git a/test/brewtility/runner.cljs b/test/brewtility/runner.cljs index d4e6855..8b932bc 100644 --- a/test/brewtility/runner.cljs +++ b/test/brewtility/runner.cljs @@ -36,6 +36,7 @@ [doo.runner :refer-macros [doo-tests]])) +;; This should match the :require above (aside from doo itself) (doo-tests 'brewtility.calculations-test 'brewtility.data.equipment 'brewtility.data.fermentables From f791b5efb8c6e2f2087f8bd2febb5eda638f91da Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Sep 2022 17:50:09 -0500 Subject: [PATCH 12/44] Add mash enrichers --- src/brewtility/calculations.cljc | 5 +- src/brewtility/enrich/impl.cljc | 2 +- src/brewtility/enrich/mash.clj | 92 ----- src/brewtility/enrich/mash.cljc | 515 ++++++++++++++++++++++++++ test/brewtility/enrich/mash_test.cljc | 109 ++++++ 5 files changed, 629 insertions(+), 94 deletions(-) delete mode 100644 src/brewtility/enrich/mash.clj create mode 100644 src/brewtility/enrich/mash.cljc create mode 100644 test/brewtility/enrich/mash_test.cljc diff --git a/src/brewtility/calculations.cljc b/src/brewtility/calculations.cljc index 6eb4575..7b63cf8 100644 --- a/src/brewtility/calculations.cljc +++ b/src/brewtility/calculations.cljc @@ -207,7 +207,10 @@ (defn calculate-equipment-boil-volume "Given a `common-beer-format` conforming `equipment`, calculate the volume of the wort at the start of the boil. If insufficient data is provided, this function will throw an exception." - {:added "1.5"} + {:added "1.5" + :see-also ["brewtility.enrich.equipment/enrich-calculated-boil-size" + "brewtility.enrich.equipment/enrich-equipment" + "brewtility.enrich.equipment/enrich-equipment-wrapper"]} [{:keys [batch-size top-up-water trub-chiller-loss boil-time evap-rate]}] (if (every? number? [batch-size top-up-water trub-chiller-loss boil-time evap-rate]) (let [starting-water (- batch-size top-up-water trub-chiller-loss) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index b9e5c17..4070da9 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -385,5 +385,5 @@ :system-of-measure system-of-measure :precision precision :suffix suffix})] - (assoc source-data display-key (->displayable-temperature source-value :minute target-units opts))) + (assoc source-data display-key (->displayable-temperature source-value :celsius target-units opts))) source-data)) diff --git a/src/brewtility/enrich/mash.clj b/src/brewtility/enrich/mash.clj deleted file mode 100644 index 3866348..0000000 --- a/src/brewtility/enrich/mash.clj +++ /dev/null @@ -1,92 +0,0 @@ -(ns brewtility.enrich.mash - "Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps" - {:added "1.3" - :see-also ["brewtility.enrich.equipment" - "brewtility.enrich.hops" - "brewtility.enrich.fermentables" - "brewtility.enrich.miscs" - "brewtility.enrich.recipes" - "brewtility.enrich.styles" - "brewtility.enrich.waters" - "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) - - -(defn enrich-display-step-temperature - "An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. - - To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: - - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" - :see-also ["brewtility.string/same?" - "enrich-mash-step" - "enrich-mash-step-wrapper" - "enrich-mash-steps" - "enrich-mash" - "enrich-mash-wrapper"]} - ([mash-step] (enrich-display-step-temperature mash-step {})) - ([mash-step {:keys [display-temperature-target-units - display-temperature-precision - display-temperature-suffix] - :as opts}] - (let [options (merge opts {:value-key :step-temp - :display-key :display-step-temp - :fine-grain-target-units display-temperature-target-units - :fine-grain-precision display-temperature-precision - :fine-grain-suffix display-temperature-suffix})] - (impl/enrich-displayable-temperature mash-step options)))) - - -(defn enrich-display-infuse-amount - "An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. - - To support fine-grained selections within the context of `enrich-hop` and `enrich-hop-wrapper`, this function also supports the following keys: - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" - :see-also ["brewtility.string/same?" - "enrich-mash-step" - "enrich-mash-step-wrapper" - "enrich-mash-steps" - "enrich-mash" - "enrich-mash-wrapper"]} - ([mash-step] (enrich-display-infuse-amount mash-step {})) - ([mash-step {:keys [display-infuse-amount-target-units - display-infuse-amount-precision - display-infuse-amount-suffix] - :as opts}] - (let [options (merge opts {:value-key :infuse-amount - :display-key :display-infuse-amt - :fine-grain-target-units display-infuse-amount-target-units - :fine-grain-precision display-infuse-amount-precision - :fine-grain-suffix display-infuse-amount-suffix})] - (impl/enrich-displayable-volume mash-step options)))) diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc new file mode 100644 index 0000000..8e651a5 --- /dev/null +++ b/src/brewtility/enrich/mash.cljc @@ -0,0 +1,515 @@ +(ns brewtility.enrich.mash + "Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.mash-steps" + "brewtility.enrich.fermentables" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + + +(defn enrich-display-step-temperature + "An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.enrich.impl/->displayable-temperature" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash-steps-wrapper" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-display-step-temperature mash-step {})) + ([mash-step {:keys [display-temperature-target-units + display-temperature-precision + display-temperature-suffix] + :as opts}] + (let [options (merge opts {:value-key :step-temp + :display-key :display-step-temp + :fine-grain-target-units display-temperature-target-units + :fine-grain-precision display-temperature-precision + :fine-grain-suffix display-temperature-suffix})] + (impl/enrich-displayable-temperature mash-step options)))) + + +(defn enrich-display-infuse-amount + "An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.string/same?" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash-steps-wrapper" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-display-infuse-amount mash-step {})) + ([mash-step {:keys [display-infuse-amount-target-units + display-infuse-amount-precision + display-infuse-amount-suffix] + :as opts}] + (let [options (merge opts {:value-key :infuse-amount + :display-key :display-infuse-amt + :fine-grain-target-units display-infuse-amount-target-units + :fine-grain-precision display-infuse-amount-precision + :fine-grain-suffix display-infuse-amount-suffix})] + (impl/enrich-displayable-volume mash-step options)))) + + +(defn enrich-mash-step + "An enricher pattern function to derive as many values from an [mash-step record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash-steps-wrapper" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-mash-step mash-step {})) + ([mash-step opts] + (-> mash-step + (enrich-display-step-temperature opts) + (enrich-display-infuse-amount opts)))) + + +(defn enrich-mash-step-wrapper + "An enricher pattern function to derive as many values from an [mash-step wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-mash-step" + "enrich-mash-steps" + "enrich-mash-steps-wrapper" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-step] (enrich-mash-step-wrapper mash-step {})) + ([mash-step opts] + (update mash-step :mash-step enrich-mash-step opts))) + + +(defn enrich-mash-steps + "An enricher pattern function to derive as many values from a collection of [mash-step wrapper records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps-wrapper" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash-steps] (enrich-mash-steps mash-steps {})) + ([mash-steps opts] + (map #(enrich-mash-step-wrapper % opts) mash-steps))) + + +(defn enrich-mash-steps-wrapper + "An enricher pattern function to derive as many values from a collection of [mash-steps wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-mash-step" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-mash-steps-wrapper mash {})) + ([mash opts] + (update mash :mash-steps enrich-mash-steps opts))) + + +(defn enrich-display-grain-temperature + "An enricher pattern function to render a human-readable temperature of the grain temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.enrich.impl/->displayable-temperature" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-display-grain-temperature mash {})) + ([mash {:keys [display-grain-temperature-target-units + display-grain-temperature-precision + display-grain-temperature-suffix] + :as opts}] + (let [options (merge opts {:value-key :grain-temp + :display-key :display-grain-temp + :fine-grain-target-units display-grain-temperature-target-units + :fine-grain-precision display-grain-temperature-precision + :fine-grain-suffix display-grain-temperature-suffix})] + (impl/enrich-displayable-temperature mash options)))) + + +(defn enrich-display-tun-temperature + "An enricher pattern function to render a human-readable temperature of the tun temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-tuned selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.enrich.impl/->displayable-temperature" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-display-tun-temperature mash {})) + ([mash {:keys [display-tun-temperature-target-units + display-tun-temperature-precision + display-tun-temperature-suffix] + :as opts}] + (let [options (merge opts {:value-key :tun-temp + :display-key :display-tun-temp + :fine-grain-target-units display-tun-temperature-target-units + :fine-grain-precision display-tun-temperature-precision + :fine-grain-suffix display-tun-temperature-suffix})] + (impl/enrich-displayable-temperature mash options)))) + + +(defn enrich-display-sparge-temperature + "An enricher pattern function to render a human-readable temperature of the sparge temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-spargeed selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.enrich.impl/->displayable-temperature" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-display-sparge-temperature mash {})) + ([mash {:keys [display-sparge-temperature-target-units + display-sparge-temperature-precision + display-sparge-temperature-suffix] + :as opts}] + (let [options (merge opts {:value-key :sparge-temp + :display-key :display-sparge-temp + :fine-grain-target-units display-sparge-temperature-target-units + :fine-grain-precision display-sparge-temperature-precision + :fine-grain-suffix display-sparge-temperature-suffix})] + (impl/enrich-displayable-temperature mash options)))) + + +(defn enrich-display-tun-weight + "An enricher pattern function to render a human-readable weight of the tun weight during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-tuned selections within the context of `enrich-mash-step` and `enrich-mash-step-wrapper`, this function also supports the following keys: + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["brewtility.enrich.impl/->displayable-weight" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-display-tun-weight mash {})) + ([mash {:keys [display-tun-weight-target-units + display-tun-weight-precision + display-tun-weight-suffix] + :as opts}] + (let [options (merge opts {:value-key :tun-weight + :display-key :display-tun-weight + :fine-grain-target-units display-tun-weight-target-units + :fine-grain-precision display-tun-weight-precision + :fine-grain-suffix display-tun-weight-suffix})] + (impl/enrich-displayable-weight mash options)))) + + +(defn enrich-mash + "An enricher pattern function to derive as many values from an [mash record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-grain-temperature]] + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-tun-temperature]] + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-sparge-temperature]] + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` + - [[enrich-display-tun-weight]] + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-display-grain-temperature" + "enrich-display-tun-temperature" + "enrich-display-sparge-temperature" + "enrich-display-tun-weight" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-mash mash {})) + ([mash opts] + (-> mash + (enrich-mash-steps-wrapper opts) + (enrich-display-grain-temperature opts) + (enrich-display-tun-temperature opts) + (enrich-display-sparge-temperature opts) + (enrich-display-tun-weight opts)))) + + +(defn enrich-mash-wrapper + "An enricher pattern function to derive as many values from an [mash wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-grain-temperature]] + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-tun-temperature]] + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-sparge-temperature]] + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` + - [[enrich-display-tun-weight]] + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-step-temperature" + "enrich-display-infuse-amount" + "enrich-display-grain-temperature" + "enrich-display-tun-temperature" + "enrich-display-sparge-temperature" + "enrich-display-tun-weight" + "enrich-mash-step-wrapper" + "enrich-mash-steps" + "enrich-mash" + "enrich-mash-wrapper"]} + ([mash] (enrich-mash-wrapper mash {})) + ([mash opts] + (update mash :mash enrich-mash opts))) diff --git a/test/brewtility/enrich/mash_test.cljc b/test/brewtility/enrich/mash_test.cljc new file mode 100644 index 0000000..3b1b735 --- /dev/null +++ b/test/brewtility/enrich/mash_test.cljc @@ -0,0 +1,109 @@ +(ns brewtility.enrich.mash-test + (:require [brewtility.data.mash :as mash.data] + [brewtility.enrich.mash :as mash.enrich] + [clojure.spec.alpha :as s] + [common-beer-format.mash :as mash.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(deftest static-enrichment-tests + (testing "Ensure enrichment pattern works against the static test mash steps" + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-display-step-temperature mash.data/sample-mash-step)) + "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-display-infuse-amount mash.data/sample-mash-step)) + "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-mash-step mash.data/sample-mash-step)) + "enrich-mash-step is a function to and from common-beer-format.mash/mash")) + (testing "Ensure enrichment pattern works against static test mash step wrappers" + (is (s/valid? ::mash.format/mash-step-wrapper + (mash.enrich/enrich-mash-step-wrapper mash.data/sample-mash-step-wrapper)) + "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) + (testing "Ensure enrichment pattern works against static test mash steps" + (is (s/valid? ::mash.format/mash-steps + (mash.enrich/enrich-mash-steps mash.data/sample-mash-steps)) + "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) + (testing "Ensure enrichment pattern works against static test mash steps wrapper" + (is (s/valid? ::mash.format/mash-steps + (:mash-steps (mash.enrich/enrich-mash-steps-wrapper mash.data/sample-mash-steps-wrapper))) + "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) + (testing "Ensure enrichment pattern works against static test mash" + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-grain-temperature mash.data/sample-mash)) + "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-tun-temperature mash.data/sample-mash)) + "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-sparge-temperature mash.data/sample-mash)) + "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-tun-weight mash.data/sample-mash)) + "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-mash mash.data/sample-mash)) + "enrich-mash is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-wrapper + (mash.enrich/enrich-mash-wrapper mash.data/sample-mash-wrapper)) + "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper")) + (testing "Static data comparison for enrichment pattern functions" + (is (= {:name "Single Step Infusion, 68 C" + :version 1 + :grain-temp 22.0 + :mash-steps [{:mash-step {:name "Conversion Step, 68C" + :version 1 + :type "Infusion" + :step-temp 68.0 + :step-time 60.0 + :infuse-amount 10.0 + :display-step-temp "154.4 f" + :display-infuse-amt "2.642 gal"}}] + :display-grain-temp "71.6 f"} + (mash.enrich/enrich-mash mash.data/sample-mash))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary mash steps" + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-display-step-temperature (mash.data/generate-mash-step))) + "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-display-infuse-amount (mash.data/generate-mash-step))) + "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-step + (mash.enrich/enrich-mash-step (mash.data/generate-mash-step))) + "enrich-mash-step is a function to and from common-beer-format.mash/mash")) + (testing "Ensure enrichment pattern works against arbitrary mash step wrappers" + (is (s/valid? ::mash.format/mash-step-wrapper + (mash.enrich/enrich-mash-step-wrapper (mash.data/generate-mash-step-wrapper))) + "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) + (testing "Ensure enrichment pattern works against arbitrary mash steps" + (is (s/valid? ::mash.format/mash-steps + (mash.enrich/enrich-mash-steps (mash.data/generate-mash-steps))) + "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) + (testing "Ensure enrichment pattern works against arbitrary mash steps wrapper" + (is (s/valid? ::mash.format/mash-steps + (:mash-steps (mash.enrich/enrich-mash-steps-wrapper (mash.data/generate-mash-steps-wrapper)))) + "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) + (testing "Ensure enrichment pattern works against arbitrary mash" + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-grain-temperature (mash.data/generate-mash))) + "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-tun-temperature (mash.data/generate-mash))) + "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-sparge-temperature (mash.data/generate-mash))) + "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-display-tun-weight (mash.data/generate-mash))) + "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash + (mash.enrich/enrich-mash (mash.data/generate-mash))) + "enrich-mash is a function to and from common-beer-format.mash/mash") + (is (s/valid? ::mash.format/mash-wrapper + (mash.enrich/enrich-mash-wrapper (mash.data/generate-mash-wrapper))) + "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper"))) From db7bcea3eb59276059116f3b919d95e310d3e8b4 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Fri, 23 Sep 2022 14:47:53 -0500 Subject: [PATCH 13/44] Misc enrichers --- .github/workflows/clojure.yml | 2 +- .github/workflows/format.yml | 15 + API.md | 4102 +++++++++++++++++++++++ README.md | 6 + doc/cljdoc.edn | 2 + doc/enricher-pattern.md | 3 +- doc/symbolic-keywords.md | 51 + src/brewtility/enrich/fermentables.cljc | 2 +- src/brewtility/enrich/miscs.cljc | 261 ++ src/brewtility/static.cljc | 3 + src/brewtility/string.cljc | 30 +- test/brewtility/string_test.cljc | 3 + 12 files changed, 4474 insertions(+), 6 deletions(-) create mode 100644 API.md create mode 100644 doc/symbolic-keywords.md create mode 100644 src/brewtility/enrich/miscs.cljc create mode 100644 src/brewtility/static.cljc diff --git a/.github/workflows/clojure.yml b/.github/workflows/clojure.yml index 90a8408..450a44a 100644 --- a/.github/workflows/clojure.yml +++ b/.github/workflows/clojure.yml @@ -14,7 +14,7 @@ jobs: - name: Cache maven dependencies uses: actions/cache@v4 env: - cache-name: cache-maven + cache-name: cache-maven with: path: ~/.m2 save-always: true diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index b36b14b..ca1901e 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,6 +13,18 @@ jobs: ref: ${{ github.head_ref }} token: ${{ secrets.WALL_BREW_BOT_PAT }} + - name: Cache maven dependencies + uses: actions/cache@v3 + env: + cache-name: cache-maven + with: + path: | + ~/.m2/repository + ~/.gitlibs + key: ${{ runner.os }}-clj-${{ hashFiles('**/project.clj') }} + restore-keys: | + ${{ runner.os }}-clj + - name: Install cljstyle uses: just-sultanov/setup-cljstyle@v1 with: @@ -22,6 +34,9 @@ jobs: run: | cljstyle fix --report --report-timing --verbose + - name: Rebuild pom.xml + run: lein pom + - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5.0.0 with: diff --git a/API.md b/API.md new file mode 100644 index 0000000..8a14a3f --- /dev/null +++ b/API.md @@ -0,0 +1,4102 @@ +# Table of contents +- [`brewtility.calculations`](#brewtility.calculations) - Namespace for handling recipe calculations. + - [`calculate-alpha-acid-units`](#brewtility.calculations/calculate-alpha-acid-units) - Calculate the maximum amount of alpha acid released by weight ounce of a hop at percent alpha acid. + - [`calculate-ebc-color`](#brewtility.calculations/calculate-ebc-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the EBC color for a recipe. + - [`calculate-equipment-boil-volume`](#brewtility.calculations/calculate-equipment-boil-volume) - Given a common-beer-format conforming equipment, calculate the volume of the wort at the start of the boil. + - [`calculate-hop-utilization`](#brewtility.calculations/calculate-hop-utilization) - Calculate the percentage of alpha acid that a hop could release over boil-duration in a wort at a specific gravity Based on: http://howtobrew.com/book/section-1/hops/hop-bittering-calculations. + - [`calculate-ibu-per-hop`](#brewtility.calculations/calculate-ibu-per-hop) - Given a common-beer-format conforming hop, batch-size, and potential-gravity, calculate the amount of IBUs generated. + - [`calculate-lovibond-color`](#brewtility.calculations/calculate-lovibond-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the color in degrees Lovibond for a recipe. + - [`calculate-malt-color-units`](#brewtility.calculations/calculate-malt-color-units) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the overall Malt Color Units for a recipe. + - [`calculate-potential-abv`](#brewtility.calculations/calculate-potential-abv) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, estimate the ABV. + - [`calculate-potential-final-gravity`](#brewtility.calculations/calculate-potential-final-gravity) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, estimate the Final Gravity. + - [`calculate-potential-gravity`](#brewtility.calculations/calculate-potential-gravity) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, calculate the potential original gravity. + - [`calculate-recipe-ibus`](#brewtility.calculations/calculate-recipe-ibus) - Given a collection of common-beer-format conforming hops, batch-size, and potential-gravity calculate the amount of IBUs generated. + - [`calculate-rgba-color`](#brewtility.calculations/calculate-rgba-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the RGBA color for a recipe. + - [`calculate-srm-color`](#brewtility.calculations/calculate-srm-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the SRM color for a recipe. + - [`default-attenuation`](#brewtility.calculations/default-attenuation) - A constant backup attenuation for calculations. + - [`gravity->abv-multiplier`](#brewtility.calculations/gravity->abv-multiplier) - The constanct factor used to calculate ABV from potential gravity. + - [`gravity-points->potential-gravity`](#brewtility.calculations/gravity-points->potential-gravity) - Given the gravity-points of a recipe, and the volume of the batch, calculate the potential gravity. + - [`potential-gravity->gravity-points`](#brewtility.calculations/potential-gravity->gravity-points) - Given the potential-gravity of a fermentable, and the weight of the fermentable, calculate gravity points. +- [`brewtility.color`](#brewtility.color) - Namespace for calculating beer colors. + - [`color-system->display-name`](#brewtility.color/color-system->display-name) - A map from color system names to their full and short unit names. + - [`color-systems`](#brewtility.color/color-systems) - The color systems available across brewtility. + - [`ebc->lovibond`](#brewtility.color/ebc->lovibond) - Convert the color described in 'ebc` to the equivalent degrees Lovibond. + - [`ebc->rgba`](#brewtility.color/ebc->rgba) - Given ebc-number, return the closest, bounded applicable RGBA color string. + - [`ebc->srm`](#brewtility.color/ebc->srm) - Convert the color described by the ebc to the equivalent SRM color. + - [`lovibond->ebc`](#brewtility.color/lovibond->ebc) - Convert the color described in degrees 'lovibond` to the equivalent EBC color. + - [`lovibond->rgba`](#brewtility.color/lovibond->rgba) - Given lovibond-number, return the closest, bounded applicable RGBA color string. + - [`lovibond->srm`](#brewtility.color/lovibond->srm) - Convert the color described in degrees lovibond to the equivalent SRM color. + - [`srm-1`](#brewtility.color/srm-1) - An SRM of 1 mapped to an RGBa color code. + - [`srm-10`](#brewtility.color/srm-10) - An SRM of 10 mapped to an RGBa color code. + - [`srm-11`](#brewtility.color/srm-11) - An SRM of 11 mapped to an RGBa color code. + - [`srm-12`](#brewtility.color/srm-12) - An SRM of 12 mapped to an RGBa color code. + - [`srm-13`](#brewtility.color/srm-13) - An SRM of 13 mapped to an RGBa color code. + - [`srm-14`](#brewtility.color/srm-14) - An SRM of 14 mapped to an RGBa color code. + - [`srm-15`](#brewtility.color/srm-15) - An SRM of 15 mapped to an RGBa color code. + - [`srm-16`](#brewtility.color/srm-16) - An SRM of 16 mapped to an RGBa color code. + - [`srm-17`](#brewtility.color/srm-17) - An SRM of 17 mapped to an RGBa color code. + - [`srm-18`](#brewtility.color/srm-18) - An SRM of 18 mapped to an RGBa color code. + - [`srm-19`](#brewtility.color/srm-19) - An SRM of 19 mapped to an RGBa color code. + - [`srm-2`](#brewtility.color/srm-2) - An SRM of 2 mapped to an RGBa color code. + - [`srm-20`](#brewtility.color/srm-20) - An SRM of 20 mapped to an RGBa color code. + - [`srm-21`](#brewtility.color/srm-21) - An SRM of 21 mapped to an RGBa color code. + - [`srm-22`](#brewtility.color/srm-22) - An SRM of 22 mapped to an RGBa color code. + - [`srm-23`](#brewtility.color/srm-23) - An SRM of 23 mapped to an RGBa color code. + - [`srm-24`](#brewtility.color/srm-24) - An SRM of 24 mapped to an RGBa color code. + - [`srm-25`](#brewtility.color/srm-25) - An SRM of 25 mapped to an RGBa color code. + - [`srm-26`](#brewtility.color/srm-26) - An SRM of 26 mapped to an RGBa color code. + - [`srm-27`](#brewtility.color/srm-27) - An SRM of 27 mapped to an RGBa color code. + - [`srm-28`](#brewtility.color/srm-28) - An SRM of 28 mapped to an RGBa color code. + - [`srm-29`](#brewtility.color/srm-29) - An SRM of 29 mapped to an RGBa color code. + - [`srm-3`](#brewtility.color/srm-3) - An SRM of 3 mapped to an RGBa color code. + - [`srm-30`](#brewtility.color/srm-30) - An SRM of 30 mapped to an RGBa color code. + - [`srm-31`](#brewtility.color/srm-31) - An SRM of 31 mapped to an RGBa color code. + - [`srm-32`](#brewtility.color/srm-32) - An SRM of 32 mapped to an RGBa color code. + - [`srm-33`](#brewtility.color/srm-33) - An SRM of 33 mapped to an RGBa color code. + - [`srm-34`](#brewtility.color/srm-34) - An SRM of 34 mapped to an RGBa color code. + - [`srm-35`](#brewtility.color/srm-35) - An SRM of 35 mapped to an RGBa color code. + - [`srm-36`](#brewtility.color/srm-36) - An SRM of 36 mapped to an RGBa color code. + - [`srm-37`](#brewtility.color/srm-37) - An SRM of 37 mapped to an RGBa color code. + - [`srm-38`](#brewtility.color/srm-38) - An SRM of 38 mapped to an RGBa color code. + - [`srm-39`](#brewtility.color/srm-39) - An SRM of 39 mapped to an RGBa color code. + - [`srm-4`](#brewtility.color/srm-4) - An SRM of 4 mapped to an RGBa color code. + - [`srm-40`](#brewtility.color/srm-40) - An SRM of 40 mapped to an RGBa color code. + - [`srm-5`](#brewtility.color/srm-5) - An SRM of 5 mapped to an RGBa color code. + - [`srm-6`](#brewtility.color/srm-6) - An SRM of 6 mapped to an RGBa color code. + - [`srm-7`](#brewtility.color/srm-7) - An SRM of 7 mapped to an RGBa color code. + - [`srm-8`](#brewtility.color/srm-8) - An SRM of 8 mapped to an RGBa color code. + - [`srm-9`](#brewtility.color/srm-9) - An SRM of 9 mapped to an RGBa color code. + - [`srm->ebc`](#brewtility.color/srm->ebc) - Convert the color described by the srm to the equivalent EBC color. + - [`srm->lovibond`](#brewtility.color/srm->lovibond) - Convert the color described in 'srm` to the equivalent degrees Lovibond. + - [`srm->rgba`](#brewtility.color/srm->rgba) - Given srm-number, return the closest, bounded applicable RGBA color string. + - [`srm-color-map`](#brewtility.color/srm-color-map) - A map of integer values to their closest SRM value as an RGBa color code. +- [`brewtility.enrich.equipment`](#brewtility.enrich.equipment) - Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps. + - [`enrich-calculated-boil-size`](#brewtility.enrich.equipment/enrich-calculated-boil-size) - An enricher pattern function to calculate the boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record via [[brewtility.calculations/calculate-equipment-boil-volume]]. + - [`enrich-display-batch-size`](#brewtility.enrich.equipment/enrich-display-batch-size) - An enricher pattern function to add the displayable batch size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-boil-size`](#brewtility.enrich.equipment/enrich-display-boil-size) - An enricher pattern function to add the displayable boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-lauter-deadspace`](#brewtility.enrich.equipment/enrich-display-lauter-deadspace) - An enricher pattern function to add the displayable lauter deadspace to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-top-up-kettle`](#brewtility.enrich.equipment/enrich-display-top-up-kettle) - An enricher pattern function to add the displayable top up kettle to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-top-up-water`](#brewtility.enrich.equipment/enrich-display-top-up-water) - An enricher pattern function to add the displayable top up water to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-trub-chiller-loss`](#brewtility.enrich.equipment/enrich-display-trub-chiller-loss) - An enricher pattern function to add the displayable trub chiller loss to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-tun-volume`](#brewtility.enrich.equipment/enrich-display-tun-volume) - An enricher pattern function to add the displayable tun volume to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-display-tun-weight`](#brewtility.enrich.equipment/enrich-display-tun-weight) - An enricher pattern function to add the displayable tun weight to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + - [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) - An enricher pattern function to derive as many values from an [equipment record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). + - [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper) - An enricher pattern function to derive as many values from an [equipment-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). +- [`brewtility.enrich.fermentables`](#brewtility.enrich.fermentables) - Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps. + - [`enrich-add-after-boil`](#brewtility.enrich.fermentables/enrich-add-after-boil) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. + - [`enrich-coarse-fine-diff`](#brewtility.enrich.fermentables/enrich-coarse-fine-diff) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a coarse/fine differential. + - [`enrich-diastatic-power`](#brewtility.enrich.fermentables/enrich-diastatic-power) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a listed Diastatic Power. + - [`enrich-display-amount`](#brewtility.enrich.fermentables/enrich-display-amount) - An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + - [`enrich-display-color`](#brewtility.enrich.fermentables/enrich-display-color) - An enricher pattern function to determine what color a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + - [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) - An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + - [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper) - An enricher pattern function to derive as many values from an [fermentable-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + - [`enrich-fermentables`](#brewtility.enrich.fermentables/enrich-fermentables) - An enricher pattern function to derive as many values from an [fermentables record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + - [`enrich-fermentables-wrapper`](#brewtility.enrich.fermentables/enrich-fermentables-wrapper) - An enricher pattern function to derive as many values from an [fermentables-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + - [`enrich-ibu-gallons-per-pound`](#brewtility.enrich.fermentables/enrich-ibu-gallons-per-pound) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. + - [`enrich-moisture`](#brewtility.enrich.fermentables/enrich-moisture) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a moisture content. + - [`enrich-protein`](#brewtility.enrich.fermentables/enrich-protein) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have protein. + - [`enrich-recommend-mash`](#brewtility.enrich.fermentables/enrich-recommend-mash) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. +- [`brewtility.enrich.hops`](#brewtility.enrich.hops) - Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps. + - [`enrich-display-amount`](#brewtility.enrich.hops/enrich-display-amount) - An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + - [`enrich-display-time`](#brewtility.enrich.hops/enrich-display-time) - An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + - [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) - An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + - [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper) - An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + - [`enrich-hops`](#brewtility.enrich.hops/enrich-hops) - An enricher pattern function to derive as many values from an [hops record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + - [`enrich-hops-wrapper`](#brewtility.enrich.hops/enrich-hops-wrapper) - An enricher pattern function to derive as many values from an [hops-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). +- [`brewtility.enrich.mash`](#brewtility.enrich.mash) - Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps. + - [`enrich-display-grain-temperature`](#brewtility.enrich.mash/enrich-display-grain-temperature) - An enricher pattern function to render a human-readable temperature of the grain temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-display-infuse-amount`](#brewtility.enrich.mash/enrich-display-infuse-amount) - An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-display-sparge-temperature`](#brewtility.enrich.mash/enrich-display-sparge-temperature) - An enricher pattern function to render a human-readable temperature of the sparge temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-display-step-temperature`](#brewtility.enrich.mash/enrich-display-step-temperature) - An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-display-tun-temperature`](#brewtility.enrich.mash/enrich-display-tun-temperature) - An enricher pattern function to render a human-readable temperature of the tun temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-display-tun-weight`](#brewtility.enrich.mash/enrich-display-tun-weight) - An enricher pattern function to render a human-readable weight of the tun weight during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + - [`enrich-mash`](#brewtility.enrich.mash/enrich-mash) - An enricher pattern function to derive as many values from an [mash record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + - [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) - An enricher pattern function to derive as many values from an [mash-step record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + - [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper) - An enricher pattern function to derive as many values from an [mash-step wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + - [`enrich-mash-steps`](#brewtility.enrich.mash/enrich-mash-steps) - An enricher pattern function to derive as many values from a collection of [mash-step wrapper records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + - [`enrich-mash-steps-wrapper`](#brewtility.enrich.mash/enrich-mash-steps-wrapper) - An enricher pattern function to derive as many values from a collection of [mash-steps wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + - [`enrich-mash-wrapper`](#brewtility.enrich.mash/enrich-mash-wrapper) - An enricher pattern function to derive as many values from an [mash wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). +- [`brewtility.enrich.miscs`](#brewtility.enrich.miscs) - Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps. + - [`enrich-amount-is-weight`](#brewtility.enrich.miscs/enrich-amount-is-weight) - An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. + - [`enrich-display-amount`](#brewtility.enrich.miscs/enrich-display-amount) - An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + - [`enrich-display-time`](#brewtility.enrich.miscs/enrich-display-time) - An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + - [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) - An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + - [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper) - An enricher pattern function to derive as many values from an [misc-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + - [`enrich-miscs`](#brewtility.enrich.miscs/enrich-miscs) - An enricher pattern function to derive as many values from an [miscs record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + - [`enrich-miscs-wrapper`](#brewtility.enrich.miscs/enrich-miscs-wrapper) - An enricher pattern function to derive as many values from an [miscs-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). +- [`brewtility.precision`](#brewtility.precision) - Namespace for handling numeric precision. + - [`->1dp`](#brewtility.precision/->1dp) - Given a decimal x, returns that number rounded to one decimal place. + - [`->2dp`](#brewtility.precision/->2dp) - Given a decimal x, returns that number rounded to two decimal places. + - [`->3dp`](#brewtility.precision/->3dp) - Given a decimal x, returns that number rounded to three decimal places. + - [`->precision`](#brewtility.precision/->precision) - Given a decimal x and the number of decimal places, returns that number rounded to num-decimals precision. + - [`approximates?`](#brewtility.precision/approximates?) - Determine if n2 approximates n1 within variance percent. +- [`brewtility.predicates.equipment`](#brewtility.predicates.equipment) - Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps. + - [`calculated-boil-volume?`](#brewtility.predicates.equipment/calculated-boil-volume?) - A predicate function to determine if an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) had its boil volume calculated. +- [`brewtility.predicates.fermentables`](#brewtility.predicates.fermentables) - Predicate functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps. + - [`add-after-boil?`](#brewtility.predicates.fermentables/add-after-boil?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the start of the boil. + - [`adjunct?`](#brewtility.predicates.fermentables/adjunct?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is an adjunct, non-standard fermentable. + - [`dry-extract?`](#brewtility.predicates.fermentables/dry-extract?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is dried malt extract. + - [`extract?`](#brewtility.predicates.fermentables/extract?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a liquid malt extract. + - [`grain?`](#brewtility.predicates.fermentables/grain?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is whole grain. + - [`sugar?`](#brewtility.predicates.fermentables/sugar?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a raw sugar. +- [`brewtility.predicates.hops`](#brewtility.predicates.hops) - Predicate functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps. + - [`aroma-type?`](#brewtility.predicates.hops/aroma-type?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for aroma. + - [`aroma-use?`](#brewtility.predicates.hops/aroma-use?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added at the end of the boil for aroma. + - [`bittering?`](#brewtility.predicates.hops/bittering?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for bittering. + - [`boil?`](#brewtility.predicates.hops/boil?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used during the boil. + - [`both?`](#brewtility.predicates.hops/both?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for both bittering and aroma. + - [`dry-hop?`](#brewtility.predicates.hops/dry-hop?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used as a dry-hop addition in secondary fermentation. + - [`first-wort?`](#brewtility.predicates.hops/first-wort?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added to the wort at the first possible moment. + - [`leaf?`](#brewtility.predicates.hops/leaf?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a whole hop cone. + - [`mash?`](#brewtility.predicates.hops/mash?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added during the mash and before the boil. + - [`pellet?`](#brewtility.predicates.hops/pellet?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed pellet. + - [`plug?`](#brewtility.predicates.hops/plug?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed whole-hop plug. +- [`brewtility.predicates.mash`](#brewtility.predicates.mash) - Predicate functions for [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps. + - [`adjust-for-equipment?`](#brewtility.predicates.mash/adjust-for-equipment?) - A predicate function to determine if a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) should account for any temperature effects of the equipment used. + - [`decoction?`](#brewtility.predicates.mash/decoction?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to extract and concentrate flavor. + - [`infusion?`](#brewtility.predicates.mash/infusion?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used as a basic infusion. + - [`temperature?`](#brewtility.predicates.mash/temperature?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to bring wort up to temperature. +- [`brewtility.predicates.miscs`](#brewtility.predicates.miscs) - Predicate functions for [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps. + - [`boil?`](#brewtility.predicates.miscs/boil?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the boil. + - [`bottling?`](#brewtility.predicates.miscs/bottling?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during bottle conditioning. + - [`fining?`](#brewtility.predicates.miscs/fining?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. + - [`flavor?`](#brewtility.predicates.miscs/flavor?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is added for flavor. + - [`herb?`](#brewtility.predicates.miscs/herb?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a herb. + - [`mash?`](#brewtility.predicates.miscs/mash?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the mash. + - [`other?`](#brewtility.predicates.miscs/other?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is an unspecified type. + - [`primary?`](#brewtility.predicates.miscs/primary?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the primary fermentation. + - [`secondary?`](#brewtility.predicates.miscs/secondary?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the secondary fermentation. + - [`spice?`](#brewtility.predicates.miscs/spice?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a spice. + - [`water-agent?`](#brewtility.predicates.miscs/water-agent?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a water agent. +- [`brewtility.predicates.recipes`](#brewtility.predicates.recipes) - Predicate functions for [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) maps. + - [`all-grain?`](#brewtility.predicates.recipes/all-grain?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made entirely of grain. + - [`extract?`](#brewtility.predicates.recipes/extract?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made with extract only. + - [`forced-carbonation?`](#brewtility.predicates.recipes/forced-carbonation?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was forcefully carbonated. + - [`garetz?`](#brewtility.predicates.recipes/garetz?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the garetz method. + - [`partial-mash?`](#brewtility.predicates.recipes/partial-mash?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was partially mashed. + - [`rager?`](#brewtility.predicates.recipes/rager?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the Rager method. + - [`tinseth?`](#brewtility.predicates.recipes/tinseth?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the tinseth method. +- [`brewtility.predicates.styles`](#brewtility.predicates.styles) - Predicate functions for [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps. + - [`ale?`](#brewtility.predicates.styles/ale?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. + - [`cider?`](#brewtility.predicates.styles/cider?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ciders. + - [`lager?`](#brewtility.predicates.styles/lager?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for lagers. + - [`mead?`](#brewtility.predicates.styles/mead?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for meads. + - [`mixed?`](#brewtility.predicates.styles/mixed?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for blended/mixed beers. + - [`wheat?`](#brewtility.predicates.styles/wheat?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for wheat beers. +- [`brewtility.predicates.waters`](#brewtility.predicates.waters) - Predicate functions for [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps. + - [`acidic?`](#brewtility.predicates.waters/acidic?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is acidic. + - [`alkaline?`](#brewtility.predicates.waters/alkaline?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. + - [`neutral?`](#brewtility.predicates.waters/neutral?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. +- [`brewtility.predicates.yeasts`](#brewtility.predicates.yeasts) - Predicate functions for [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps. + - [`ale?`](#brewtility.predicates.yeasts/ale?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for ale. + - [`champagne?`](#brewtility.predicates.yeasts/champagne?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. + - [`culture?`](#brewtility.predicates.yeasts/culture?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. + - [`dry?`](#brewtility.predicates.yeasts/dry?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. + - [`high-flocculation?`](#brewtility.predicates.yeasts/high-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. + - [`lager?`](#brewtility.predicates.yeasts/lager?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. + - [`liquid?`](#brewtility.predicates.yeasts/liquid?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in liquid form. + - [`low-flocculation?`](#brewtility.predicates.yeasts/low-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a low amount of floc. + - [`medium-flocculation?`](#brewtility.predicates.yeasts/medium-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. + - [`slant?`](#brewtility.predicates.yeasts/slant?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. + - [`very-high-flocculation?`](#brewtility.predicates.yeasts/very-high-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. + - [`wheat?`](#brewtility.predicates.yeasts/wheat?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. + - [`wine?`](#brewtility.predicates.yeasts/wine?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. +- [`brewtility.string`](#brewtility.string) - String comparison utilities. + - [`->spongebob-case`](#brewtility.string/->spongebob-case) - Take a string s and coerce characters alternatively between lower and upper case. + - [`->sporadic-case`](#brewtility.string/->sporadic-case) - Take a string s and randomly coerce characters to either lower or upper case. + - [`includes?`](#brewtility.string/includes?) - Checks to see if s1 includes s2 after each string has been modified by prepare-for-compare. + - [`prepare-for-compare`](#brewtility.string/prepare-for-compare) - Takes a string s, trims it, and coerces it to lower case. + - [`same?`](#brewtility.string/same?) - Checks to see if s1 and s2 are equal after each string has been modified by prepare-for-compare. +- [`brewtility.units`](#brewtility.units) - Namespace for converting between different units of measure. + - [`celsius->temperature-measurement`](#brewtility.units/celsius->temperature-measurement) - A map from measurement names to the implementation function which converts them from degrees celsius. + - [`convert-temperature`](#brewtility.units/convert-temperature) - Given a temperature in source-measurement, convert it to the target-measurement. + - [`convert-time`](#brewtility.units/convert-time) - Given a time-val in source-measurement, convert it to the target-measurement. + - [`convert-volume`](#brewtility.units/convert-volume) - Given a volume in source-measurement, convert it to the target-measurement. + - [`convert-weight`](#brewtility.units/convert-weight) - Given a weight in source-measurement, convert it to the target-measurement. + - [`suffix-types`](#brewtility.units/suffix-types) - The unit suffix types available across brewtility. + - [`systems-of-meaure`](#brewtility.units/systems-of-meaure) - The systems of measure available across brewtility. + - [`temperature-measurement->celsius`](#brewtility.units/temperature-measurement->celsius) - A map from measurement names to the implementation function which converts them to degrees celsius. + - [`temperature-measurements`](#brewtility.units/temperature-measurements) - The temperature measurements available across brewtility. + - [`temperature-measurements->display-name`](#brewtility.units/temperature-measurements->display-name) - A map from measurement names to their full name and abbreviation. + - [`time-measurement->minute`](#brewtility.units/time-measurement->minute) - A map from measurement names to doubles representing their fractional value to one minute. + - [`time-measurements`](#brewtility.units/time-measurements) - The time measurements available across brewtility. + - [`time-measurements->display-name`](#brewtility.units/time-measurements->display-name) - A map from measurement names to their full name and abbreviation. + - [`volume-measurement->litre`](#brewtility.units/volume-measurement->litre) - A map from measurement names to doubles representing their fractional value to one liter. + - [`volume-measurements`](#brewtility.units/volume-measurements) - The volume measurements available across brewtility. + - [`volume-measurements->display-name`](#brewtility.units/volume-measurements->display-name) - A map from measurement names to their full name and abbreviation. + - [`weight-measurement->kilogram`](#brewtility.units/weight-measurement->kilogram) - A map from measurement names to doubles representing their fractional value to one kilogram. + - [`weight-measurements`](#brewtility.units/weight-measurements) - The weight measurements available across brewtility. + - [`weight-measurements->display-name`](#brewtility.units/weight-measurements->display-name) - A map from measurement names to their full name and abbreviation. +- [`brewtility.wrapping`](#brewtility.wrapping) - Namespace for wrapping and unwrapping common-beer-format maps. + - [`unwrap-equipment`](#brewtility.wrapping/unwrap-equipment) - Unwrap an equipment-wrapper map into an equipment map. + - [`unwrap-fermentable`](#brewtility.wrapping/unwrap-fermentable) - Unwrap a fermentable-wrapper map into a fermentable map. + - [`unwrap-fermentables`](#brewtility.wrapping/unwrap-fermentables) - Unwrap a fermentables-wrapper map into a fermentables collection. + - [`unwrap-hop`](#brewtility.wrapping/unwrap-hop) - Unwrap a hop-wrapper map into a hop map. + - [`unwrap-hops`](#brewtility.wrapping/unwrap-hops) - Unwrap a hops-wrapper map into a hops collection. + - [`unwrap-mash`](#brewtility.wrapping/unwrap-mash) - Unwrap a mash-wrapper map into a mash map. + - [`unwrap-mash-step`](#brewtility.wrapping/unwrap-mash-step) - Unwrap a mash-step-wrapper map into a mash-step map. + - [`unwrap-mash-steps`](#brewtility.wrapping/unwrap-mash-steps) - Unwrap a mash-steps-wrapper map into a mash-steps collection. + - [`unwrap-misc`](#brewtility.wrapping/unwrap-misc) - Unwrap a misc-wrapper map into a misc map. + - [`unwrap-miscs`](#brewtility.wrapping/unwrap-miscs) - Unwrap a miscs-wrapper map into a miscs collection. + - [`unwrap-recipe`](#brewtility.wrapping/unwrap-recipe) - Unwrap a recipe-wrapper map into a recipe map. + - [`unwrap-recipes`](#brewtility.wrapping/unwrap-recipes) - Unwrap a recipes-wrapper map into a recipes collection. + - [`unwrap-style`](#brewtility.wrapping/unwrap-style) - Unwrap a style-wrapper map into a style map. + - [`unwrap-styles`](#brewtility.wrapping/unwrap-styles) - Unwrap a styles-wrapper map into a styles collection. + - [`unwrap-water`](#brewtility.wrapping/unwrap-water) - Unwrap a water-wrapper map into a water map. + - [`unwrap-waters`](#brewtility.wrapping/unwrap-waters) - Unwrap a waters-wrapper map into a waters collection. + - [`unwrap-yeast`](#brewtility.wrapping/unwrap-yeast) - Unwrap a yeast-wrapper map into a yeast map. + - [`unwrap-yeasts`](#brewtility.wrapping/unwrap-yeasts) - Unwrap a yeasts-wrapper map into a yeasts collection. + - [`wrap-equipment`](#brewtility.wrapping/wrap-equipment) - Wrap an equipment map into an equipment-wrapper map. + - [`wrap-fermentable`](#brewtility.wrapping/wrap-fermentable) - Wrap a fermentable map into a fermentable-wrapper map. + - [`wrap-fermentables`](#brewtility.wrapping/wrap-fermentables) - Wrap a fermentables collection into a fermentables-wrapper map. + - [`wrap-hop`](#brewtility.wrapping/wrap-hop) - Wrap a hop map into a hop-wrapper map. + - [`wrap-hops`](#brewtility.wrapping/wrap-hops) - Wrap a hops collection into a hops-wrapper map. + - [`wrap-mash`](#brewtility.wrapping/wrap-mash) - Wrap a mash map into a mash-wrapper map. + - [`wrap-mash-step`](#brewtility.wrapping/wrap-mash-step) - Wrap a mash-step map into a mash-step-wrapper map. + - [`wrap-mash-steps`](#brewtility.wrapping/wrap-mash-steps) - Wrap a mash-steps collection into a mash-steps-wrapper map. + - [`wrap-misc`](#brewtility.wrapping/wrap-misc) - Wrap a misc map into a misc-wrapper map. + - [`wrap-miscs`](#brewtility.wrapping/wrap-miscs) - Wrap a miscs collection into a miscs-wrapper map. + - [`wrap-recipe`](#brewtility.wrapping/wrap-recipe) - Wrap a recipe map into a recipe-wrapper map. + - [`wrap-recipes`](#brewtility.wrapping/wrap-recipes) - Wrap a recipes collection into a recipes-wrapper map. + - [`wrap-style`](#brewtility.wrapping/wrap-style) - Wrap a style map into a style-wrapper map. + - [`wrap-styles`](#brewtility.wrapping/wrap-styles) - Wrap a styles collection into a styles-wrapper map. + - [`wrap-water`](#brewtility.wrapping/wrap-water) - Wrap a water map into a water-wrapper map. + - [`wrap-waters`](#brewtility.wrapping/wrap-waters) - Wrap a waters collection into a waters-wrapper map. + - [`wrap-yeast`](#brewtility.wrapping/wrap-yeast) - Wrap a yeast map into a yeast-wrapper map. + - [`wrap-yeasts`](#brewtility.wrapping/wrap-yeasts) - Wrap a yeasts collection into a yeasts-wrapper map. + +----- +# brewtility.calculations + + +Namespace for handling recipe calculations. + This namespace assumes ingredients that conform to the [common-beer-format](https://github.com/Wall-Brew-Co/common-beer-format). + + + + +## `calculate-alpha-acid-units` [:page_facing_up:](null) + +``` clojure + +(calculate-alpha-acid-units weight alpha) +``` + + +Calculate the maximum amount of alpha acid released by `weight` ounce of a hop at `percent` alpha acid + +## `calculate-ebc-color` [:page_facing_up:](null) + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the EBC color for a recipe + +## `calculate-equipment-boil-volume` [:page_facing_up:](null) + +``` clojure + +(calculate-equipment-boil-volume {:keys [batch-size top-up-water trub-chiller-loss boil-time evap-rate]}) +``` + + +Given a `common-beer-format` conforming `equipment`, calculate the volume of the wort at the start of the boil. + If insufficient data is provided, this function will throw an exception. + +## `calculate-hop-utilization` [:page_facing_up:](null) + +``` clojure + +(calculate-hop-utilization gravity boil-duration) +``` + + +Calculate the percentage of alpha acid that a hop could release over `boil-duration` in a wort at a specific `gravity` + Based on: http://howtobrew.com/book/section-1/hops/hop-bittering-calculations + +## `calculate-ibu-per-hop` [:page_facing_up:](null) + +``` clojure + +(calculate-ibu-per-hop hop batch-size potential-gravity) +``` + + +Given a `common-beer-format` conforming `hop`, `batch-size`, and `potential-gravity`, calculate the amount of IBUs generated + +## `calculate-lovibond-color` [:page_facing_up:](null) + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the color in degrees Lovibond for a recipe + +## `calculate-malt-color-units` [:page_facing_up:](null) + +``` clojure + +(calculate-malt-color-units fermentables batch-size) +``` + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the overall Malt Color Units for a recipe + +## `calculate-potential-abv` [:page_facing_up:](null) + +``` clojure + +(calculate-potential-abv fermentables batch-size) +(calculate-potential-abv fermentables batch-size attenuation) +``` + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, estimate the ABV. + The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed. + +## `calculate-potential-final-gravity` [:page_facing_up:](null) + +``` clojure + +(calculate-potential-final-gravity fermentables batch-size) +(calculate-potential-final-gravity fermentables batch-size attenuation) +``` + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, estimate the Final Gravity. + The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed. + +## `calculate-potential-gravity` [:page_facing_up:](null) + +``` clojure + +(calculate-potential-gravity fermentables batch-size) +``` + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, calculate the potential original gravity. + +## `calculate-recipe-ibus` [:page_facing_up:](null) + +``` clojure + +(calculate-recipe-ibus hops batch-size potential-gravity) +``` + + +Given a collection of `common-beer-format` conforming `hops`, `batch-size`, and `potential-gravity` calculate the amount of IBUs generated + +## `calculate-rgba-color` [:page_facing_up:](null) + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the RGBA color for a recipe + +## `calculate-srm-color` [:page_facing_up:](null) + +``` clojure + +(calculate-srm-color fermentables batch-size) +``` + + +Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the SRM color for a recipe + +## `default-attenuation` [:page_facing_up:](null) + + +A constant backup attenuation for calculations. + Set to 75% a common threshold for home brewing + +## `gravity->abv-multiplier` [:page_facing_up:](null) + + +The constanct factor used to calculate ABV from potential gravity + +## `gravity-points->potential-gravity` [:page_facing_up:](null) + +``` clojure + +(gravity-points->potential-gravity gravity-points volume) +``` + + +Given the `gravity-points` of a recipe, and the `volume` of the batch, calculate the potential gravity + +## `potential-gravity->gravity-points` [:page_facing_up:](null) + +``` clojure + +(potential-gravity->gravity-points potential-gravity weight) +``` + + +Given the `potential-gravity` of a fermentable, and the `weight` of the fermentable, calculate gravity points + +----- +# brewtility.color + + +Namespace for calculating beer colors + + + + +## `color-system->display-name` [:page_facing_up:](null) + + +A map from color system names to their full and short unit names + +## `color-systems` [:page_facing_up:](null) + + +The color systems available across brewtility + +## `ebc->lovibond` [:page_facing_up:](null) + + +Convert the color described in 'ebc` to the equivalent degrees Lovibond + +## `ebc->rgba` [:page_facing_up:](null) + + +Given `ebc-number`, return the closest, bounded applicable RGBA color string. + +## `ebc->srm` [:page_facing_up:](null) + +``` clojure + +(ebc->srm ebc) +``` + + +Convert the color described by the `ebc` to the equivalent SRM color + +## `lovibond->ebc` [:page_facing_up:](null) + + +Convert the color described in degrees 'lovibond` to the equivalent EBC color + +## `lovibond->rgba` [:page_facing_up:](null) + + +Given `lovibond-number`, return the closest, bounded applicable RGBA color string. + +## `lovibond->srm` [:page_facing_up:](null) + +``` clojure + +(lovibond->srm lovibond) +``` + + +Convert the color described in degrees `lovibond` to the equivalent SRM color + +## `srm-1` [:page_facing_up:](null) + + +An SRM of 1 mapped to an RGBa color code + +## `srm-10` [:page_facing_up:](null) + + +An SRM of 10 mapped to an RGBa color code + +## `srm-11` [:page_facing_up:](null) + + +An SRM of 11 mapped to an RGBa color code + +## `srm-12` [:page_facing_up:](null) + + +An SRM of 12 mapped to an RGBa color code + +## `srm-13` [:page_facing_up:](null) + + +An SRM of 13 mapped to an RGBa color code + +## `srm-14` [:page_facing_up:](null) + + +An SRM of 14 mapped to an RGBa color code + +## `srm-15` [:page_facing_up:](null) + + +An SRM of 15 mapped to an RGBa color code + +## `srm-16` [:page_facing_up:](null) + + +An SRM of 16 mapped to an RGBa color code + +## `srm-17` [:page_facing_up:](null) + + +An SRM of 17 mapped to an RGBa color code + +## `srm-18` [:page_facing_up:](null) + + +An SRM of 18 mapped to an RGBa color code + +## `srm-19` [:page_facing_up:](null) + + +An SRM of 19 mapped to an RGBa color code + +## `srm-2` [:page_facing_up:](null) + + +An SRM of 2 mapped to an RGBa color code + +## `srm-20` [:page_facing_up:](null) + + +An SRM of 20 mapped to an RGBa color code + +## `srm-21` [:page_facing_up:](null) + + +An SRM of 21 mapped to an RGBa color code + +## `srm-22` [:page_facing_up:](null) + + +An SRM of 22 mapped to an RGBa color code + +## `srm-23` [:page_facing_up:](null) + + +An SRM of 23 mapped to an RGBa color code + +## `srm-24` [:page_facing_up:](null) + + +An SRM of 24 mapped to an RGBa color code + +## `srm-25` [:page_facing_up:](null) + + +An SRM of 25 mapped to an RGBa color code + +## `srm-26` [:page_facing_up:](null) + + +An SRM of 26 mapped to an RGBa color code + +## `srm-27` [:page_facing_up:](null) + + +An SRM of 27 mapped to an RGBa color code + +## `srm-28` [:page_facing_up:](null) + + +An SRM of 28 mapped to an RGBa color code + +## `srm-29` [:page_facing_up:](null) + + +An SRM of 29 mapped to an RGBa color code + +## `srm-3` [:page_facing_up:](null) + + +An SRM of 3 mapped to an RGBa color code + +## `srm-30` [:page_facing_up:](null) + + +An SRM of 30 mapped to an RGBa color code + +## `srm-31` [:page_facing_up:](null) + + +An SRM of 31 mapped to an RGBa color code + +## `srm-32` [:page_facing_up:](null) + + +An SRM of 32 mapped to an RGBa color code + +## `srm-33` [:page_facing_up:](null) + + +An SRM of 33 mapped to an RGBa color code + +## `srm-34` [:page_facing_up:](null) + + +An SRM of 34 mapped to an RGBa color code + +## `srm-35` [:page_facing_up:](null) + + +An SRM of 35 mapped to an RGBa color code + +## `srm-36` [:page_facing_up:](null) + + +An SRM of 36 mapped to an RGBa color code + +## `srm-37` [:page_facing_up:](null) + + +An SRM of 37 mapped to an RGBa color code + +## `srm-38` [:page_facing_up:](null) + + +An SRM of 38 mapped to an RGBa color code + +## `srm-39` [:page_facing_up:](null) + + +An SRM of 39 mapped to an RGBa color code + +## `srm-4` [:page_facing_up:](null) + + +An SRM of 4 mapped to an RGBa color code + +## `srm-40` [:page_facing_up:](null) + + +An SRM of 40 mapped to an RGBa color code + +## `srm-5` [:page_facing_up:](null) + + +An SRM of 5 mapped to an RGBa color code + +## `srm-6` [:page_facing_up:](null) + + +An SRM of 6 mapped to an RGBa color code + +## `srm-7` [:page_facing_up:](null) + + +An SRM of 7 mapped to an RGBa color code + +## `srm-8` [:page_facing_up:](null) + + +An SRM of 8 mapped to an RGBa color code + +## `srm-9` [:page_facing_up:](null) + + +An SRM of 9 mapped to an RGBa color code + +## `srm->ebc` [:page_facing_up:](null) + +``` clojure + +(srm->ebc srm) +``` + + +Convert the color described by the `srm` to the equivalent EBC color + +## `srm->lovibond` [:page_facing_up:](null) + +``` clojure + +(srm->lovibond srm) +``` + + +Convert the color described in 'srm` to the equivalent degrees Lovibond + +## `srm->rgba` [:page_facing_up:](null) + +``` clojure + +(srm->rgba srm-number) +``` + + +Given `srm-number`, return the closest, bounded applicable RGBA color string. + OPINIONATED: The provided `srm-number` will be bound to the common range from 1 to 40 + Decimal-like values are trimmed, not rounded. + +## `srm-color-map` [:page_facing_up:](null) + + +A map of integer values to their closest SRM value as an RGBa color code + +----- +# brewtility.enrich.equipment + + +Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps + + + + +## `enrich-calculated-boil-size` [:page_facing_up:](null) + +``` clojure + +(enrich-calculated-boil-size equipment) +(enrich-calculated-boil-size + {:keys [calc-boil-volume], :as equipment} + {:keys [safe-calculating-boil-size precision], :or {precision 3}}) +``` + + +An enricher pattern function to calculate the boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record via [[brewtility.calculations/calculate-equipment-boil-volume]]. + In the BeerXML spec, this behavior is controlled by the `:calc-boil-volume` field. + When `:calc-boil-volume` is set to `true`, the `:boil-size` field is calculated as: + `(batch-size - top-up-water - trub-chiller-loss) * (1 + (boil-time * evap-rate))` + + When `:calc-boil-volume` is set to `false`, the `:boil-size` field is left unmodified. + As a note, both the BeerXML spec and common-beer-format only require the `boil-size` field to be a number. + Neither the specification nor the implementation will check to ensure the value is correct given the other fields. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - `:precision` - The number of decimal places to round the calculated value to. + Defaults to `3`. + +## `enrich-display-batch-size` [:page_facing_up:](null) + +``` clojure + +(enrich-display-batch-size equipment) +(enrich-display-batch-size equipment {:keys [batch-size-target-units batch-size-precision batch-size-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable batch size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the batch size into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the batch size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. + +## `enrich-display-boil-size` [:page_facing_up:](null) + +``` clojure + +(enrich-display-boil-size equipment) +(enrich-display-boil-size equipment {:keys [boil-size-target-units boil-size-precision boil-size-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the boil size into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. + +## `enrich-display-lauter-deadspace` [:page_facing_up:](null) + +``` clojure + +(enrich-display-lauter-deadspace equipment) +(enrich-display-lauter-deadspace + equipment + {:keys [lauter-deadspace-target-units lauter-deadspace-precision lauter-deadspace-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable lauter deadspace to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the lauter deadspace into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the lauter deadspace. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. + +## `enrich-display-top-up-kettle` [:page_facing_up:](null) + +``` clojure + +(enrich-display-top-up-kettle equipment) +(enrich-display-top-up-kettle + equipment + {:keys [top-up-kettle-target-units top-up-kettle-precision top-up-kettle-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable top up kettle to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the top up kettle into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the top up kettle. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. + +## `enrich-display-top-up-water` [:page_facing_up:](null) + +``` clojure + +(enrich-display-top-up-water equipment) +(enrich-display-top-up-water + equipment + {:keys [top-up-water-target-units top-up-water-precision top-up-water-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable top up water to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the top up water into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the top up water. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. + +## `enrich-display-trub-chiller-loss` [:page_facing_up:](null) + +``` clojure + +(enrich-display-trub-chiller-loss equipment) +(enrich-display-trub-chiller-loss + equipment + {:keys [trub-chiller-loss-target-units trub-chiller-loss-precision trub-chiller-loss-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable trub chiller loss to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the trub chiller loss into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the trub chiller loss. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. + +## `enrich-display-tun-volume` [:page_facing_up:](null) + +``` clojure + +(enrich-display-tun-volume equipment) +(enrich-display-tun-volume equipment {:keys [tun-volume-target-units tun-volume-precision tun-volume-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable tun volume to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the tun volume into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the tun volume. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. + +## `enrich-display-tun-weight` [:page_facing_up:](null) + +``` clojure + +(enrich-display-tun-weight equipment) +(enrich-display-tun-weight equipment {:keys [tun-weight-target-units tun-weight-precision tun-weight-suffix], :as opts}) +``` + + +An enricher pattern function to add the displayable tun weight to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:system-of-measure`: The unit system of measure to convert the tun weight into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the tun weight. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. + +## `enrich-equipment` [:page_facing_up:](null) + +``` clojure + +(enrich-equipment equipment) +(enrich-equipment equipment opts) +``` + + +An enricher pattern function to derive as many values from an [equipment record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-calculated-boil-size]] + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - [[enrich-display-boil-size]] + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. + - [[enrich-display-batch-size]] + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. + - [[enrich-diplay-tun-volume]] + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. + - [[enrich-display-tun-weight]] + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. + - [[enrich-display-top-up-water]] + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. + - [[enrich-display-trub-chiller-loss]] + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. + - [[enrich-display-lauter-deadspace]] + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. + - [[enrich-display-top-up-kettle]] + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. + +## `enrich-equipment-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-equipment-wrapper equipment-wrapper) +(enrich-equipment-wrapper equipment-wrapper opts) +``` + + +An enricher pattern function to derive as many values from an [equipment-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. + - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-calculated-boil-size]] + - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. + In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. + Defaults to `false`. + - [[enrich-display-boil-size]] + - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. + - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. + - [[enrich-display-batch-size]] + - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. + - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. + - [[enrich-diplay-tun-volume]] + - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. + - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. + - [[enrich-display-tun-weight]] + - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. + - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. + - [[enrich-display-top-up-water]] + - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. + - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. + - [[enrich-display-trub-chiller-loss]] + - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. + - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. + - [[enrich-display-lauter-deadspace]] + - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. + - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. + - [[enrich-display-top-up-kettle]] + - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. + - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. + +----- +# brewtility.enrich.fermentables + + +Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps + + + + +## `enrich-add-after-boil` [:page_facing_up:](null) + +``` clojure + +(enrich-add-after-boil fermentable) +(enrich-add-after-boil fermentable _opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the :add-after-boil field is not present, this function will explicitly set it to false. + +## `enrich-coarse-fine-diff` [:page_facing_up:](null) + +``` clojure + +(enrich-coarse-fine-diff fermentable) +(enrich-coarse-fine-diff fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a coarse/fine differential. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:coarse-fine-diff` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `enrich-diastatic-power` [:page_facing_up:](null) + +``` clojure + +(enrich-diastatic-power fermentable) +(enrich-diastatic-power fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a listed Diastatic Power. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:diastatic-power` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `enrich-display-amount` [:page_facing_up:](null) + +``` clojure + +(enrich-display-amount fermentable) +(enrich-display-amount + fermentable + {:keys [fermentable-amount-target-units fermentable-amount-precision fermentable-amount-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + In the BeerXML spec, the amount of a liquid extract is computed by its weight. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) and [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper), this function also supports the following keys: + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-color` [:page_facing_up:](null) + +``` clojure + +(enrich-display-color fermentable) +(enrich-display-color fermentable {:keys [color-system suffix], :as opts}) +``` + + +An enricher pattern function to determine what color a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. + In the BeerXML spec, color is assumed to be in Lovibond for the `:type` of `grain`, and SRM for all other fermentables. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained selections within the context of [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) and [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper), this function also supports the following keys: + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-fermentable` [:page_facing_up:](null) + +``` clojure + +(enrich-fermentable fermentable) +(enrich-fermentable fermentable opts) +``` + + +An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-fermentable-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-fermentable-wrapper fermentable) +(enrich-fermentable-wrapper fermentable opts) +``` + + +An enricher pattern function to derive as many values from an [fermentable-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-fermentables` [:page_facing_up:](null) + +``` clojure + +(enrich-fermentables fermentables) +(enrich-fermentables fermentables opts) +``` + + +An enricher pattern function to derive as many values from an [fermentables record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-fermentables-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-fermentables-wrapper fermentables) +(enrich-fermentables-wrapper fermentables opts) +``` + + +An enricher pattern function to derive as many values from an [fermentables-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-color]] + - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. + - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. + - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-amount]] + - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-ibu-gallons-per-pound` [:page_facing_up:](null) + +``` clojure + +(enrich-ibu-gallons-per-pound fermentable) +(enrich-ibu-gallons-per-pound fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `extract`. + When the fermetable is not an extract, this function will dissoc `:ibu-gal-per-lb` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `enrich-moisture` [:page_facing_up:](null) + +``` clojure + +(enrich-moisture fermentable) +(enrich-moisture fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a moisture content. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:moisture` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `enrich-protein` [:page_facing_up:](null) + +``` clojure + +(enrich-protein fermentable) +(enrich-protein fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have protein. + In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will dissoc `:protein` from the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `enrich-recommend-mash` [:page_facing_up:](null) + +``` clojure + +(enrich-recommend-mash fermentable) +(enrich-recommend-mash fermentable opts) +``` + + +An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. + In the BeerXML spec, this field should only be `true` if the `:type` of the fermentable is `grain` or `adjunct`. + When the fermetable is not a grain or adjunct, this function will set `:recommend-mash` to false in the fermentable. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.enrich.hops + + +Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps + + + + +## `enrich-display-amount` [:page_facing_up:](null) + +``` clojure + +(enrich-display-amount hop) +(enrich-display-amount hop {:keys [hop-amount-target-units hop-amount-precision hop-amount-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) and [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper), this function also supports the following keys: + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-time` [:page_facing_up:](null) + +``` clojure + +(enrich-display-time hop) +(enrich-display-time hop {:keys [hop-time-target-units hop-time-precision hop-time-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) and [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper), this function also supports the following keys: + - `:hop-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:hop-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`. + +## `enrich-hop` [:page_facing_up:](null) + +``` clojure + +(enrich-hop hop) +(enrich-hop hop opts) +``` + + +An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-hop-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-hop-wrapper hop) +(enrich-hop-wrapper hop opts) +``` + + +An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-hops` [:page_facing_up:](null) + +``` clojure + +(enrich-hops hops) +(enrich-hops hops opts) +``` + + +An enricher pattern function to derive as many values from an [hops record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-hops-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-hops-wrapper hops) +(enrich-hops-wrapper hops opts) +``` + + +An enricher pattern function to derive as many values from an [hops-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +----- +# brewtility.enrich.mash + + +Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps + + + + +## `enrich-display-grain-temperature` [:page_facing_up:](null) + +``` clojure + +(enrich-display-grain-temperature mash) +(enrich-display-grain-temperature + mash + {:keys [display-grain-temperature-target-units display-grain-temperature-precision display-grain-temperature-suffix], + :as opts}) +``` + + +An enricher pattern function to render a human-readable temperature of the grain temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-infuse-amount` [:page_facing_up:](null) + +``` clojure + +(enrich-display-infuse-amount mash-step) +(enrich-display-infuse-amount + mash-step + {:keys [display-infuse-amount-target-units display-infuse-amount-precision display-infuse-amount-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-sparge-temperature` [:page_facing_up:](null) + +``` clojure + +(enrich-display-sparge-temperature mash) +(enrich-display-sparge-temperature + mash + {:keys + [display-sparge-temperature-target-units display-sparge-temperature-precision display-sparge-temperature-suffix], + :as opts}) +``` + + +An enricher pattern function to render a human-readable temperature of the sparge temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-spargeed selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-step-temperature` [:page_facing_up:](null) + +``` clojure + +(enrich-display-step-temperature mash-step) +(enrich-display-step-temperature + mash-step + {:keys [display-temperature-target-units display-temperature-precision display-temperature-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-tun-temperature` [:page_facing_up:](null) + +``` clojure + +(enrich-display-tun-temperature mash) +(enrich-display-tun-temperature + mash + {:keys [display-tun-temperature-target-units display-tun-temperature-precision display-tun-temperature-suffix], + :as opts}) +``` + + +An enricher pattern function to render a human-readable temperature of the tun temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-tuned selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-display-tun-weight` [:page_facing_up:](null) + +``` clojure + +(enrich-display-tun-weight mash) +(enrich-display-tun-weight + mash + {:keys [display-tun-weight-target-units display-tun-weight-precision display-tun-weight-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable weight of the tun weight during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-tuned selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash` [:page_facing_up:](null) + +``` clojure + +(enrich-mash mash) +(enrich-mash mash opts) +``` + + +An enricher pattern function to derive as many values from an [mash record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-grain-temperature]] + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-tun-temperature]] + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-sparge-temperature]] + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` + - [[enrich-display-tun-weight]] + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash-step` [:page_facing_up:](null) + +``` clojure + +(enrich-mash-step mash-step) +(enrich-mash-step mash-step opts) +``` + + +An enricher pattern function to derive as many values from an [mash-step record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash-step-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-mash-step-wrapper mash-step) +(enrich-mash-step-wrapper mash-step opts) +``` + + +An enricher pattern function to derive as many values from an [mash-step wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash-steps` [:page_facing_up:](null) + +``` clojure + +(enrich-mash-steps mash-steps) +(enrich-mash-steps mash-steps opts) +``` + + +An enricher pattern function to derive as many values from a collection of [mash-step wrapper records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash-steps-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-mash-steps-wrapper mash) +(enrich-mash-steps-wrapper mash opts) +``` + + +An enricher pattern function to derive as many values from a collection of [mash-steps wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-mash-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-mash-wrapper mash) +(enrich-mash-wrapper mash opts) +``` + + +An enricher pattern function to derive as many values from an [mash wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-step-temperature]] + - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. + - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-grain-temperature]] + - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-tun-temperature]] + - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-sparge-temperature]] + - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` + - [[enrich-display-tun-weight]] + - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +----- +# brewtility.enrich.miscs + + +Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps + + + + +## `enrich-amount-is-weight` [:page_facing_up:](null) + +``` clojure + +(enrich-amount-is-weight misc) +(enrich-amount-is-weight misc _) +``` + + +An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. + When this feild is not present, it is assumed to be false. + +## `enrich-display-amount` [:page_facing_up:](null) + +``` clojure + +(enrich-display-amount misc) +(enrich-display-amount misc {:keys [misc-time-target-units misc-time-precision misc-time-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. + Otherwise, it will be treated as a volume in liters. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) and [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper), this function also supports the following keys: + - `:misc-amount-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the time. Supersedes `:suffix`. + +## `enrich-display-time` [:page_facing_up:](null) + +``` clojure + +(enrich-display-time misc) +(enrich-display-time misc {:keys [misc-time-target-units misc-time-precision misc-time-suffix], :as opts}) +``` + + +An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. + - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. + + To support fine-grained selections within the context of [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) and [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper), this function also supports the following keys: + - `:misc-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:misc-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`. + +## `enrich-misc` [:page_facing_up:](null) + +``` clojure + +(enrich-misc misc) +(enrich-misc misc opts) +``` + + +An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-misc-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-misc-wrapper misc) +(enrich-misc-wrapper misc opts) +``` + + +An enricher pattern function to derive as many values from an [misc-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-miscs` [:page_facing_up:](null) + +``` clojure + +(enrich-miscs miscs) +(enrich-miscs miscs opts) +``` + + +An enricher pattern function to derive as many values from an [miscs record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +## `enrich-miscs-wrapper` [:page_facing_up:](null) + +``` clojure + +(enrich-miscs-wrapper miscs) +(enrich-miscs-wrapper miscs opts) +``` + + +An enricher pattern function to derive as many values from an [miscs-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + +----- +# brewtility.precision + + +Namespace for handling numeric precision + + + + +## `->1dp` [:page_facing_up:](null) + +``` clojure + +(->1dp x) +``` + + +Given a decimal `x`, returns that number rounded to one decimal place. + +## `->2dp` [:page_facing_up:](null) + +``` clojure + +(->2dp x) +``` + + +Given a decimal `x`, returns that number rounded to two decimal places. + +## `->3dp` [:page_facing_up:](null) + +``` clojure + +(->3dp x) +``` + + +Given a decimal `x`, returns that number rounded to three decimal places. + +## `->precision` [:page_facing_up:](null) + +``` clojure + +(->precision x num-decimals) +``` + + +Given a decimal `x` and the number of decimal places, returns that number rounded to `num-decimals` precision + +## `approximates?` [:page_facing_up:](null) + +``` clojure + +(approximates? n1 n2 variance) +``` + + +Determine if `n2` approximates `n1` within `variance` percent + +----- +# brewtility.predicates.equipment + + +Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps + + + + +## `calculated-boil-volume?` [:page_facing_up:](null) + +``` clojure + +(calculated-boil-volume? equipment) +``` + + +A predicate function to determine if an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) had its boil volume calculated. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the :calc-boil-volume field is not present, this function will explicitly return false. + +----- +# brewtility.predicates.fermentables + + +Predicate functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps + + + + +## `add-after-boil?` [:page_facing_up:](null) + +``` clojure + +(add-after-boil? fermentable) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the start of the boil. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the :add-after-boil field is not present, this function will explicitly return false. + +## `adjunct?` [:page_facing_up:](null) + +``` clojure + +(adjunct? fermentable) +(adjunct? fermentable opts) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is an adjunct, non-standard fermentable. + This function will throw an exception if the `type` field is not present. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `dry-extract?` [:page_facing_up:](null) + +``` clojure + +(dry-extract? fermentable) +(dry-extract? fermentable opts) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is dried malt extract. + This function will throw an exception if the `type` field is not present. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `extract?` [:page_facing_up:](null) + +``` clojure + +(extract? fermentable) +(extract? fermentable opts) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a liquid malt extract. + This function will throw an exception if the `type` field is not present. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `grain?` [:page_facing_up:](null) + +``` clojure + +(grain? fermentable) +(grain? fermentable opts) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is whole grain. + This function will throw an exception if the `type` field is not present. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `sugar?` [:page_facing_up:](null) + +``` clojure + +(sugar? fermentable) +(sugar? fermentable opts) +``` + + +A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a raw sugar. + This function will throw an exception if the `type` field is not present. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.hops + + +Predicate functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps + + + + +## `aroma-type?` [:page_facing_up:](null) + +``` clojure + +(aroma-type? hop) +(aroma-type? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for aroma. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `aroma-use?` [:page_facing_up:](null) + +``` clojure + +(aroma-use? hop) +(aroma-use? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added at the end of the boil for aroma. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `bittering?` [:page_facing_up:](null) + +``` clojure + +(bittering? hop) +(bittering? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for bittering. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `boil?` [:page_facing_up:](null) + +``` clojure + +(boil? hop) +(boil? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used during the boil. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `both?` [:page_facing_up:](null) + +``` clojure + +(both? hop) +(both? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for both bittering and aroma. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `dry-hop?` [:page_facing_up:](null) + +``` clojure + +(dry-hop? hop) +(dry-hop? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used as a dry-hop addition in secondary fermentation. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `first-wort?` [:page_facing_up:](null) + +``` clojure + +(first-wort? hop) +(first-wort? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added to the wort at the first possible moment. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `leaf?` [:page_facing_up:](null) + +``` clojure + +(leaf? hop) +(leaf? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a whole hop cone. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. + +## `mash?` [:page_facing_up:](null) + +``` clojure + +(mash? hop) +(mash? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added during the mash and before the boil. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `pellet?` [:page_facing_up:](null) + +``` clojure + +(pellet? hop) +(pellet? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed pellet. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. + +## `plug?` [:page_facing_up:](null) + +``` clojure + +(plug? hop) +(plug? hop opts) +``` + + +A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed whole-hop plug. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.mash + + +Predicate functions for [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps + + + + +## `adjust-for-equipment?` [:page_facing_up:](null) + +``` clojure + +(adjust-for-equipment? mash) +``` + + +A predicate function to determine if a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) should account for any temperature effects of the equipment used. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the `:equip-adjust` field is not present, this function will return false. + +## `decoction?` [:page_facing_up:](null) + +``` clojure + +(decoction? mash-step) +(decoction? mash-step opts) +``` + + +A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to extract and concentrate flavor. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `infusion?` [:page_facing_up:](null) + +``` clojure + +(infusion? mash-step) +(infusion? mash-step opts) +``` + + +A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used as a basic infusion. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `temperature?` [:page_facing_up:](null) + +``` clojure + +(temperature? mash-step) +(temperature? mash-step opts) +``` + + +A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to bring wort up to temperature. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.miscs + + +Predicate functions for [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps + + + + +## `boil?` [:page_facing_up:](null) + +``` clojure + +(boil? misc) +(boil? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the boil. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `bottling?` [:page_facing_up:](null) + +``` clojure + +(bottling? misc) +(bottling? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during bottle conditioning. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `fining?` [:page_facing_up:](null) + +``` clojure + +(fining? misc) +(fining? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `flavor?` [:page_facing_up:](null) + +``` clojure + +(flavor? misc) +(flavor? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is added for flavor. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `herb?` [:page_facing_up:](null) + +``` clojure + +(herb? misc) +(herb? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a herb. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `mash?` [:page_facing_up:](null) + +``` clojure + +(mash? misc) +(mash? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the mash. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `other?` [:page_facing_up:](null) + +``` clojure + +(other? misc) +(other? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is an unspecified type. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `primary?` [:page_facing_up:](null) + +``` clojure + +(primary? misc) +(primary? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the primary fermentation. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `secondary?` [:page_facing_up:](null) + +``` clojure + +(secondary? misc) +(secondary? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the secondary fermentation. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. + +## `spice?` [:page_facing_up:](null) + +``` clojure + +(spice? misc) +(spice? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a spice. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `water-agent?` [:page_facing_up:](null) + +``` clojure + +(water-agent? misc) +(water-agent? misc opts) +``` + + +A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a water agent. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.recipes + + +Predicate functions for [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) maps + + + + +## `all-grain?` [:page_facing_up:](null) + +``` clojure + +(all-grain? recipe) +(all-grain? recipe opts) +``` + + +A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made entirely of grain. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `extract?` [:page_facing_up:](null) + +``` clojure + +(extract? recipe) +(extract? recipe opts) +``` + + +A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made with extract only. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `forced-carbonation?` [:page_facing_up:](null) + +``` clojure + +(forced-carbonation? recipe) +``` + + +A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was forcefully carbonated. + In the BeerXML spec, this behavior is implicitly falsey. + Therefore, if the :forced-carbonation field is not present, this function will explicitly return false. + +## `garetz?` [:page_facing_up:](null) + +``` clojure + +(garetz? recipe) +(garetz? recipe opts) +``` + + +A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the garetz method. + This method was originally developed by Mark Garetz, and is most accurate for High IBU recipes. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. + +## `partial-mash?` [:page_facing_up:](null) + +``` clojure + +(partial-mash? recipe) +(partial-mash? recipe opts) +``` + + +A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was partially mashed. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `rager?` [:page_facing_up:](null) + +``` clojure + +(rager? recipe) +(rager? recipe opts) +``` + + +A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the Rager method. + This method was originally developed by Jackie Rager, and is most accurate for partial mash recipes. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. + +## `tinseth?` [:page_facing_up:](null) + +``` clojure + +(tinseth? recipe) +(tinseth? recipe opts) +``` + + +A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the tinseth method. + This method was originally developed by Glenn Tinseth, and is most accurate for all grain recipes. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.styles + + +Predicate functions for [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps + + + + +## `ale?` [:page_facing_up:](null) + +``` clojure + +(ale? style) +(ale? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `cider?` [:page_facing_up:](null) + +``` clojure + +(cider? style) +(cider? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ciders. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `lager?` [:page_facing_up:](null) + +``` clojure + +(lager? style) +(lager? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for lagers. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `mead?` [:page_facing_up:](null) + +``` clojure + +(mead? style) +(mead? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for meads. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `mixed?` [:page_facing_up:](null) + +``` clojure + +(mixed? style) +(mixed? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for blended/mixed beers. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `wheat?` [:page_facing_up:](null) + +``` clojure + +(wheat? style) +(wheat? style opts) +``` + + +A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for wheat beers. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.predicates.waters + + +Predicate functions for [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps. + + + + +## `acidic?` [:page_facing_up:](null) + +``` clojure + +(acidic? water) +``` + + +A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is acidic. + +## `alkaline?` [:page_facing_up:](null) + +``` clojure + +(alkaline? water) +``` + + +A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. + +## `neutral?` [:page_facing_up:](null) + +``` clojure + +(neutral? water) +``` + + +A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. + +----- +# brewtility.predicates.yeasts + + +Predicate functions for [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps + + + + +## `ale?` [:page_facing_up:](null) + +``` clojure + +(ale? yeast) +(ale? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for ale. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `champagne?` [:page_facing_up:](null) + +``` clojure + +(champagne? yeast) +(champagne? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `culture?` [:page_facing_up:](null) + +``` clojure + +(culture? yeast) +(culture? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `dry?` [:page_facing_up:](null) + +``` clojure + +(dry? yeast) +(dry? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `high-flocculation?` [:page_facing_up:](null) + +``` clojure + +(high-flocculation? yeast) +(high-flocculation? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `lager?` [:page_facing_up:](null) + +``` clojure + +(lager? yeast) +(lager? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `liquid?` [:page_facing_up:](null) + +``` clojure + +(liquid? yeast) +(liquid? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in liquid form. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `low-flocculation?` [:page_facing_up:](null) + +``` clojure + +(low-flocculation? yeast) +(low-flocculation? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a low amount of floc. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `medium-flocculation?` [:page_facing_up:](null) + +``` clojure + +(medium-flocculation? yeast) +(medium-flocculation? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `slant?` [:page_facing_up:](null) + +``` clojure + +(slant? yeast) +(slant? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. + Typically, this is a solid growth of yeast cells in a test tube. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `very-high-flocculation?` [:page_facing_up:](null) + +``` clojure + +(very-high-flocculation? yeast) +(very-high-flocculation? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `wheat?` [:page_facing_up:](null) + +``` clojure + +(wheat? yeast) +(wheat? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +## `wine?` [:page_facing_up:](null) + +``` clojure + +(wine? yeast) +(wine? yeast opts) +``` + + +A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. + + An option map can be passed to this function as an optional second parameter. + Supported keys are: + + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. + - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. + +----- +# brewtility.string + + +String comparison utilities + + + + +## `->spongebob-case` [:page_facing_up:](null) + +``` clojure + +(->spongebob-case s) +``` + + +Take a string `s` and coerce characters alternatively between lower and upper case. + + For example: + + ```clj + (->spongebob-case "spongebob") ;; => "sPoNgEbOb" + ``` + +## `->sporadic-case` [:page_facing_up:](null) + +``` clojure + +(->sporadic-case s) +``` + + +Take a string `s` and randomly coerce characters to either lower or upper case. + + For example: + + ```clj + (->sporadic-case "hello world") ;; => "hElLo wOrLd" + ``` + +## `includes?` [:page_facing_up:](null) + +``` clojure + +(includes? s1 s2) +(includes? s1 s2 opts) +``` + + +Checks to see if `s1` includes `s2` after each string has been modified by [`prepare-for-compare`](#brewtility.string/prepare-for-compare). + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false. + +## `prepare-for-compare` [:page_facing_up:](null) + +``` clojure + +(prepare-for-compare s) +(prepare-for-compare s {:keys [uppercase? coerce?]}) +``` + + +Takes a string `s`, trims it, and coerces it to lower case. + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s` will be cast to a string via `str`. Defaults to false. + +## `same?` [:page_facing_up:](null) + +``` clojure + +(same? s1 s2) +(same? s1 s2 opts) +``` + + +Checks to see if `s1` and `s2` are equal after each string has been modified by [`prepare-for-compare`](#brewtility.string/prepare-for-compare). + + An option map may be passed as an optional second argument. + The following keys are supported: + + - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. + - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false. + +----- +# brewtility.units + + +Namespace for converting between different units of measure + + + + +## `celsius->temperature-measurement` [:page_facing_up:](null) + + +A map from measurement names to the implementation function which converts them from degrees celsius + +## `convert-temperature` [:page_facing_up:](null) + +``` clojure + +(convert-temperature temperature source-measurement target-measurement) +``` + + +Given a `temperature` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[temperature-measurements]]. + + This function will throw an exception if unsupported measurement values are passed. + +## `convert-time` [:page_facing_up:](null) + +``` clojure + +(convert-time time-val source-measurement target-measurement) +``` + + +Given a `time-val` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[time-measurements]]. + + This function will throw an exception if unsupported measurement values are passed. + +## `convert-volume` [:page_facing_up:](null) + +``` clojure + +(convert-volume volume source-measurement target-measurement) +``` + + +Given a `volume` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[volume-measurements]]. + + This function will throw an exception if unsupported measurement values are passed. + +## `convert-weight` [:page_facing_up:](null) + +``` clojure + +(convert-weight weight source-measurement target-measurement) +``` + + +Given a `weight` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[weight-measurements]]. + + This function will throw an exception if unsupported measurement values are passed. + +## `suffix-types` [:page_facing_up:](null) + + +The unit suffix types available across brewtility + +## `systems-of-meaure` [:page_facing_up:](null) + + +The systems of measure available across brewtility + +## `temperature-measurement->celsius` [:page_facing_up:](null) + + +A map from measurement names to the implementation function which converts them to degrees celsius + +## `temperature-measurements` [:page_facing_up:](null) + + +The temperature measurements available across brewtility + +## `temperature-measurements->display-name` [:page_facing_up:](null) + + +A map from measurement names to their full name and abbreviation + +## `time-measurement->minute` [:page_facing_up:](null) + + +A map from measurement names to doubles representing their fractional value to one minute + +## `time-measurements` [:page_facing_up:](null) + + +The time measurements available across brewtility + +## `time-measurements->display-name` [:page_facing_up:](null) + + +A map from measurement names to their full name and abbreviation + +## `volume-measurement->litre` [:page_facing_up:](null) + + +A map from measurement names to doubles representing their fractional value to one liter + +## `volume-measurements` [:page_facing_up:](null) + + +The volume measurements available across brewtility + +## `volume-measurements->display-name` [:page_facing_up:](null) + + +A map from measurement names to their full name and abbreviation + +## `weight-measurement->kilogram` [:page_facing_up:](null) + + +A map from measurement names to doubles representing their fractional value to one kilogram + +## `weight-measurements` [:page_facing_up:](null) + + +The weight measurements available across brewtility + +## `weight-measurements->display-name` [:page_facing_up:](null) + + +A map from measurement names to their full name and abbreviation + +----- +# brewtility.wrapping + + +Namespace for wrapping and unwrapping common-beer-format maps + + + + +## `unwrap-equipment` [:page_facing_up:](null) + +``` clojure + +(unwrap-equipment equipment-wrapper) +``` + + +Unwrap an `equipment-wrapper` map into an `equipment` map. + +## `unwrap-fermentable` [:page_facing_up:](null) + +``` clojure + +(unwrap-fermentable fermentable-wrapper) +``` + + +Unwrap a `fermentable-wrapper` map into a `fermentable` map. + +## `unwrap-fermentables` [:page_facing_up:](null) + +``` clojure + +(unwrap-fermentables fermentables-wrapper) +``` + + +Unwrap a `fermentables-wrapper` map into a `fermentables` collection. + +## `unwrap-hop` [:page_facing_up:](null) + +``` clojure + +(unwrap-hop hop-wrapper) +``` + + +Unwrap a `hop-wrapper` map into a `hop` map. + +## `unwrap-hops` [:page_facing_up:](null) + +``` clojure + +(unwrap-hops hops-wrapper) +``` + + +Unwrap a `hops-wrapper` map into a `hops` collection. + +## `unwrap-mash` [:page_facing_up:](null) + +``` clojure + +(unwrap-mash mash-wrapper) +``` + + +Unwrap a `mash-wrapper` map into a `mash` map. + +## `unwrap-mash-step` [:page_facing_up:](null) + +``` clojure + +(unwrap-mash-step mash-step-wrapper) +``` + + +Unwrap a `mash-step-wrapper` map into a `mash-step` map. + +## `unwrap-mash-steps` [:page_facing_up:](null) + +``` clojure + +(unwrap-mash-steps mash-steps-wrapper) +``` + + +Unwrap a `mash-steps-wrapper` map into a `mash-steps` collection. + +## `unwrap-misc` [:page_facing_up:](null) + +``` clojure + +(unwrap-misc misc-wrapper) +``` + + +Unwrap a `misc-wrapper` map into a `misc` map. + +## `unwrap-miscs` [:page_facing_up:](null) + +``` clojure + +(unwrap-miscs miscs-wrapper) +``` + + +Unwrap a `miscs-wrapper` map into a `miscs` collection. + +## `unwrap-recipe` [:page_facing_up:](null) + +``` clojure + +(unwrap-recipe recipe-wrapper) +``` + + +Unwrap a `recipe-wrapper` map into a `recipe` map. + +## `unwrap-recipes` [:page_facing_up:](null) + +``` clojure + +(unwrap-recipes recipes-wrapper) +``` + + +Unwrap a `recipes-wrapper` map into a `recipes` collection. + +## `unwrap-style` [:page_facing_up:](null) + +``` clojure + +(unwrap-style style-wrapper) +``` + + +Unwrap a `style-wrapper` map into a `style` map. + +## `unwrap-styles` [:page_facing_up:](null) + +``` clojure + +(unwrap-styles styles-wrapper) +``` + + +Unwrap a `styles-wrapper` map into a `styles` collection. + +## `unwrap-water` [:page_facing_up:](null) + +``` clojure + +(unwrap-water water-wrapper) +``` + + +Unwrap a `water-wrapper` map into a `water` map. + +## `unwrap-waters` [:page_facing_up:](null) + +``` clojure + +(unwrap-waters waters-wrapper) +``` + + +Unwrap a `waters-wrapper` map into a `waters` collection. + +## `unwrap-yeast` [:page_facing_up:](null) + +``` clojure + +(unwrap-yeast yeast-wrapper) +``` + + +Unwrap a `yeast-wrapper` map into a `yeast` map. + +## `unwrap-yeasts` [:page_facing_up:](null) + +``` clojure + +(unwrap-yeasts yeasts-wrapper) +``` + + +Unwrap a `yeasts-wrapper` map into a `yeasts` collection. + +## `wrap-equipment` [:page_facing_up:](null) + +``` clojure + +(wrap-equipment equipment) +``` + + +Wrap an `equipment` map into an `equipment-wrapper` map. + +## `wrap-fermentable` [:page_facing_up:](null) + +``` clojure + +(wrap-fermentable fermentable) +``` + + +Wrap a `fermentable` map into a `fermentable-wrapper` map. + +## `wrap-fermentables` [:page_facing_up:](null) + +``` clojure + +(wrap-fermentables fermentables) +``` + + +Wrap a `fermentables` collection into a `fermentables-wrapper` map. + +## `wrap-hop` [:page_facing_up:](null) + +``` clojure + +(wrap-hop hop) +``` + + +Wrap a `hop` map into a `hop-wrapper` map. + +## `wrap-hops` [:page_facing_up:](null) + +``` clojure + +(wrap-hops hops) +``` + + +Wrap a `hops` collection into a `hops-wrapper` map. + +## `wrap-mash` [:page_facing_up:](null) + +``` clojure + +(wrap-mash mash) +``` + + +Wrap a `mash` map into a `mash-wrapper` map. + +## `wrap-mash-step` [:page_facing_up:](null) + +``` clojure + +(wrap-mash-step mash-step) +``` + + +Wrap a `mash-step` map into a `mash-step-wrapper` map. + +## `wrap-mash-steps` [:page_facing_up:](null) + +``` clojure + +(wrap-mash-steps mash-steps) +``` + + +Wrap a `mash-steps` collection into a `mash-steps-wrapper` map. + +## `wrap-misc` [:page_facing_up:](null) + +``` clojure + +(wrap-misc misc) +``` + + +Wrap a `misc` map into a `misc-wrapper` map. + +## `wrap-miscs` [:page_facing_up:](null) + +``` clojure + +(wrap-miscs miscs) +``` + + +Wrap a `miscs` collection into a `miscs-wrapper` map. + +## `wrap-recipe` [:page_facing_up:](null) + +``` clojure + +(wrap-recipe recipe) +``` + + +Wrap a `recipe` map into a `recipe-wrapper` map. + +## `wrap-recipes` [:page_facing_up:](null) + +``` clojure + +(wrap-recipes recipes) +``` + + +Wrap a `recipes` collection into a `recipes-wrapper` map. + +## `wrap-style` [:page_facing_up:](null) + +``` clojure + +(wrap-style style) +``` + + +Wrap a `style` map into a `style-wrapper` map. + +## `wrap-styles` [:page_facing_up:](null) + +``` clojure + +(wrap-styles styles) +``` + + +Wrap a `styles` collection into a `styles-wrapper` map. + +## `wrap-water` [:page_facing_up:](null) + +``` clojure + +(wrap-water water) +``` + + +Wrap a `water` map into a `water-wrapper` map. + +## `wrap-waters` [:page_facing_up:](null) + +``` clojure + +(wrap-waters waters) +``` + + +Wrap a `waters` collection into a `waters-wrapper` map. + +## `wrap-yeast` [:page_facing_up:](null) + +``` clojure + +(wrap-yeast yeast) +``` + + +Wrap a `yeast` map into a `yeast-wrapper` map. + +## `wrap-yeasts` [:page_facing_up:](null) + +``` clojure + +(wrap-yeasts yeasts) +``` + + +Wrap a `yeasts` collection into a `yeasts-wrapper` map. diff --git a/README.md b/README.md index d93f3ba..fbf4fe9 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![Clojars Project](https://img.shields.io/clojars/v/com.wallbrew/brewtility.svg)](https://clojars.org/com.wallbrew/brewtility) ![Clojure and ClojureScript CI](https://github.com/Wall-Brew-Co/brewtility/workflows/Clojure%20and%20ClojureScript%20CI/badge.svg) [![cljdoc badge](https://cljdoc.org/badge/com.wallbrew/brewtility)](https://cljdoc.org/d/com.wallbrew/brewtility/CURRENT) +[![GitHub](https://img.shields.io/github/license/Wall-Brew-Co/brewtility)](https://github.com/Wall-Brew-Co/brewtility/blob/master/LICENSE) +[![Twitter Follow](https://img.shields.io/twitter/follow/WallBrew?style=social)](https://twitter.com/WallBrew) A Clojure(Script) utility library for all of your brewing needs. @@ -62,6 +64,10 @@ lein test-build The tests will also execute on the JVM, to ensure the library is compatible for apps in both deployment environments. +## Contributors + +The GitHub profile pictures of all current contributors. Clicking this image will lead you to the GitHub contribution graph. + ## License Copyright © 2020-2023 - [Wall Brew Co](https://wallbrew.com/) diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index f363c4b..2d29b52 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -3,6 +3,7 @@ ["Community" {} ["Contributing" {:file "CONTRIBUTING.md"}] ["Code of Conduct" {:file "CODE_OF_CONDUCT.md"}] + ["License" {:file "LICENSE.md"}] ["Security Policy" {:file "SECURITY.md"}]] ["Functionality" {} ["Calculations" {:file "doc/api/calculations.md"}] @@ -12,4 +13,5 @@ ["Units of Measure" {:file "doc/api/units.md"}] ["Wrapping" {:file "doc/api/wrapping.md"}]] ["Adopted Patterns" {} + ["Enricher Pattern" {:file "doc/enricher-pattern.md"}] ["Symbolic Keywords" {:file "doc/patterns/symbolic_keywords.md"}]]]} diff --git a/doc/enricher-pattern.md b/doc/enricher-pattern.md index 5f1c33e..fa7478f 100644 --- a/doc/enricher-pattern.md +++ b/doc/enricher-pattern.md @@ -16,7 +16,8 @@ For a concrete example, consider a sample [equipment](https://github.com/Wall-Br In the above, you can find two representations of the pre-boil volume that piece of equipment held. By the standard, the `:boil-size` is standardized to be the volume in litres, and the `:display-boil-size` is meant to represent that value in a region and human friendly way. -This is great for users; however, it can be unweildy in applications for a few to store and transmit data which may only be used in the display layer. Programatically, we are often more interested in a smaller subset of the equipment record and will defer computing display values until they are needed. +This is great for users; however, it can be unwieldy in applications for a few to store and transmit data which may only be used in the display layer. +Programmatically, we are often more interested in a smaller subset of the equipment record and will defer computing display values until they are needed. While the unit conversion is simple, it can often lead to front-end code like this: diff --git a/doc/symbolic-keywords.md b/doc/symbolic-keywords.md new file mode 100644 index 0000000..67bc5cd --- /dev/null +++ b/doc/symbolic-keywords.md @@ -0,0 +1,51 @@ +# Symbolic Keyword Pattern + +In many clojure libraries, the behavior of complex functions may be controlled by a map. +For example: + +```clojure +(:require [brewtility.string :as b-str]) + +(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" +(sut/prepare-for-compare " 100 lines of CODE" {:uppercase? true}) ;; => "100 LINES OF CODE" +``` + +This allows us to easily extend the definition of a single function to fulfil multiple complex needs; however, option maps come with considerable drawbacks. +When a map is keyed with keywords, it is easy to introduce subtle, hard-to-detect errors. +Since most of these functions select default values for keys not present, typos can lead to large differences in behavior. +For example: + +```clojure +(:require [brewtility.string :as b-str]) + +(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" +(sut/prepare-for-compare " 100 lines of CODE" {:uppercased? true}) ;; => "100 lines of code" +``` + +Because keywords aren't picked up by the auto-complete features of most editors, they're vulnerable to all classes of transpositional errors. +Further, the options themselves are unable to carry metadata and documentation with them, making them little more than magic values. + +For this reason, it is often helpful for libraries to include symbols which point to the magic keywords used in option maps. +This has several benefits: + +- Misspelled or incorrect options are compile-time errors, instead of runtime bugs +- Symbols can carry metadata like documentation, deprecation notices, and point to alternative options +- Context-aware editors can auto-complete options + +Here's can example: + +```clojure +(:require [brewtility.string :as b-str]) + +(def compare-with-uppercase? + "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. + This option will be enabled if this key's value is truthy." + :uppercase?) + +(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" +(sut/prepare-for-compare " 100 lines of CODE" {compare-with-uppercase? true}) ;; => "100 LINES OF CODE" +``` + +Most option maps in `brewtility` support symbolic keywords. +Options relevant to only one namespace are colocated with the functionality they control. +High-level options which control behavior throughout brewtility can be found in `brewtility.static`. diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 85b9db3..fb4ce4e 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -24,7 +24,7 @@ "enrich-fermentables" "enrich-fermentables-wrapper"]} ([fermentable] (enrich-add-after-boil fermentable {})) - ([fermentable _opts] + ([fermentable _opts] ;; Used to maintain signature parity with enricher pattern functions (if (contains? fermentable :add-after-boil) fermentable (assoc fermentable :add-after-boil false)))) diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc new file mode 100644 index 0000000..30f7892 --- /dev/null +++ b/src/brewtility/enrich/miscs.cljc @@ -0,0 +1,261 @@ +(ns brewtility.enrich.miscs + "Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.fermentables" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + + +(defn enrich-amount-is-weight + "An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. + When this feild is not present, it is assumed to be false." + {:added "1.3" + :see-also ["enrich-misc" + "enrich-misc-wrapper" + "enrich-miscs" + "enrich-miscs-wrapper"]} + ([misc] (enrich-amount-is-weight misc {})) + ([misc _] ;; Used to maintain signature parity with enricher pattern functions + (if (contains? misc :amount-is-weight) + misc + (assoc misc :amount-is-weight false)))) + + +(defn enrich-display-time + "An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-misc` and `enrich-misc-wrapper`, this function also supports the following keys: + - `:misc-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:misc-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-misc" + "enrich-misc-wrapper" + "enrich-miscs" + "enrich-miscs-wrapper"]} + ([misc] (enrich-display-time misc {})) + ([misc {:keys [misc-time-target-units + misc-time-precision + misc-time-suffix] + :as opts}] + (let [options (merge opts {:value-key :time + :display-key :display-time + :fine-grain-target-units misc-time-target-units + :fine-grain-precision misc-time-precision + :fine-grain-suffix misc-time-suffix})] + (impl/enrich-displayable-time misc options)))) + + +(defn enrich-display-amount + "An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. + Otherwise, it will be treated as a volume in liters. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-misc` and `enrich-misc-wrapper`, this function also supports the following keys: + - `:misc-amount-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the time. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-misc" + "enrich-misc-wrapper" + "enrich-miscs" + "enrich-miscs-wrapper"]} + ([misc] (enrich-display-amount misc {})) + ([misc {:keys [misc-time-target-units + misc-time-precision + misc-time-suffix] + :as opts}] + (let [options (merge opts {:value-key :time + :display-key :display-time + :fine-grain-target-units misc-time-target-units + :fine-grain-precision misc-time-precision + :fine-grain-suffix misc-time-suffix})] + (if (:amount-is-weight misc) + (impl/enrich-displayable-weight misc options) + (impl/enrich-displayable-volume misc options))))) + + + + +(defn enrich-misc + "An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-amount-is-weight" + "enrich-misc-wrapper" + "enrich-miscs" + "enrich-miscs-wrapper"]} + ([misc] (enrich-misc misc {})) + ([misc opts] + (-> misc + (enrich-amount-is-weight opts) + (enrich-display-amount opts) + (enrich-display-time opts)))) + + +(defn enrich-misc-wrapper + "An enricher pattern function to derive as many values from an [misc-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-amount-is-weight" + "enrich-misc" + "enrich-miscs" + "enrich-miscs-wrapper"]} + ([misc] (enrich-misc-wrapper misc {})) + ([misc opts] + (update misc :misc enrich-misc opts))) + + +(defn enrich-miscs + "An enricher pattern function to derive as many values from an [miscs record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-amount-is-weight" + "enrich-misc-wrapper" + "enrich-misc" + "enrich-miscs-wrapper"]} + ([miscs] (enrich-miscs miscs {})) + ([miscs opts] + (map #(enrich-misc-wrapper % opts) miscs))) + + +(defn enrich-miscs-wrapper + "An enricher pattern function to derive as many values from an [miscs-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-time]] + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-display-time" + "enrich-amount-is-weight" + "enrich-misc-wrapper" + "enrich-miscs" + "enrich-misc"]} + ([miscs] (enrich-miscs-wrapper miscs {})) + ([miscs opts] + (update miscs :miscs enrich-miscs opts))) + diff --git a/src/brewtility/static.cljc b/src/brewtility/static.cljc new file mode 100644 index 0000000..e7c6e87 --- /dev/null +++ b/src/brewtility/static.cljc @@ -0,0 +1,3 @@ +(ns brewtility.static + "A namespace of static symbolic keywords and values used in the option maps throughout brewtility." + {:added "1.3"}) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index 821d1d0..b75bd3f 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -4,6 +4,21 @@ (:require [clojure.string :as str])) +#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} +(def cast-to-uppercase? + "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. + Commonly, this is set for the `options` argument of `same?` and `includes?`. + This option will be enabled if this key's value is truthy, and is disabled by default." + :uppercase?) + +#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} +(def coerce-to-compare? + "An option map key to coerce values to strings in `prepare-for-compare`. + Commonly, this is set for the `options` argument of `same?` and `includes?`. + This option will be enabled if this key's value is truthy, and is disabled by default." + :coerce?) + + (defn prepare-for-compare "Takes a string `s`, trims it, and coerces it to lower case. @@ -13,7 +28,10 @@ - `:uppercase?` - If true, `s` will be coerced to upper case. Defaults to false. - `:coerce?` - If true, `s` will be cast to a string via `str`. Defaults to false." {:added "1.3" - :see-also ["same?" "includes?"]} + :see-also ["same?" + "includes?" + "cast-to-uppercase?" + "coerce-to-compare?"]} ([s] (prepare-for-compare s {})) ([s {:keys [uppercase? coerce?]}] @@ -31,7 +49,10 @@ - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." {:added "1.3" - :see-also ["includes?" "prepare-for-compare"]} + :see-also ["includes?" + "prepare-for-compare" + "cast-to-uppercase?" + "coerce-to-compare?"]} ([s1 s2] (same? s1 s2 {})) ([s1 s2 opts] @@ -48,7 +69,10 @@ - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." {:added "1.3" - :see-also ["includes?" "prepare-for-compare"]} + :see-also ["includes?" + "prepare-for-compare" + "cast-to-uppercase?" + "coerce-to-compare?"]} ([s1 s2] (includes? s1 s2 {})) ([s1 s2 opts] diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc index e4ea9f1..5b38844 100644 --- a/test/brewtility/string_test.cljc +++ b/test/brewtility/string_test.cljc @@ -14,10 +14,13 @@ (testing "Strings are appropriately re-cased and trimmed of whitespace" (is (= "" (sut/prepare-for-compare " "))) (is (= "clojure" (sut/prepare-for-compare "ClOjUrE "))) + (is (= "clojure" (sut/prepare-for-compare "ClOjUrE " {:uppercase? false}))) + (is (= "clojure" (sut/prepare-for-compare "ClOjUrE " {sut/cast-to-uppercase? false}))) (is (= "clojure" (sut/prepare-for-compare "clojure"))) (is (= "100 lines of code" (sut/prepare-for-compare " 100 lines of CODE"))) (is (= "a b" (sut/prepare-for-compare " a b "))) (is (= "CLOJURE" (sut/prepare-for-compare "ClOjUrE " {:uppercase? true}))) + (is (= "CLOJURE" (sut/prepare-for-compare "ClOjUrE " {sut/cast-to-uppercase? true}))) (is (= "CLOJURE" (sut/prepare-for-compare "clojure" {:uppercase? true}))) (is (= "100 LINES OF CODE" (sut/prepare-for-compare " 100 lines of CODE" {:uppercase? true}))) (is (= "A B" (sut/prepare-for-compare " a b " {:uppercase? true}))) From 35aa980852274821c74255cf1efcd61c7c0b2081 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 7 Jan 2023 19:40:50 +0000 Subject: [PATCH 14/44] Use spoon as source of string functions --- API.md | 4102 ----------------- src/brewtility/string.cljc | 40 - test/brewtility/data/recipes.cljc | 13 +- test/brewtility/data/yeasts.cljc | 1 + test/brewtility/enrich/fermentables_test.cljc | 36 +- test/brewtility/enrich/hops_test.cljc | 30 +- test/brewtility/enrich/mash_test.cljc | 50 +- test/brewtility/string_test.cljc | 22 - 8 files changed, 66 insertions(+), 4228 deletions(-) delete mode 100644 API.md diff --git a/API.md b/API.md deleted file mode 100644 index 8a14a3f..0000000 --- a/API.md +++ /dev/null @@ -1,4102 +0,0 @@ -# Table of contents -- [`brewtility.calculations`](#brewtility.calculations) - Namespace for handling recipe calculations. - - [`calculate-alpha-acid-units`](#brewtility.calculations/calculate-alpha-acid-units) - Calculate the maximum amount of alpha acid released by weight ounce of a hop at percent alpha acid. - - [`calculate-ebc-color`](#brewtility.calculations/calculate-ebc-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the EBC color for a recipe. - - [`calculate-equipment-boil-volume`](#brewtility.calculations/calculate-equipment-boil-volume) - Given a common-beer-format conforming equipment, calculate the volume of the wort at the start of the boil. - - [`calculate-hop-utilization`](#brewtility.calculations/calculate-hop-utilization) - Calculate the percentage of alpha acid that a hop could release over boil-duration in a wort at a specific gravity Based on: http://howtobrew.com/book/section-1/hops/hop-bittering-calculations. - - [`calculate-ibu-per-hop`](#brewtility.calculations/calculate-ibu-per-hop) - Given a common-beer-format conforming hop, batch-size, and potential-gravity, calculate the amount of IBUs generated. - - [`calculate-lovibond-color`](#brewtility.calculations/calculate-lovibond-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the color in degrees Lovibond for a recipe. - - [`calculate-malt-color-units`](#brewtility.calculations/calculate-malt-color-units) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the overall Malt Color Units for a recipe. - - [`calculate-potential-abv`](#brewtility.calculations/calculate-potential-abv) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, estimate the ABV. - - [`calculate-potential-final-gravity`](#brewtility.calculations/calculate-potential-final-gravity) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, estimate the Final Gravity. - - [`calculate-potential-gravity`](#brewtility.calculations/calculate-potential-gravity) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, calculate the potential original gravity. - - [`calculate-recipe-ibus`](#brewtility.calculations/calculate-recipe-ibus) - Given a collection of common-beer-format conforming hops, batch-size, and potential-gravity calculate the amount of IBUs generated. - - [`calculate-rgba-color`](#brewtility.calculations/calculate-rgba-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the RGBA color for a recipe. - - [`calculate-srm-color`](#brewtility.calculations/calculate-srm-color) - Given a collection of common-beer-format conforming fermentables, and a conformed batch-size in liters, return the SRM color for a recipe. - - [`default-attenuation`](#brewtility.calculations/default-attenuation) - A constant backup attenuation for calculations. - - [`gravity->abv-multiplier`](#brewtility.calculations/gravity->abv-multiplier) - The constanct factor used to calculate ABV from potential gravity. - - [`gravity-points->potential-gravity`](#brewtility.calculations/gravity-points->potential-gravity) - Given the gravity-points of a recipe, and the volume of the batch, calculate the potential gravity. - - [`potential-gravity->gravity-points`](#brewtility.calculations/potential-gravity->gravity-points) - Given the potential-gravity of a fermentable, and the weight of the fermentable, calculate gravity points. -- [`brewtility.color`](#brewtility.color) - Namespace for calculating beer colors. - - [`color-system->display-name`](#brewtility.color/color-system->display-name) - A map from color system names to their full and short unit names. - - [`color-systems`](#brewtility.color/color-systems) - The color systems available across brewtility. - - [`ebc->lovibond`](#brewtility.color/ebc->lovibond) - Convert the color described in 'ebc` to the equivalent degrees Lovibond. - - [`ebc->rgba`](#brewtility.color/ebc->rgba) - Given ebc-number, return the closest, bounded applicable RGBA color string. - - [`ebc->srm`](#brewtility.color/ebc->srm) - Convert the color described by the ebc to the equivalent SRM color. - - [`lovibond->ebc`](#brewtility.color/lovibond->ebc) - Convert the color described in degrees 'lovibond` to the equivalent EBC color. - - [`lovibond->rgba`](#brewtility.color/lovibond->rgba) - Given lovibond-number, return the closest, bounded applicable RGBA color string. - - [`lovibond->srm`](#brewtility.color/lovibond->srm) - Convert the color described in degrees lovibond to the equivalent SRM color. - - [`srm-1`](#brewtility.color/srm-1) - An SRM of 1 mapped to an RGBa color code. - - [`srm-10`](#brewtility.color/srm-10) - An SRM of 10 mapped to an RGBa color code. - - [`srm-11`](#brewtility.color/srm-11) - An SRM of 11 mapped to an RGBa color code. - - [`srm-12`](#brewtility.color/srm-12) - An SRM of 12 mapped to an RGBa color code. - - [`srm-13`](#brewtility.color/srm-13) - An SRM of 13 mapped to an RGBa color code. - - [`srm-14`](#brewtility.color/srm-14) - An SRM of 14 mapped to an RGBa color code. - - [`srm-15`](#brewtility.color/srm-15) - An SRM of 15 mapped to an RGBa color code. - - [`srm-16`](#brewtility.color/srm-16) - An SRM of 16 mapped to an RGBa color code. - - [`srm-17`](#brewtility.color/srm-17) - An SRM of 17 mapped to an RGBa color code. - - [`srm-18`](#brewtility.color/srm-18) - An SRM of 18 mapped to an RGBa color code. - - [`srm-19`](#brewtility.color/srm-19) - An SRM of 19 mapped to an RGBa color code. - - [`srm-2`](#brewtility.color/srm-2) - An SRM of 2 mapped to an RGBa color code. - - [`srm-20`](#brewtility.color/srm-20) - An SRM of 20 mapped to an RGBa color code. - - [`srm-21`](#brewtility.color/srm-21) - An SRM of 21 mapped to an RGBa color code. - - [`srm-22`](#brewtility.color/srm-22) - An SRM of 22 mapped to an RGBa color code. - - [`srm-23`](#brewtility.color/srm-23) - An SRM of 23 mapped to an RGBa color code. - - [`srm-24`](#brewtility.color/srm-24) - An SRM of 24 mapped to an RGBa color code. - - [`srm-25`](#brewtility.color/srm-25) - An SRM of 25 mapped to an RGBa color code. - - [`srm-26`](#brewtility.color/srm-26) - An SRM of 26 mapped to an RGBa color code. - - [`srm-27`](#brewtility.color/srm-27) - An SRM of 27 mapped to an RGBa color code. - - [`srm-28`](#brewtility.color/srm-28) - An SRM of 28 mapped to an RGBa color code. - - [`srm-29`](#brewtility.color/srm-29) - An SRM of 29 mapped to an RGBa color code. - - [`srm-3`](#brewtility.color/srm-3) - An SRM of 3 mapped to an RGBa color code. - - [`srm-30`](#brewtility.color/srm-30) - An SRM of 30 mapped to an RGBa color code. - - [`srm-31`](#brewtility.color/srm-31) - An SRM of 31 mapped to an RGBa color code. - - [`srm-32`](#brewtility.color/srm-32) - An SRM of 32 mapped to an RGBa color code. - - [`srm-33`](#brewtility.color/srm-33) - An SRM of 33 mapped to an RGBa color code. - - [`srm-34`](#brewtility.color/srm-34) - An SRM of 34 mapped to an RGBa color code. - - [`srm-35`](#brewtility.color/srm-35) - An SRM of 35 mapped to an RGBa color code. - - [`srm-36`](#brewtility.color/srm-36) - An SRM of 36 mapped to an RGBa color code. - - [`srm-37`](#brewtility.color/srm-37) - An SRM of 37 mapped to an RGBa color code. - - [`srm-38`](#brewtility.color/srm-38) - An SRM of 38 mapped to an RGBa color code. - - [`srm-39`](#brewtility.color/srm-39) - An SRM of 39 mapped to an RGBa color code. - - [`srm-4`](#brewtility.color/srm-4) - An SRM of 4 mapped to an RGBa color code. - - [`srm-40`](#brewtility.color/srm-40) - An SRM of 40 mapped to an RGBa color code. - - [`srm-5`](#brewtility.color/srm-5) - An SRM of 5 mapped to an RGBa color code. - - [`srm-6`](#brewtility.color/srm-6) - An SRM of 6 mapped to an RGBa color code. - - [`srm-7`](#brewtility.color/srm-7) - An SRM of 7 mapped to an RGBa color code. - - [`srm-8`](#brewtility.color/srm-8) - An SRM of 8 mapped to an RGBa color code. - - [`srm-9`](#brewtility.color/srm-9) - An SRM of 9 mapped to an RGBa color code. - - [`srm->ebc`](#brewtility.color/srm->ebc) - Convert the color described by the srm to the equivalent EBC color. - - [`srm->lovibond`](#brewtility.color/srm->lovibond) - Convert the color described in 'srm` to the equivalent degrees Lovibond. - - [`srm->rgba`](#brewtility.color/srm->rgba) - Given srm-number, return the closest, bounded applicable RGBA color string. - - [`srm-color-map`](#brewtility.color/srm-color-map) - A map of integer values to their closest SRM value as an RGBa color code. -- [`brewtility.enrich.equipment`](#brewtility.enrich.equipment) - Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps. - - [`enrich-calculated-boil-size`](#brewtility.enrich.equipment/enrich-calculated-boil-size) - An enricher pattern function to calculate the boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record via [[brewtility.calculations/calculate-equipment-boil-volume]]. - - [`enrich-display-batch-size`](#brewtility.enrich.equipment/enrich-display-batch-size) - An enricher pattern function to add the displayable batch size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-boil-size`](#brewtility.enrich.equipment/enrich-display-boil-size) - An enricher pattern function to add the displayable boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-lauter-deadspace`](#brewtility.enrich.equipment/enrich-display-lauter-deadspace) - An enricher pattern function to add the displayable lauter deadspace to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-top-up-kettle`](#brewtility.enrich.equipment/enrich-display-top-up-kettle) - An enricher pattern function to add the displayable top up kettle to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-top-up-water`](#brewtility.enrich.equipment/enrich-display-top-up-water) - An enricher pattern function to add the displayable top up water to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-trub-chiller-loss`](#brewtility.enrich.equipment/enrich-display-trub-chiller-loss) - An enricher pattern function to add the displayable trub chiller loss to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-tun-volume`](#brewtility.enrich.equipment/enrich-display-tun-volume) - An enricher pattern function to add the displayable tun volume to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-display-tun-weight`](#brewtility.enrich.equipment/enrich-display-tun-weight) - An enricher pattern function to add the displayable tun weight to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) - An enricher pattern function to derive as many values from an [equipment record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). - - [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper) - An enricher pattern function to derive as many values from an [equipment-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). -- [`brewtility.enrich.fermentables`](#brewtility.enrich.fermentables) - Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps. - - [`enrich-add-after-boil`](#brewtility.enrich.fermentables/enrich-add-after-boil) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. - - [`enrich-coarse-fine-diff`](#brewtility.enrich.fermentables/enrich-coarse-fine-diff) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a coarse/fine differential. - - [`enrich-diastatic-power`](#brewtility.enrich.fermentables/enrich-diastatic-power) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a listed Diastatic Power. - - [`enrich-display-amount`](#brewtility.enrich.fermentables/enrich-display-amount) - An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. - - [`enrich-display-color`](#brewtility.enrich.fermentables/enrich-display-color) - An enricher pattern function to determine what color a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. - - [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) - An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper) - An enricher pattern function to derive as many values from an [fermentable-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - [`enrich-fermentables`](#brewtility.enrich.fermentables/enrich-fermentables) - An enricher pattern function to derive as many values from an [fermentables record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - [`enrich-fermentables-wrapper`](#brewtility.enrich.fermentables/enrich-fermentables-wrapper) - An enricher pattern function to derive as many values from an [fermentables-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - [`enrich-ibu-gallons-per-pound`](#brewtility.enrich.fermentables/enrich-ibu-gallons-per-pound) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. - - [`enrich-moisture`](#brewtility.enrich.fermentables/enrich-moisture) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a moisture content. - - [`enrich-protein`](#brewtility.enrich.fermentables/enrich-protein) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have protein. - - [`enrich-recommend-mash`](#brewtility.enrich.fermentables/enrich-recommend-mash) - An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. -- [`brewtility.enrich.hops`](#brewtility.enrich.hops) - Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps. - - [`enrich-display-amount`](#brewtility.enrich.hops/enrich-display-amount) - An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. - - [`enrich-display-time`](#brewtility.enrich.hops/enrich-display-time) - An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. - - [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) - An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper) - An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - [`enrich-hops`](#brewtility.enrich.hops/enrich-hops) - An enricher pattern function to derive as many values from an [hops record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - [`enrich-hops-wrapper`](#brewtility.enrich.hops/enrich-hops-wrapper) - An enricher pattern function to derive as many values from an [hops-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). -- [`brewtility.enrich.mash`](#brewtility.enrich.mash) - Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps. - - [`enrich-display-grain-temperature`](#brewtility.enrich.mash/enrich-display-grain-temperature) - An enricher pattern function to render a human-readable temperature of the grain temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-display-infuse-amount`](#brewtility.enrich.mash/enrich-display-infuse-amount) - An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-display-sparge-temperature`](#brewtility.enrich.mash/enrich-display-sparge-temperature) - An enricher pattern function to render a human-readable temperature of the sparge temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-display-step-temperature`](#brewtility.enrich.mash/enrich-display-step-temperature) - An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-display-tun-temperature`](#brewtility.enrich.mash/enrich-display-tun-temperature) - An enricher pattern function to render a human-readable temperature of the tun temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-display-tun-weight`](#brewtility.enrich.mash/enrich-display-tun-weight) - An enricher pattern function to render a human-readable weight of the tun weight during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - [`enrich-mash`](#brewtility.enrich.mash/enrich-mash) - An enricher pattern function to derive as many values from an [mash record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) - An enricher pattern function to derive as many values from an [mash-step record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper) - An enricher pattern function to derive as many values from an [mash-step wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - [`enrich-mash-steps`](#brewtility.enrich.mash/enrich-mash-steps) - An enricher pattern function to derive as many values from a collection of [mash-step wrapper records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - [`enrich-mash-steps-wrapper`](#brewtility.enrich.mash/enrich-mash-steps-wrapper) - An enricher pattern function to derive as many values from a collection of [mash-steps wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - [`enrich-mash-wrapper`](#brewtility.enrich.mash/enrich-mash-wrapper) - An enricher pattern function to derive as many values from an [mash wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). -- [`brewtility.enrich.miscs`](#brewtility.enrich.miscs) - Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps. - - [`enrich-amount-is-weight`](#brewtility.enrich.miscs/enrich-amount-is-weight) - An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. - - [`enrich-display-amount`](#brewtility.enrich.miscs/enrich-display-amount) - An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. - - [`enrich-display-time`](#brewtility.enrich.miscs/enrich-display-time) - An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. - - [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) - An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper) - An enricher pattern function to derive as many values from an [misc-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - [`enrich-miscs`](#brewtility.enrich.miscs/enrich-miscs) - An enricher pattern function to derive as many values from an [miscs record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - [`enrich-miscs-wrapper`](#brewtility.enrich.miscs/enrich-miscs-wrapper) - An enricher pattern function to derive as many values from an [miscs-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). -- [`brewtility.precision`](#brewtility.precision) - Namespace for handling numeric precision. - - [`->1dp`](#brewtility.precision/->1dp) - Given a decimal x, returns that number rounded to one decimal place. - - [`->2dp`](#brewtility.precision/->2dp) - Given a decimal x, returns that number rounded to two decimal places. - - [`->3dp`](#brewtility.precision/->3dp) - Given a decimal x, returns that number rounded to three decimal places. - - [`->precision`](#brewtility.precision/->precision) - Given a decimal x and the number of decimal places, returns that number rounded to num-decimals precision. - - [`approximates?`](#brewtility.precision/approximates?) - Determine if n2 approximates n1 within variance percent. -- [`brewtility.predicates.equipment`](#brewtility.predicates.equipment) - Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps. - - [`calculated-boil-volume?`](#brewtility.predicates.equipment/calculated-boil-volume?) - A predicate function to determine if an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) had its boil volume calculated. -- [`brewtility.predicates.fermentables`](#brewtility.predicates.fermentables) - Predicate functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps. - - [`add-after-boil?`](#brewtility.predicates.fermentables/add-after-boil?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the start of the boil. - - [`adjunct?`](#brewtility.predicates.fermentables/adjunct?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is an adjunct, non-standard fermentable. - - [`dry-extract?`](#brewtility.predicates.fermentables/dry-extract?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is dried malt extract. - - [`extract?`](#brewtility.predicates.fermentables/extract?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a liquid malt extract. - - [`grain?`](#brewtility.predicates.fermentables/grain?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is whole grain. - - [`sugar?`](#brewtility.predicates.fermentables/sugar?) - A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a raw sugar. -- [`brewtility.predicates.hops`](#brewtility.predicates.hops) - Predicate functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps. - - [`aroma-type?`](#brewtility.predicates.hops/aroma-type?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for aroma. - - [`aroma-use?`](#brewtility.predicates.hops/aroma-use?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added at the end of the boil for aroma. - - [`bittering?`](#brewtility.predicates.hops/bittering?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for bittering. - - [`boil?`](#brewtility.predicates.hops/boil?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used during the boil. - - [`both?`](#brewtility.predicates.hops/both?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for both bittering and aroma. - - [`dry-hop?`](#brewtility.predicates.hops/dry-hop?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used as a dry-hop addition in secondary fermentation. - - [`first-wort?`](#brewtility.predicates.hops/first-wort?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added to the wort at the first possible moment. - - [`leaf?`](#brewtility.predicates.hops/leaf?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a whole hop cone. - - [`mash?`](#brewtility.predicates.hops/mash?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added during the mash and before the boil. - - [`pellet?`](#brewtility.predicates.hops/pellet?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed pellet. - - [`plug?`](#brewtility.predicates.hops/plug?) - A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed whole-hop plug. -- [`brewtility.predicates.mash`](#brewtility.predicates.mash) - Predicate functions for [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps. - - [`adjust-for-equipment?`](#brewtility.predicates.mash/adjust-for-equipment?) - A predicate function to determine if a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) should account for any temperature effects of the equipment used. - - [`decoction?`](#brewtility.predicates.mash/decoction?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to extract and concentrate flavor. - - [`infusion?`](#brewtility.predicates.mash/infusion?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used as a basic infusion. - - [`temperature?`](#brewtility.predicates.mash/temperature?) - A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to bring wort up to temperature. -- [`brewtility.predicates.miscs`](#brewtility.predicates.miscs) - Predicate functions for [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps. - - [`boil?`](#brewtility.predicates.miscs/boil?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the boil. - - [`bottling?`](#brewtility.predicates.miscs/bottling?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during bottle conditioning. - - [`fining?`](#brewtility.predicates.miscs/fining?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. - - [`flavor?`](#brewtility.predicates.miscs/flavor?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is added for flavor. - - [`herb?`](#brewtility.predicates.miscs/herb?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a herb. - - [`mash?`](#brewtility.predicates.miscs/mash?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the mash. - - [`other?`](#brewtility.predicates.miscs/other?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is an unspecified type. - - [`primary?`](#brewtility.predicates.miscs/primary?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the primary fermentation. - - [`secondary?`](#brewtility.predicates.miscs/secondary?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the secondary fermentation. - - [`spice?`](#brewtility.predicates.miscs/spice?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a spice. - - [`water-agent?`](#brewtility.predicates.miscs/water-agent?) - A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a water agent. -- [`brewtility.predicates.recipes`](#brewtility.predicates.recipes) - Predicate functions for [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) maps. - - [`all-grain?`](#brewtility.predicates.recipes/all-grain?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made entirely of grain. - - [`extract?`](#brewtility.predicates.recipes/extract?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made with extract only. - - [`forced-carbonation?`](#brewtility.predicates.recipes/forced-carbonation?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was forcefully carbonated. - - [`garetz?`](#brewtility.predicates.recipes/garetz?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the garetz method. - - [`partial-mash?`](#brewtility.predicates.recipes/partial-mash?) - A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was partially mashed. - - [`rager?`](#brewtility.predicates.recipes/rager?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the Rager method. - - [`tinseth?`](#brewtility.predicates.recipes/tinseth?) - A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the tinseth method. -- [`brewtility.predicates.styles`](#brewtility.predicates.styles) - Predicate functions for [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps. - - [`ale?`](#brewtility.predicates.styles/ale?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. - - [`cider?`](#brewtility.predicates.styles/cider?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ciders. - - [`lager?`](#brewtility.predicates.styles/lager?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for lagers. - - [`mead?`](#brewtility.predicates.styles/mead?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for meads. - - [`mixed?`](#brewtility.predicates.styles/mixed?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for blended/mixed beers. - - [`wheat?`](#brewtility.predicates.styles/wheat?) - A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for wheat beers. -- [`brewtility.predicates.waters`](#brewtility.predicates.waters) - Predicate functions for [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps. - - [`acidic?`](#brewtility.predicates.waters/acidic?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is acidic. - - [`alkaline?`](#brewtility.predicates.waters/alkaline?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. - - [`neutral?`](#brewtility.predicates.waters/neutral?) - A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. -- [`brewtility.predicates.yeasts`](#brewtility.predicates.yeasts) - Predicate functions for [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps. - - [`ale?`](#brewtility.predicates.yeasts/ale?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for ale. - - [`champagne?`](#brewtility.predicates.yeasts/champagne?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. - - [`culture?`](#brewtility.predicates.yeasts/culture?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. - - [`dry?`](#brewtility.predicates.yeasts/dry?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. - - [`high-flocculation?`](#brewtility.predicates.yeasts/high-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. - - [`lager?`](#brewtility.predicates.yeasts/lager?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. - - [`liquid?`](#brewtility.predicates.yeasts/liquid?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in liquid form. - - [`low-flocculation?`](#brewtility.predicates.yeasts/low-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a low amount of floc. - - [`medium-flocculation?`](#brewtility.predicates.yeasts/medium-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. - - [`slant?`](#brewtility.predicates.yeasts/slant?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. - - [`very-high-flocculation?`](#brewtility.predicates.yeasts/very-high-flocculation?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. - - [`wheat?`](#brewtility.predicates.yeasts/wheat?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. - - [`wine?`](#brewtility.predicates.yeasts/wine?) - A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. -- [`brewtility.string`](#brewtility.string) - String comparison utilities. - - [`->spongebob-case`](#brewtility.string/->spongebob-case) - Take a string s and coerce characters alternatively between lower and upper case. - - [`->sporadic-case`](#brewtility.string/->sporadic-case) - Take a string s and randomly coerce characters to either lower or upper case. - - [`includes?`](#brewtility.string/includes?) - Checks to see if s1 includes s2 after each string has been modified by prepare-for-compare. - - [`prepare-for-compare`](#brewtility.string/prepare-for-compare) - Takes a string s, trims it, and coerces it to lower case. - - [`same?`](#brewtility.string/same?) - Checks to see if s1 and s2 are equal after each string has been modified by prepare-for-compare. -- [`brewtility.units`](#brewtility.units) - Namespace for converting between different units of measure. - - [`celsius->temperature-measurement`](#brewtility.units/celsius->temperature-measurement) - A map from measurement names to the implementation function which converts them from degrees celsius. - - [`convert-temperature`](#brewtility.units/convert-temperature) - Given a temperature in source-measurement, convert it to the target-measurement. - - [`convert-time`](#brewtility.units/convert-time) - Given a time-val in source-measurement, convert it to the target-measurement. - - [`convert-volume`](#brewtility.units/convert-volume) - Given a volume in source-measurement, convert it to the target-measurement. - - [`convert-weight`](#brewtility.units/convert-weight) - Given a weight in source-measurement, convert it to the target-measurement. - - [`suffix-types`](#brewtility.units/suffix-types) - The unit suffix types available across brewtility. - - [`systems-of-meaure`](#brewtility.units/systems-of-meaure) - The systems of measure available across brewtility. - - [`temperature-measurement->celsius`](#brewtility.units/temperature-measurement->celsius) - A map from measurement names to the implementation function which converts them to degrees celsius. - - [`temperature-measurements`](#brewtility.units/temperature-measurements) - The temperature measurements available across brewtility. - - [`temperature-measurements->display-name`](#brewtility.units/temperature-measurements->display-name) - A map from measurement names to their full name and abbreviation. - - [`time-measurement->minute`](#brewtility.units/time-measurement->minute) - A map from measurement names to doubles representing their fractional value to one minute. - - [`time-measurements`](#brewtility.units/time-measurements) - The time measurements available across brewtility. - - [`time-measurements->display-name`](#brewtility.units/time-measurements->display-name) - A map from measurement names to their full name and abbreviation. - - [`volume-measurement->litre`](#brewtility.units/volume-measurement->litre) - A map from measurement names to doubles representing their fractional value to one liter. - - [`volume-measurements`](#brewtility.units/volume-measurements) - The volume measurements available across brewtility. - - [`volume-measurements->display-name`](#brewtility.units/volume-measurements->display-name) - A map from measurement names to their full name and abbreviation. - - [`weight-measurement->kilogram`](#brewtility.units/weight-measurement->kilogram) - A map from measurement names to doubles representing their fractional value to one kilogram. - - [`weight-measurements`](#brewtility.units/weight-measurements) - The weight measurements available across brewtility. - - [`weight-measurements->display-name`](#brewtility.units/weight-measurements->display-name) - A map from measurement names to their full name and abbreviation. -- [`brewtility.wrapping`](#brewtility.wrapping) - Namespace for wrapping and unwrapping common-beer-format maps. - - [`unwrap-equipment`](#brewtility.wrapping/unwrap-equipment) - Unwrap an equipment-wrapper map into an equipment map. - - [`unwrap-fermentable`](#brewtility.wrapping/unwrap-fermentable) - Unwrap a fermentable-wrapper map into a fermentable map. - - [`unwrap-fermentables`](#brewtility.wrapping/unwrap-fermentables) - Unwrap a fermentables-wrapper map into a fermentables collection. - - [`unwrap-hop`](#brewtility.wrapping/unwrap-hop) - Unwrap a hop-wrapper map into a hop map. - - [`unwrap-hops`](#brewtility.wrapping/unwrap-hops) - Unwrap a hops-wrapper map into a hops collection. - - [`unwrap-mash`](#brewtility.wrapping/unwrap-mash) - Unwrap a mash-wrapper map into a mash map. - - [`unwrap-mash-step`](#brewtility.wrapping/unwrap-mash-step) - Unwrap a mash-step-wrapper map into a mash-step map. - - [`unwrap-mash-steps`](#brewtility.wrapping/unwrap-mash-steps) - Unwrap a mash-steps-wrapper map into a mash-steps collection. - - [`unwrap-misc`](#brewtility.wrapping/unwrap-misc) - Unwrap a misc-wrapper map into a misc map. - - [`unwrap-miscs`](#brewtility.wrapping/unwrap-miscs) - Unwrap a miscs-wrapper map into a miscs collection. - - [`unwrap-recipe`](#brewtility.wrapping/unwrap-recipe) - Unwrap a recipe-wrapper map into a recipe map. - - [`unwrap-recipes`](#brewtility.wrapping/unwrap-recipes) - Unwrap a recipes-wrapper map into a recipes collection. - - [`unwrap-style`](#brewtility.wrapping/unwrap-style) - Unwrap a style-wrapper map into a style map. - - [`unwrap-styles`](#brewtility.wrapping/unwrap-styles) - Unwrap a styles-wrapper map into a styles collection. - - [`unwrap-water`](#brewtility.wrapping/unwrap-water) - Unwrap a water-wrapper map into a water map. - - [`unwrap-waters`](#brewtility.wrapping/unwrap-waters) - Unwrap a waters-wrapper map into a waters collection. - - [`unwrap-yeast`](#brewtility.wrapping/unwrap-yeast) - Unwrap a yeast-wrapper map into a yeast map. - - [`unwrap-yeasts`](#brewtility.wrapping/unwrap-yeasts) - Unwrap a yeasts-wrapper map into a yeasts collection. - - [`wrap-equipment`](#brewtility.wrapping/wrap-equipment) - Wrap an equipment map into an equipment-wrapper map. - - [`wrap-fermentable`](#brewtility.wrapping/wrap-fermentable) - Wrap a fermentable map into a fermentable-wrapper map. - - [`wrap-fermentables`](#brewtility.wrapping/wrap-fermentables) - Wrap a fermentables collection into a fermentables-wrapper map. - - [`wrap-hop`](#brewtility.wrapping/wrap-hop) - Wrap a hop map into a hop-wrapper map. - - [`wrap-hops`](#brewtility.wrapping/wrap-hops) - Wrap a hops collection into a hops-wrapper map. - - [`wrap-mash`](#brewtility.wrapping/wrap-mash) - Wrap a mash map into a mash-wrapper map. - - [`wrap-mash-step`](#brewtility.wrapping/wrap-mash-step) - Wrap a mash-step map into a mash-step-wrapper map. - - [`wrap-mash-steps`](#brewtility.wrapping/wrap-mash-steps) - Wrap a mash-steps collection into a mash-steps-wrapper map. - - [`wrap-misc`](#brewtility.wrapping/wrap-misc) - Wrap a misc map into a misc-wrapper map. - - [`wrap-miscs`](#brewtility.wrapping/wrap-miscs) - Wrap a miscs collection into a miscs-wrapper map. - - [`wrap-recipe`](#brewtility.wrapping/wrap-recipe) - Wrap a recipe map into a recipe-wrapper map. - - [`wrap-recipes`](#brewtility.wrapping/wrap-recipes) - Wrap a recipes collection into a recipes-wrapper map. - - [`wrap-style`](#brewtility.wrapping/wrap-style) - Wrap a style map into a style-wrapper map. - - [`wrap-styles`](#brewtility.wrapping/wrap-styles) - Wrap a styles collection into a styles-wrapper map. - - [`wrap-water`](#brewtility.wrapping/wrap-water) - Wrap a water map into a water-wrapper map. - - [`wrap-waters`](#brewtility.wrapping/wrap-waters) - Wrap a waters collection into a waters-wrapper map. - - [`wrap-yeast`](#brewtility.wrapping/wrap-yeast) - Wrap a yeast map into a yeast-wrapper map. - - [`wrap-yeasts`](#brewtility.wrapping/wrap-yeasts) - Wrap a yeasts collection into a yeasts-wrapper map. - ------ -# brewtility.calculations - - -Namespace for handling recipe calculations. - This namespace assumes ingredients that conform to the [common-beer-format](https://github.com/Wall-Brew-Co/common-beer-format). - - - - -## `calculate-alpha-acid-units` [:page_facing_up:](null) - -``` clojure - -(calculate-alpha-acid-units weight alpha) -``` - - -Calculate the maximum amount of alpha acid released by `weight` ounce of a hop at `percent` alpha acid - -## `calculate-ebc-color` [:page_facing_up:](null) - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the EBC color for a recipe - -## `calculate-equipment-boil-volume` [:page_facing_up:](null) - -``` clojure - -(calculate-equipment-boil-volume {:keys [batch-size top-up-water trub-chiller-loss boil-time evap-rate]}) -``` - - -Given a `common-beer-format` conforming `equipment`, calculate the volume of the wort at the start of the boil. - If insufficient data is provided, this function will throw an exception. - -## `calculate-hop-utilization` [:page_facing_up:](null) - -``` clojure - -(calculate-hop-utilization gravity boil-duration) -``` - - -Calculate the percentage of alpha acid that a hop could release over `boil-duration` in a wort at a specific `gravity` - Based on: http://howtobrew.com/book/section-1/hops/hop-bittering-calculations - -## `calculate-ibu-per-hop` [:page_facing_up:](null) - -``` clojure - -(calculate-ibu-per-hop hop batch-size potential-gravity) -``` - - -Given a `common-beer-format` conforming `hop`, `batch-size`, and `potential-gravity`, calculate the amount of IBUs generated - -## `calculate-lovibond-color` [:page_facing_up:](null) - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the color in degrees Lovibond for a recipe - -## `calculate-malt-color-units` [:page_facing_up:](null) - -``` clojure - -(calculate-malt-color-units fermentables batch-size) -``` - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the overall Malt Color Units for a recipe - -## `calculate-potential-abv` [:page_facing_up:](null) - -``` clojure - -(calculate-potential-abv fermentables batch-size) -(calculate-potential-abv fermentables batch-size attenuation) -``` - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, estimate the ABV. - The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed. - -## `calculate-potential-final-gravity` [:page_facing_up:](null) - -``` clojure - -(calculate-potential-final-gravity fermentables batch-size) -(calculate-potential-final-gravity fermentables batch-size attenuation) -``` - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, estimate the Final Gravity. - The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed. - -## `calculate-potential-gravity` [:page_facing_up:](null) - -``` clojure - -(calculate-potential-gravity fermentables batch-size) -``` - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, calculate the potential original gravity. - -## `calculate-recipe-ibus` [:page_facing_up:](null) - -``` clojure - -(calculate-recipe-ibus hops batch-size potential-gravity) -``` - - -Given a collection of `common-beer-format` conforming `hops`, `batch-size`, and `potential-gravity` calculate the amount of IBUs generated - -## `calculate-rgba-color` [:page_facing_up:](null) - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the RGBA color for a recipe - -## `calculate-srm-color` [:page_facing_up:](null) - -``` clojure - -(calculate-srm-color fermentables batch-size) -``` - - -Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the SRM color for a recipe - -## `default-attenuation` [:page_facing_up:](null) - - -A constant backup attenuation for calculations. - Set to 75% a common threshold for home brewing - -## `gravity->abv-multiplier` [:page_facing_up:](null) - - -The constanct factor used to calculate ABV from potential gravity - -## `gravity-points->potential-gravity` [:page_facing_up:](null) - -``` clojure - -(gravity-points->potential-gravity gravity-points volume) -``` - - -Given the `gravity-points` of a recipe, and the `volume` of the batch, calculate the potential gravity - -## `potential-gravity->gravity-points` [:page_facing_up:](null) - -``` clojure - -(potential-gravity->gravity-points potential-gravity weight) -``` - - -Given the `potential-gravity` of a fermentable, and the `weight` of the fermentable, calculate gravity points - ------ -# brewtility.color - - -Namespace for calculating beer colors - - - - -## `color-system->display-name` [:page_facing_up:](null) - - -A map from color system names to their full and short unit names - -## `color-systems` [:page_facing_up:](null) - - -The color systems available across brewtility - -## `ebc->lovibond` [:page_facing_up:](null) - - -Convert the color described in 'ebc` to the equivalent degrees Lovibond - -## `ebc->rgba` [:page_facing_up:](null) - - -Given `ebc-number`, return the closest, bounded applicable RGBA color string. - -## `ebc->srm` [:page_facing_up:](null) - -``` clojure - -(ebc->srm ebc) -``` - - -Convert the color described by the `ebc` to the equivalent SRM color - -## `lovibond->ebc` [:page_facing_up:](null) - - -Convert the color described in degrees 'lovibond` to the equivalent EBC color - -## `lovibond->rgba` [:page_facing_up:](null) - - -Given `lovibond-number`, return the closest, bounded applicable RGBA color string. - -## `lovibond->srm` [:page_facing_up:](null) - -``` clojure - -(lovibond->srm lovibond) -``` - - -Convert the color described in degrees `lovibond` to the equivalent SRM color - -## `srm-1` [:page_facing_up:](null) - - -An SRM of 1 mapped to an RGBa color code - -## `srm-10` [:page_facing_up:](null) - - -An SRM of 10 mapped to an RGBa color code - -## `srm-11` [:page_facing_up:](null) - - -An SRM of 11 mapped to an RGBa color code - -## `srm-12` [:page_facing_up:](null) - - -An SRM of 12 mapped to an RGBa color code - -## `srm-13` [:page_facing_up:](null) - - -An SRM of 13 mapped to an RGBa color code - -## `srm-14` [:page_facing_up:](null) - - -An SRM of 14 mapped to an RGBa color code - -## `srm-15` [:page_facing_up:](null) - - -An SRM of 15 mapped to an RGBa color code - -## `srm-16` [:page_facing_up:](null) - - -An SRM of 16 mapped to an RGBa color code - -## `srm-17` [:page_facing_up:](null) - - -An SRM of 17 mapped to an RGBa color code - -## `srm-18` [:page_facing_up:](null) - - -An SRM of 18 mapped to an RGBa color code - -## `srm-19` [:page_facing_up:](null) - - -An SRM of 19 mapped to an RGBa color code - -## `srm-2` [:page_facing_up:](null) - - -An SRM of 2 mapped to an RGBa color code - -## `srm-20` [:page_facing_up:](null) - - -An SRM of 20 mapped to an RGBa color code - -## `srm-21` [:page_facing_up:](null) - - -An SRM of 21 mapped to an RGBa color code - -## `srm-22` [:page_facing_up:](null) - - -An SRM of 22 mapped to an RGBa color code - -## `srm-23` [:page_facing_up:](null) - - -An SRM of 23 mapped to an RGBa color code - -## `srm-24` [:page_facing_up:](null) - - -An SRM of 24 mapped to an RGBa color code - -## `srm-25` [:page_facing_up:](null) - - -An SRM of 25 mapped to an RGBa color code - -## `srm-26` [:page_facing_up:](null) - - -An SRM of 26 mapped to an RGBa color code - -## `srm-27` [:page_facing_up:](null) - - -An SRM of 27 mapped to an RGBa color code - -## `srm-28` [:page_facing_up:](null) - - -An SRM of 28 mapped to an RGBa color code - -## `srm-29` [:page_facing_up:](null) - - -An SRM of 29 mapped to an RGBa color code - -## `srm-3` [:page_facing_up:](null) - - -An SRM of 3 mapped to an RGBa color code - -## `srm-30` [:page_facing_up:](null) - - -An SRM of 30 mapped to an RGBa color code - -## `srm-31` [:page_facing_up:](null) - - -An SRM of 31 mapped to an RGBa color code - -## `srm-32` [:page_facing_up:](null) - - -An SRM of 32 mapped to an RGBa color code - -## `srm-33` [:page_facing_up:](null) - - -An SRM of 33 mapped to an RGBa color code - -## `srm-34` [:page_facing_up:](null) - - -An SRM of 34 mapped to an RGBa color code - -## `srm-35` [:page_facing_up:](null) - - -An SRM of 35 mapped to an RGBa color code - -## `srm-36` [:page_facing_up:](null) - - -An SRM of 36 mapped to an RGBa color code - -## `srm-37` [:page_facing_up:](null) - - -An SRM of 37 mapped to an RGBa color code - -## `srm-38` [:page_facing_up:](null) - - -An SRM of 38 mapped to an RGBa color code - -## `srm-39` [:page_facing_up:](null) - - -An SRM of 39 mapped to an RGBa color code - -## `srm-4` [:page_facing_up:](null) - - -An SRM of 4 mapped to an RGBa color code - -## `srm-40` [:page_facing_up:](null) - - -An SRM of 40 mapped to an RGBa color code - -## `srm-5` [:page_facing_up:](null) - - -An SRM of 5 mapped to an RGBa color code - -## `srm-6` [:page_facing_up:](null) - - -An SRM of 6 mapped to an RGBa color code - -## `srm-7` [:page_facing_up:](null) - - -An SRM of 7 mapped to an RGBa color code - -## `srm-8` [:page_facing_up:](null) - - -An SRM of 8 mapped to an RGBa color code - -## `srm-9` [:page_facing_up:](null) - - -An SRM of 9 mapped to an RGBa color code - -## `srm->ebc` [:page_facing_up:](null) - -``` clojure - -(srm->ebc srm) -``` - - -Convert the color described by the `srm` to the equivalent EBC color - -## `srm->lovibond` [:page_facing_up:](null) - -``` clojure - -(srm->lovibond srm) -``` - - -Convert the color described in 'srm` to the equivalent degrees Lovibond - -## `srm->rgba` [:page_facing_up:](null) - -``` clojure - -(srm->rgba srm-number) -``` - - -Given `srm-number`, return the closest, bounded applicable RGBA color string. - OPINIONATED: The provided `srm-number` will be bound to the common range from 1 to 40 - Decimal-like values are trimmed, not rounded. - -## `srm-color-map` [:page_facing_up:](null) - - -A map of integer values to their closest SRM value as an RGBa color code - ------ -# brewtility.enrich.equipment - - -Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps - - - - -## `enrich-calculated-boil-size` [:page_facing_up:](null) - -``` clojure - -(enrich-calculated-boil-size equipment) -(enrich-calculated-boil-size - {:keys [calc-boil-volume], :as equipment} - {:keys [safe-calculating-boil-size precision], :or {precision 3}}) -``` - - -An enricher pattern function to calculate the boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record via [[brewtility.calculations/calculate-equipment-boil-volume]]. - In the BeerXML spec, this behavior is controlled by the `:calc-boil-volume` field. - When `:calc-boil-volume` is set to `true`, the `:boil-size` field is calculated as: - `(batch-size - top-up-water - trub-chiller-loss) * (1 + (boil-time * evap-rate))` - - When `:calc-boil-volume` is set to `false`, the `:boil-size` field is left unmodified. - As a note, both the BeerXML spec and common-beer-format only require the `boil-size` field to be a number. - Neither the specification nor the implementation will check to ensure the value is correct given the other fields. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. - In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. - Defaults to `false`. - - `:precision` - The number of decimal places to round the calculated value to. - Defaults to `3`. - -## `enrich-display-batch-size` [:page_facing_up:](null) - -``` clojure - -(enrich-display-batch-size equipment) -(enrich-display-batch-size equipment {:keys [batch-size-target-units batch-size-precision batch-size-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable batch size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the batch size into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the batch size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. - - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. - -## `enrich-display-boil-size` [:page_facing_up:](null) - -``` clojure - -(enrich-display-boil-size equipment) -(enrich-display-boil-size equipment {:keys [boil-size-target-units boil-size-precision boil-size-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable boil size to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the boil size into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. - - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. - -## `enrich-display-lauter-deadspace` [:page_facing_up:](null) - -``` clojure - -(enrich-display-lauter-deadspace equipment) -(enrich-display-lauter-deadspace - equipment - {:keys [lauter-deadspace-target-units lauter-deadspace-precision lauter-deadspace-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable lauter deadspace to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the lauter deadspace into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the lauter deadspace. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. - - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. - -## `enrich-display-top-up-kettle` [:page_facing_up:](null) - -``` clojure - -(enrich-display-top-up-kettle equipment) -(enrich-display-top-up-kettle - equipment - {:keys [top-up-kettle-target-units top-up-kettle-precision top-up-kettle-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable top up kettle to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the top up kettle into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the top up kettle. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. - -## `enrich-display-top-up-water` [:page_facing_up:](null) - -``` clojure - -(enrich-display-top-up-water equipment) -(enrich-display-top-up-water - equipment - {:keys [top-up-water-target-units top-up-water-precision top-up-water-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable top up water to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the top up water into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the top up water. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. - - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. - -## `enrich-display-trub-chiller-loss` [:page_facing_up:](null) - -``` clojure - -(enrich-display-trub-chiller-loss equipment) -(enrich-display-trub-chiller-loss - equipment - {:keys [trub-chiller-loss-target-units trub-chiller-loss-precision trub-chiller-loss-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable trub chiller loss to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the trub chiller loss into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the trub chiller loss. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. - - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. - -## `enrich-display-tun-volume` [:page_facing_up:](null) - -``` clojure - -(enrich-display-tun-volume equipment) -(enrich-display-tun-volume equipment {:keys [tun-volume-target-units tun-volume-precision tun-volume-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable tun volume to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the tun volume into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the tun volume. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. - - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. - -## `enrich-display-tun-weight` [:page_facing_up:](null) - -``` clojure - -(enrich-display-tun-weight equipment) -(enrich-display-tun-weight equipment {:keys [tun-weight-target-units tun-weight-precision tun-weight-suffix], :as opts}) -``` - - -An enricher pattern function to add the displayable tun weight to an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) record. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:system-of-measure`: The unit system of measure to convert the tun weight into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the tun weight. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-equipment`](#brewtility.enrich.equipment/enrich-equipment) and [`enrich-equipment-wrapper`](#brewtility.enrich.equipment/enrich-equipment-wrapper), this function also supports the following keys: - - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. - - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. - -## `enrich-equipment` [:page_facing_up:](null) - -``` clojure - -(enrich-equipment equipment) -(enrich-equipment equipment opts) -``` - - -An enricher pattern function to derive as many values from an [equipment record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-calculated-boil-size]] - - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. - In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. - Defaults to `false`. - - [[enrich-display-boil-size]] - - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. - - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. - - [[enrich-display-batch-size]] - - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. - - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. - - [[enrich-diplay-tun-volume]] - - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. - - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. - - [[enrich-display-tun-weight]] - - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. - - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. - - [[enrich-display-top-up-water]] - - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. - - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. - - [[enrich-display-trub-chiller-loss]] - - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. - - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. - - [[enrich-display-lauter-deadspace]] - - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. - - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. - - [[enrich-display-top-up-kettle]] - - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. - -## `enrich-equipment-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-equipment-wrapper equipment-wrapper) -(enrich-equipment-wrapper equipment-wrapper opts) -``` - - -An enricher pattern function to derive as many values from an [equipment-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the displayable fields into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the displayable fields. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"gal"` for `" US gallons"`. - - `:full`: The full name of the selected unit. For example, `"teaspoon"` for `"teaspoon"`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-calculated-boil-size]] - - `:safe-calculating-boil-size` - If this value is true, the program will not throw an exception if data is missing for the calculation. - In that case, the exception will be caught internally and the `:boil-size` will not be modified from its original value. - Defaults to `false`. - - [[enrich-display-boil-size]] - - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. - - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`. - - [[enrich-display-batch-size]] - - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. - - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`. - - [[enrich-diplay-tun-volume]] - - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. - - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`. - - [[enrich-display-tun-weight]] - - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. - - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`. - - [[enrich-display-top-up-water]] - - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. - - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`. - - [[enrich-display-trub-chiller-loss]] - - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. - - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`. - - [[enrich-display-lauter-deadspace]] - - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. - - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`. - - [[enrich-display-top-up-kettle]] - - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`. - ------ -# brewtility.enrich.fermentables - - -Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps - - - - -## `enrich-add-after-boil` [:page_facing_up:](null) - -``` clojure - -(enrich-add-after-boil fermentable) -(enrich-add-after-boil fermentable _opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. - In the BeerXML spec, this behavior is implicitly falsey. - Therefore, if the :add-after-boil field is not present, this function will explicitly set it to false. - -## `enrich-coarse-fine-diff` [:page_facing_up:](null) - -``` clojure - -(enrich-coarse-fine-diff fermentable) -(enrich-coarse-fine-diff fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a coarse/fine differential. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will dissoc `:coarse-fine-diff` from the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `enrich-diastatic-power` [:page_facing_up:](null) - -``` clojure - -(enrich-diastatic-power fermentable) -(enrich-diastatic-power fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a listed Diastatic Power. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will dissoc `:diastatic-power` from the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `enrich-display-amount` [:page_facing_up:](null) - -``` clojure - -(enrich-display-amount fermentable) -(enrich-display-amount - fermentable - {:keys [fermentable-amount-target-units fermentable-amount-precision fermentable-amount-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display weight of a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. - In the BeerXML spec, the amount of a liquid extract is computed by its weight. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) and [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper), this function also supports the following keys: - - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-color` [:page_facing_up:](null) - -``` clojure - -(enrich-display-color fermentable) -(enrich-display-color fermentable {:keys [color-system suffix], :as opts}) -``` - - -An enricher pattern function to determine what color a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is in a given system. - In the BeerXML spec, color is assumed to be in Lovibond for the `:type` of `grain`, and SRM for all other fermentables. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - `:suffix`: The suffix type to append to the boil size. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained selections within the context of [`enrich-fermentable`](#brewtility.enrich.fermentables/enrich-fermentable) and [`enrich-fermentable-wrapper`](#brewtility.enrich.fermentables/enrich-fermentable-wrapper), this function also supports the following keys: - - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-fermentable` [:page_facing_up:](null) - -``` clojure - -(enrich-fermentable fermentable) -(enrich-fermentable fermentable opts) -``` - - -An enricher pattern function to derive as many values from an [fermentable record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-color]] - - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-amount]] - - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-fermentable-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-fermentable-wrapper fermentable) -(enrich-fermentable-wrapper fermentable opts) -``` - - -An enricher pattern function to derive as many values from an [fermentable-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-color]] - - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-amount]] - - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-fermentables` [:page_facing_up:](null) - -``` clojure - -(enrich-fermentables fermentables) -(enrich-fermentables fermentables opts) -``` - - -An enricher pattern function to derive as many values from an [fermentables record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-color]] - - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-amount]] - - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-fermentables-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-fermentables-wrapper fermentables) -(enrich-fermentables-wrapper fermentables opts) -``` - - -An enricher pattern function to derive as many values from an [fermentables-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: - - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. - - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. - - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. - - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-color]] - - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-amount]] - - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-ibu-gallons-per-pound` [:page_facing_up:](null) - -``` clojure - -(enrich-ibu-gallons-per-pound fermentable) -(enrich-ibu-gallons-per-pound fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have ibu-gal-per-lb. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `extract`. - When the fermetable is not an extract, this function will dissoc `:ibu-gal-per-lb` from the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `enrich-moisture` [:page_facing_up:](null) - -``` clojure - -(enrich-moisture fermentable) -(enrich-moisture fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have a moisture content. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will dissoc `:moisture` from the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `enrich-protein` [:page_facing_up:](null) - -``` clojure - -(enrich-protein fermentable) -(enrich-protein fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have protein. - In the BeerXML spec, this field is only valid if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will dissoc `:protein` from the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `enrich-recommend-mash` [:page_facing_up:](null) - -``` clojure - -(enrich-recommend-mash fermentable) -(enrich-recommend-mash fermentable opts) -``` - - -An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) should have recommend-mash. - In the BeerXML spec, this field should only be `true` if the `:type` of the fermentable is `grain` or `adjunct`. - When the fermetable is not a grain or adjunct, this function will set `:recommend-mash` to false in the fermentable. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.enrich.hops - - -Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps - - - - -## `enrich-display-amount` [:page_facing_up:](null) - -``` clojure - -(enrich-display-amount hop) -(enrich-display-amount hop {:keys [hop-amount-target-units hop-amount-precision hop-amount-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display weight of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) and [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper), this function also supports the following keys: - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-time` [:page_facing_up:](null) - -``` clojure - -(enrich-display-time hop) -(enrich-display-time hop {:keys [hop-time-target-units hop-time-precision hop-time-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display time of a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-hop`](#brewtility.enrich.hops/enrich-hop) and [`enrich-hop-wrapper`](#brewtility.enrich.hops/enrich-hop-wrapper), this function also supports the following keys: - - `:hop-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - - `:hop-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`. - -## `enrich-hop` [:page_facing_up:](null) - -``` clojure - -(enrich-hop hop) -(enrich-hop hop opts) -``` - - -An enricher pattern function to derive as many values from an [hop record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-hop-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-hop-wrapper hop) -(enrich-hop-wrapper hop opts) -``` - - -An enricher pattern function to derive as many values from an [hop-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-hops` [:page_facing_up:](null) - -``` clojure - -(enrich-hops hops) -(enrich-hops hops opts) -``` - - -An enricher pattern function to derive as many values from an [hops record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-hops-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-hops-wrapper hops) -(enrich-hops-wrapper hops opts) -``` - - -An enricher pattern function to derive as many values from an [hops-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - ------ -# brewtility.enrich.mash - - -Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps - - - - -## `enrich-display-grain-temperature` [:page_facing_up:](null) - -``` clojure - -(enrich-display-grain-temperature mash) -(enrich-display-grain-temperature - mash - {:keys [display-grain-temperature-target-units display-grain-temperature-precision display-grain-temperature-suffix], - :as opts}) -``` - - -An enricher pattern function to render a human-readable temperature of the grain temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-infuse-amount` [:page_facing_up:](null) - -``` clojure - -(enrich-display-infuse-amount mash-step) -(enrich-display-infuse-amount - mash-step - {:keys [display-infuse-amount-target-units display-infuse-amount-precision display-infuse-amount-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable infuse amount of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-sparge-temperature` [:page_facing_up:](null) - -``` clojure - -(enrich-display-sparge-temperature mash) -(enrich-display-sparge-temperature - mash - {:keys - [display-sparge-temperature-target-units display-sparge-temperature-precision display-sparge-temperature-suffix], - :as opts}) -``` - - -An enricher pattern function to render a human-readable temperature of the sparge temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-spargeed selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-step-temperature` [:page_facing_up:](null) - -``` clojure - -(enrich-display-step-temperature mash-step) -(enrich-display-step-temperature - mash-step - {:keys [display-temperature-target-units display-temperature-precision display-temperature-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display temperature of a [mash step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-tun-temperature` [:page_facing_up:](null) - -``` clojure - -(enrich-display-tun-temperature mash) -(enrich-display-tun-temperature - mash - {:keys [display-tun-temperature-target-units display-tun-temperature-precision display-tun-temperature-suffix], - :as opts}) -``` - - -An enricher pattern function to render a human-readable temperature of the tun temperature during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-tuned selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-display-tun-weight` [:page_facing_up:](null) - -``` clojure - -(enrich-display-tun-weight mash) -(enrich-display-tun-weight - mash - {:keys [display-tun-weight-target-units display-tun-weight-precision display-tun-weight-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable weight of the tun weight during a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the amount. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-tuned selections within the context of [`enrich-mash-step`](#brewtility.enrich.mash/enrich-mash-step) and [`enrich-mash-step-wrapper`](#brewtility.enrich.mash/enrich-mash-step-wrapper), this function also supports the following keys: - - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash` [:page_facing_up:](null) - -``` clojure - -(enrich-mash mash) -(enrich-mash mash opts) -``` - - -An enricher pattern function to derive as many values from an [mash record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-grain-temperature]] - - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-tun-temperature]] - - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-sparge-temperature]] - - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` - - [[enrich-display-tun-weight]] - - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash-step` [:page_facing_up:](null) - -``` clojure - -(enrich-mash-step mash-step) -(enrich-mash-step mash-step opts) -``` - - -An enricher pattern function to derive as many values from an [mash-step record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash-step-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-mash-step-wrapper mash-step) -(enrich-mash-step-wrapper mash-step opts) -``` - - -An enricher pattern function to derive as many values from an [mash-step wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash-steps` [:page_facing_up:](null) - -``` clojure - -(enrich-mash-steps mash-steps) -(enrich-mash-steps mash-steps opts) -``` - - -An enricher pattern function to derive as many values from a collection of [mash-step wrapper records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash-steps-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-mash-steps-wrapper mash) -(enrich-mash-steps-wrapper mash opts) -``` - - -An enricher pattern function to derive as many values from a collection of [mash-steps wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-mash-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-mash-wrapper mash) -(enrich-mash-wrapper mash opts) -``` - - -An enricher pattern function to derive as many values from an [mash wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-step-temperature]] - - `:display-temperature-target-units`: The unit to convert the temperature into. Supersedes `:system-of-measure`. - - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-temperature-suffix`: The suffix type to append to the temperature. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-grain-temperature]] - - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-tun-temperature]] - - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-sparge-temperature]] - - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix` - - [[enrich-display-tun-weight]] - - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - ------ -# brewtility.enrich.miscs - - -Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps - - - - -## `enrich-amount-is-weight` [:page_facing_up:](null) - -``` clojure - -(enrich-amount-is-weight misc) -(enrich-amount-is-weight misc _) -``` - - -An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. - When this feild is not present, it is assumed to be false. - -## `enrich-display-amount` [:page_facing_up:](null) - -``` clojure - -(enrich-display-amount misc) -(enrich-display-amount misc {:keys [misc-time-target-units misc-time-precision misc-time-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. - If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. - Otherwise, it will be treated as a volume in liters. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) and [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper), this function also supports the following keys: - - `:misc-amount-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the time. Supersedes `:suffix`. - -## `enrich-display-time` [:page_facing_up:](null) - -``` clojure - -(enrich-display-time misc) -(enrich-display-time misc {:keys [misc-time-target-units misc-time-precision misc-time-suffix], :as opts}) -``` - - -An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. - - An option map may be passed as an optional second argument to this function to override the default behavior. - Supported keys include: - - - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"lb"` for `"pounds"`. - - `:full`: The full name of the selected unit. For example, `"gram"` for `"gram"`. - - To support fine-grained selections within the context of [`enrich-misc`](#brewtility.enrich.miscs/enrich-misc) and [`enrich-misc-wrapper`](#brewtility.enrich.miscs/enrich-misc-wrapper), this function also supports the following keys: - - `:misc-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - - `:misc-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`. - -## `enrich-misc` [:page_facing_up:](null) - -``` clojure - -(enrich-misc misc) -(enrich-misc misc opts) -``` - - -An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-misc-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-misc-wrapper misc) -(enrich-misc-wrapper misc opts) -``` - - -An enricher pattern function to derive as many values from an [misc-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-miscs` [:page_facing_up:](null) - -``` clojure - -(enrich-miscs miscs) -(enrich-miscs miscs opts) -``` - - -An enricher pattern function to derive as many values from an [miscs record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - -## `enrich-miscs-wrapper` [:page_facing_up:](null) - -``` clojure - -(enrich-miscs-wrapper miscs) -(enrich-miscs-wrapper miscs opts) -``` - - -An enricher pattern function to derive as many values from an [miscs-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). - - An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - - - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: - - `:short`: A customary abbreviation for the selected unit. For example, `"°L"` for `:lovibond`. - - `:full`: The full name of the selected unit. For example, `"° Lovibond"` for `:lovibond`. - - To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - - [[enrich-display-amount]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - - [[enrich-display-time]] - - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. - ------ -# brewtility.precision - - -Namespace for handling numeric precision - - - - -## `->1dp` [:page_facing_up:](null) - -``` clojure - -(->1dp x) -``` - - -Given a decimal `x`, returns that number rounded to one decimal place. - -## `->2dp` [:page_facing_up:](null) - -``` clojure - -(->2dp x) -``` - - -Given a decimal `x`, returns that number rounded to two decimal places. - -## `->3dp` [:page_facing_up:](null) - -``` clojure - -(->3dp x) -``` - - -Given a decimal `x`, returns that number rounded to three decimal places. - -## `->precision` [:page_facing_up:](null) - -``` clojure - -(->precision x num-decimals) -``` - - -Given a decimal `x` and the number of decimal places, returns that number rounded to `num-decimals` precision - -## `approximates?` [:page_facing_up:](null) - -``` clojure - -(approximates? n1 n2 variance) -``` - - -Determine if `n2` approximates `n1` within `variance` percent - ------ -# brewtility.predicates.equipment - - -Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps - - - - -## `calculated-boil-volume?` [:page_facing_up:](null) - -``` clojure - -(calculated-boil-volume? equipment) -``` - - -A predicate function to determine if an [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) had its boil volume calculated. - In the BeerXML spec, this behavior is implicitly falsey. - Therefore, if the :calc-boil-volume field is not present, this function will explicitly return false. - ------ -# brewtility.predicates.fermentables - - -Predicate functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps - - - - -## `add-after-boil?` [:page_facing_up:](null) - -``` clojure - -(add-after-boil? fermentable) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the start of the boil. - In the BeerXML spec, this behavior is implicitly falsey. - Therefore, if the :add-after-boil field is not present, this function will explicitly return false. - -## `adjunct?` [:page_facing_up:](null) - -``` clojure - -(adjunct? fermentable) -(adjunct? fermentable opts) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is an adjunct, non-standard fermentable. - This function will throw an exception if the `type` field is not present. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `dry-extract?` [:page_facing_up:](null) - -``` clojure - -(dry-extract? fermentable) -(dry-extract? fermentable opts) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is dried malt extract. - This function will throw an exception if the `type` field is not present. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `extract?` [:page_facing_up:](null) - -``` clojure - -(extract? fermentable) -(extract? fermentable opts) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a liquid malt extract. - This function will throw an exception if the `type` field is not present. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `grain?` [:page_facing_up:](null) - -``` clojure - -(grain? fermentable) -(grain? fermentable opts) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is whole grain. - This function will throw an exception if the `type` field is not present. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `sugar?` [:page_facing_up:](null) - -``` clojure - -(sugar? fermentable) -(sugar? fermentable opts) -``` - - -A predicate function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) is a raw sugar. - This function will throw an exception if the `type` field is not present. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.hops - - -Predicate functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps - - - - -## `aroma-type?` [:page_facing_up:](null) - -``` clojure - -(aroma-type? hop) -(aroma-type? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for aroma. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `aroma-use?` [:page_facing_up:](null) - -``` clojure - -(aroma-use? hop) -(aroma-use? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added at the end of the boil for aroma. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `bittering?` [:page_facing_up:](null) - -``` clojure - -(bittering? hop) -(bittering? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for bittering. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `boil?` [:page_facing_up:](null) - -``` clojure - -(boil? hop) -(boil? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used during the boil. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `both?` [:page_facing_up:](null) - -``` clojure - -(both? hop) -(both? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for both bittering and aroma. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `dry-hop?` [:page_facing_up:](null) - -``` clojure - -(dry-hop? hop) -(dry-hop? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was used as a dry-hop addition in secondary fermentation. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `first-wort?` [:page_facing_up:](null) - -``` clojure - -(first-wort? hop) -(first-wort? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added to the wort at the first possible moment. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `leaf?` [:page_facing_up:](null) - -``` clojure - -(leaf? hop) -(leaf? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a whole hop cone. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. - -## `mash?` [:page_facing_up:](null) - -``` clojure - -(mash? hop) -(mash? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added during the mash and before the boil. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `pellet?` [:page_facing_up:](null) - -``` clojure - -(pellet? hop) -(pellet? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed pellet. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. - -## `plug?` [:page_facing_up:](null) - -``` clojure - -(plug? hop) -(plug? hop opts) -``` - - -A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed whole-hop plug. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.mash - - -Predicate functions for [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps - - - - -## `adjust-for-equipment?` [:page_facing_up:](null) - -``` clojure - -(adjust-for-equipment? mash) -``` - - -A predicate function to determine if a [mash](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) should account for any temperature effects of the equipment used. - In the BeerXML spec, this behavior is implicitly falsey. - Therefore, if the `:equip-adjust` field is not present, this function will return false. - -## `decoction?` [:page_facing_up:](null) - -``` clojure - -(decoction? mash-step) -(decoction? mash-step opts) -``` - - -A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to extract and concentrate flavor. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `infusion?` [:page_facing_up:](null) - -``` clojure - -(infusion? mash-step) -(infusion? mash-step opts) -``` - - -A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used as a basic infusion. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `temperature?` [:page_facing_up:](null) - -``` clojure - -(temperature? mash-step) -(temperature? mash-step opts) -``` - - -A predicate function to determine if a [mash-step](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) is used to bring wort up to temperature. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.miscs - - -Predicate functions for [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps - - - - -## `boil?` [:page_facing_up:](null) - -``` clojure - -(boil? misc) -(boil? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the boil. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `bottling?` [:page_facing_up:](null) - -``` clojure - -(bottling? misc) -(bottling? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during bottle conditioning. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `fining?` [:page_facing_up:](null) - -``` clojure - -(fining? misc) -(fining? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `flavor?` [:page_facing_up:](null) - -``` clojure - -(flavor? misc) -(flavor? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is added for flavor. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `herb?` [:page_facing_up:](null) - -``` clojure - -(herb? misc) -(herb? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a herb. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `mash?` [:page_facing_up:](null) - -``` clojure - -(mash? misc) -(mash? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the mash. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `other?` [:page_facing_up:](null) - -``` clojure - -(other? misc) -(other? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is an unspecified type. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `primary?` [:page_facing_up:](null) - -``` clojure - -(primary? misc) -(primary? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the primary fermentation. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `secondary?` [:page_facing_up:](null) - -``` clojure - -(secondary? misc) -(secondary? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) was added during the secondary fermentation. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:use` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:use` field should be coerced to a string for comparison. Default is false. - -## `spice?` [:page_facing_up:](null) - -``` clojure - -(spice? misc) -(spice? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a spice. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `water-agent?` [:page_facing_up:](null) - -``` clojure - -(water-agent? misc) -(water-agent? misc opts) -``` - - -A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is a water agent. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.recipes - - -Predicate functions for [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) maps - - - - -## `all-grain?` [:page_facing_up:](null) - -``` clojure - -(all-grain? recipe) -(all-grain? recipe opts) -``` - - -A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made entirely of grain. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `extract?` [:page_facing_up:](null) - -``` clojure - -(extract? recipe) -(extract? recipe opts) -``` - - -A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was made with extract only. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `forced-carbonation?` [:page_facing_up:](null) - -``` clojure - -(forced-carbonation? recipe) -``` - - -A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was forcefully carbonated. - In the BeerXML spec, this behavior is implicitly falsey. - Therefore, if the :forced-carbonation field is not present, this function will explicitly return false. - -## `garetz?` [:page_facing_up:](null) - -``` clojure - -(garetz? recipe) -(garetz? recipe opts) -``` - - -A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the garetz method. - This method was originally developed by Mark Garetz, and is most accurate for High IBU recipes. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. - -## `partial-mash?` [:page_facing_up:](null) - -``` clojure - -(partial-mash? recipe) -(partial-mash? recipe opts) -``` - - -A predicate function to determine if a [recipe](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) was partially mashed. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `rager?` [:page_facing_up:](null) - -``` clojure - -(rager? recipe) -(rager? recipe opts) -``` - - -A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the Rager method. - This method was originally developed by Jackie Rager, and is most accurate for partial mash recipes. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. - -## `tinseth?` [:page_facing_up:](null) - -``` clojure - -(tinseth? recipe) -(tinseth? recipe opts) -``` - - -A predicate function to determine if a [recipe's](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) IBU was calculated with the tinseth method. - This method was originally developed by Glenn Tinseth, and is most accurate for all grain recipes. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:ibu-method` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:ibu-method` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.styles - - -Predicate functions for [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps - - - - -## `ale?` [:page_facing_up:](null) - -``` clojure - -(ale? style) -(ale? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `cider?` [:page_facing_up:](null) - -``` clojure - -(cider? style) -(cider? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ciders. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `lager?` [:page_facing_up:](null) - -``` clojure - -(lager? style) -(lager? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for lagers. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `mead?` [:page_facing_up:](null) - -``` clojure - -(mead? style) -(mead? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for meads. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `mixed?` [:page_facing_up:](null) - -``` clojure - -(mixed? style) -(mixed? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for blended/mixed beers. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `wheat?` [:page_facing_up:](null) - -``` clojure - -(wheat? style) -(wheat? style opts) -``` - - -A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for wheat beers. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.predicates.waters - - -Predicate functions for [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps. - - - - -## `acidic?` [:page_facing_up:](null) - -``` clojure - -(acidic? water) -``` - - -A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is acidic. - -## `alkaline?` [:page_facing_up:](null) - -``` clojure - -(alkaline? water) -``` - - -A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. - -## `neutral?` [:page_facing_up:](null) - -``` clojure - -(neutral? water) -``` - - -A predicate function to determine if a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) profile is alkaline. - ------ -# brewtility.predicates.yeasts - - -Predicate functions for [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps - - - - -## `ale?` [:page_facing_up:](null) - -``` clojure - -(ale? yeast) -(ale? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for ale. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `champagne?` [:page_facing_up:](null) - -``` clojure - -(champagne? yeast) -(champagne? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `culture?` [:page_facing_up:](null) - -``` clojure - -(culture? yeast) -(culture? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `dry?` [:page_facing_up:](null) - -``` clojure - -(dry? yeast) -(dry? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `high-flocculation?` [:page_facing_up:](null) - -``` clojure - -(high-flocculation? yeast) -(high-flocculation? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `lager?` [:page_facing_up:](null) - -``` clojure - -(lager? yeast) -(lager? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `liquid?` [:page_facing_up:](null) - -``` clojure - -(liquid? yeast) -(liquid? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in liquid form. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `low-flocculation?` [:page_facing_up:](null) - -``` clojure - -(low-flocculation? yeast) -(low-flocculation? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a low amount of floc. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `medium-flocculation?` [:page_facing_up:](null) - -``` clojure - -(medium-flocculation? yeast) -(medium-flocculation? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `slant?` [:page_facing_up:](null) - -``` clojure - -(slant? yeast) -(slant? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. - Typically, this is a solid growth of yeast cells in a test tube. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `very-high-flocculation?` [:page_facing_up:](null) - -``` clojure - -(very-high-flocculation? yeast) -(very-high-flocculation? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `wheat?` [:page_facing_up:](null) - -``` clojure - -(wheat? yeast) -(wheat? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - -## `wine?` [:page_facing_up:](null) - -``` clojure - -(wine? yeast) -(wine? yeast opts) -``` - - -A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. - - An option map can be passed to this function as an optional second parameter. - Supported keys are: - - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - ------ -# brewtility.string - - -String comparison utilities - - - - -## `->spongebob-case` [:page_facing_up:](null) - -``` clojure - -(->spongebob-case s) -``` - - -Take a string `s` and coerce characters alternatively between lower and upper case. - - For example: - - ```clj - (->spongebob-case "spongebob") ;; => "sPoNgEbOb" - ``` - -## `->sporadic-case` [:page_facing_up:](null) - -``` clojure - -(->sporadic-case s) -``` - - -Take a string `s` and randomly coerce characters to either lower or upper case. - - For example: - - ```clj - (->sporadic-case "hello world") ;; => "hElLo wOrLd" - ``` - -## `includes?` [:page_facing_up:](null) - -``` clojure - -(includes? s1 s2) -(includes? s1 s2 opts) -``` - - -Checks to see if `s1` includes `s2` after each string has been modified by [`prepare-for-compare`](#brewtility.string/prepare-for-compare). - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false. - -## `prepare-for-compare` [:page_facing_up:](null) - -``` clojure - -(prepare-for-compare s) -(prepare-for-compare s {:keys [uppercase? coerce?]}) -``` - - -Takes a string `s`, trims it, and coerces it to lower case. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s` will be cast to a string via `str`. Defaults to false. - -## `same?` [:page_facing_up:](null) - -``` clojure - -(same? s1 s2) -(same? s1 s2 opts) -``` - - -Checks to see if `s1` and `s2` are equal after each string has been modified by [`prepare-for-compare`](#brewtility.string/prepare-for-compare). - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false. - ------ -# brewtility.units - - -Namespace for converting between different units of measure - - - - -## `celsius->temperature-measurement` [:page_facing_up:](null) - - -A map from measurement names to the implementation function which converts them from degrees celsius - -## `convert-temperature` [:page_facing_up:](null) - -``` clojure - -(convert-temperature temperature source-measurement target-measurement) -``` - - -Given a `temperature` in `source-measurement`, convert it to the `target-measurement`. - Supported values for `source-measurement` and `target-measurement` are enumerated in [[temperature-measurements]]. - - This function will throw an exception if unsupported measurement values are passed. - -## `convert-time` [:page_facing_up:](null) - -``` clojure - -(convert-time time-val source-measurement target-measurement) -``` - - -Given a `time-val` in `source-measurement`, convert it to the `target-measurement`. - Supported values for `source-measurement` and `target-measurement` are enumerated in [[time-measurements]]. - - This function will throw an exception if unsupported measurement values are passed. - -## `convert-volume` [:page_facing_up:](null) - -``` clojure - -(convert-volume volume source-measurement target-measurement) -``` - - -Given a `volume` in `source-measurement`, convert it to the `target-measurement`. - Supported values for `source-measurement` and `target-measurement` are enumerated in [[volume-measurements]]. - - This function will throw an exception if unsupported measurement values are passed. - -## `convert-weight` [:page_facing_up:](null) - -``` clojure - -(convert-weight weight source-measurement target-measurement) -``` - - -Given a `weight` in `source-measurement`, convert it to the `target-measurement`. - Supported values for `source-measurement` and `target-measurement` are enumerated in [[weight-measurements]]. - - This function will throw an exception if unsupported measurement values are passed. - -## `suffix-types` [:page_facing_up:](null) - - -The unit suffix types available across brewtility - -## `systems-of-meaure` [:page_facing_up:](null) - - -The systems of measure available across brewtility - -## `temperature-measurement->celsius` [:page_facing_up:](null) - - -A map from measurement names to the implementation function which converts them to degrees celsius - -## `temperature-measurements` [:page_facing_up:](null) - - -The temperature measurements available across brewtility - -## `temperature-measurements->display-name` [:page_facing_up:](null) - - -A map from measurement names to their full name and abbreviation - -## `time-measurement->minute` [:page_facing_up:](null) - - -A map from measurement names to doubles representing their fractional value to one minute - -## `time-measurements` [:page_facing_up:](null) - - -The time measurements available across brewtility - -## `time-measurements->display-name` [:page_facing_up:](null) - - -A map from measurement names to their full name and abbreviation - -## `volume-measurement->litre` [:page_facing_up:](null) - - -A map from measurement names to doubles representing their fractional value to one liter - -## `volume-measurements` [:page_facing_up:](null) - - -The volume measurements available across brewtility - -## `volume-measurements->display-name` [:page_facing_up:](null) - - -A map from measurement names to their full name and abbreviation - -## `weight-measurement->kilogram` [:page_facing_up:](null) - - -A map from measurement names to doubles representing their fractional value to one kilogram - -## `weight-measurements` [:page_facing_up:](null) - - -The weight measurements available across brewtility - -## `weight-measurements->display-name` [:page_facing_up:](null) - - -A map from measurement names to their full name and abbreviation - ------ -# brewtility.wrapping - - -Namespace for wrapping and unwrapping common-beer-format maps - - - - -## `unwrap-equipment` [:page_facing_up:](null) - -``` clojure - -(unwrap-equipment equipment-wrapper) -``` - - -Unwrap an `equipment-wrapper` map into an `equipment` map. - -## `unwrap-fermentable` [:page_facing_up:](null) - -``` clojure - -(unwrap-fermentable fermentable-wrapper) -``` - - -Unwrap a `fermentable-wrapper` map into a `fermentable` map. - -## `unwrap-fermentables` [:page_facing_up:](null) - -``` clojure - -(unwrap-fermentables fermentables-wrapper) -``` - - -Unwrap a `fermentables-wrapper` map into a `fermentables` collection. - -## `unwrap-hop` [:page_facing_up:](null) - -``` clojure - -(unwrap-hop hop-wrapper) -``` - - -Unwrap a `hop-wrapper` map into a `hop` map. - -## `unwrap-hops` [:page_facing_up:](null) - -``` clojure - -(unwrap-hops hops-wrapper) -``` - - -Unwrap a `hops-wrapper` map into a `hops` collection. - -## `unwrap-mash` [:page_facing_up:](null) - -``` clojure - -(unwrap-mash mash-wrapper) -``` - - -Unwrap a `mash-wrapper` map into a `mash` map. - -## `unwrap-mash-step` [:page_facing_up:](null) - -``` clojure - -(unwrap-mash-step mash-step-wrapper) -``` - - -Unwrap a `mash-step-wrapper` map into a `mash-step` map. - -## `unwrap-mash-steps` [:page_facing_up:](null) - -``` clojure - -(unwrap-mash-steps mash-steps-wrapper) -``` - - -Unwrap a `mash-steps-wrapper` map into a `mash-steps` collection. - -## `unwrap-misc` [:page_facing_up:](null) - -``` clojure - -(unwrap-misc misc-wrapper) -``` - - -Unwrap a `misc-wrapper` map into a `misc` map. - -## `unwrap-miscs` [:page_facing_up:](null) - -``` clojure - -(unwrap-miscs miscs-wrapper) -``` - - -Unwrap a `miscs-wrapper` map into a `miscs` collection. - -## `unwrap-recipe` [:page_facing_up:](null) - -``` clojure - -(unwrap-recipe recipe-wrapper) -``` - - -Unwrap a `recipe-wrapper` map into a `recipe` map. - -## `unwrap-recipes` [:page_facing_up:](null) - -``` clojure - -(unwrap-recipes recipes-wrapper) -``` - - -Unwrap a `recipes-wrapper` map into a `recipes` collection. - -## `unwrap-style` [:page_facing_up:](null) - -``` clojure - -(unwrap-style style-wrapper) -``` - - -Unwrap a `style-wrapper` map into a `style` map. - -## `unwrap-styles` [:page_facing_up:](null) - -``` clojure - -(unwrap-styles styles-wrapper) -``` - - -Unwrap a `styles-wrapper` map into a `styles` collection. - -## `unwrap-water` [:page_facing_up:](null) - -``` clojure - -(unwrap-water water-wrapper) -``` - - -Unwrap a `water-wrapper` map into a `water` map. - -## `unwrap-waters` [:page_facing_up:](null) - -``` clojure - -(unwrap-waters waters-wrapper) -``` - - -Unwrap a `waters-wrapper` map into a `waters` collection. - -## `unwrap-yeast` [:page_facing_up:](null) - -``` clojure - -(unwrap-yeast yeast-wrapper) -``` - - -Unwrap a `yeast-wrapper` map into a `yeast` map. - -## `unwrap-yeasts` [:page_facing_up:](null) - -``` clojure - -(unwrap-yeasts yeasts-wrapper) -``` - - -Unwrap a `yeasts-wrapper` map into a `yeasts` collection. - -## `wrap-equipment` [:page_facing_up:](null) - -``` clojure - -(wrap-equipment equipment) -``` - - -Wrap an `equipment` map into an `equipment-wrapper` map. - -## `wrap-fermentable` [:page_facing_up:](null) - -``` clojure - -(wrap-fermentable fermentable) -``` - - -Wrap a `fermentable` map into a `fermentable-wrapper` map. - -## `wrap-fermentables` [:page_facing_up:](null) - -``` clojure - -(wrap-fermentables fermentables) -``` - - -Wrap a `fermentables` collection into a `fermentables-wrapper` map. - -## `wrap-hop` [:page_facing_up:](null) - -``` clojure - -(wrap-hop hop) -``` - - -Wrap a `hop` map into a `hop-wrapper` map. - -## `wrap-hops` [:page_facing_up:](null) - -``` clojure - -(wrap-hops hops) -``` - - -Wrap a `hops` collection into a `hops-wrapper` map. - -## `wrap-mash` [:page_facing_up:](null) - -``` clojure - -(wrap-mash mash) -``` - - -Wrap a `mash` map into a `mash-wrapper` map. - -## `wrap-mash-step` [:page_facing_up:](null) - -``` clojure - -(wrap-mash-step mash-step) -``` - - -Wrap a `mash-step` map into a `mash-step-wrapper` map. - -## `wrap-mash-steps` [:page_facing_up:](null) - -``` clojure - -(wrap-mash-steps mash-steps) -``` - - -Wrap a `mash-steps` collection into a `mash-steps-wrapper` map. - -## `wrap-misc` [:page_facing_up:](null) - -``` clojure - -(wrap-misc misc) -``` - - -Wrap a `misc` map into a `misc-wrapper` map. - -## `wrap-miscs` [:page_facing_up:](null) - -``` clojure - -(wrap-miscs miscs) -``` - - -Wrap a `miscs` collection into a `miscs-wrapper` map. - -## `wrap-recipe` [:page_facing_up:](null) - -``` clojure - -(wrap-recipe recipe) -``` - - -Wrap a `recipe` map into a `recipe-wrapper` map. - -## `wrap-recipes` [:page_facing_up:](null) - -``` clojure - -(wrap-recipes recipes) -``` - - -Wrap a `recipes` collection into a `recipes-wrapper` map. - -## `wrap-style` [:page_facing_up:](null) - -``` clojure - -(wrap-style style) -``` - - -Wrap a `style` map into a `style-wrapper` map. - -## `wrap-styles` [:page_facing_up:](null) - -``` clojure - -(wrap-styles styles) -``` - - -Wrap a `styles` collection into a `styles-wrapper` map. - -## `wrap-water` [:page_facing_up:](null) - -``` clojure - -(wrap-water water) -``` - - -Wrap a `water` map into a `water-wrapper` map. - -## `wrap-waters` [:page_facing_up:](null) - -``` clojure - -(wrap-waters waters) -``` - - -Wrap a `waters` collection into a `waters-wrapper` map. - -## `wrap-yeast` [:page_facing_up:](null) - -``` clojure - -(wrap-yeast yeast) -``` - - -Wrap a `yeast` map into a `yeast-wrapper` map. - -## `wrap-yeasts` [:page_facing_up:](null) - -``` clojure - -(wrap-yeasts yeasts) -``` - - -Wrap a `yeasts` collection into a `yeasts-wrapper` map. diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index b75bd3f..1d20222 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -77,43 +77,3 @@ ([s1 s2 opts] (str/includes? (prepare-for-compare s1 opts) (prepare-for-compare s2 opts)))) - - -(defn ->sporadic-case - "Take a string `s` and randomly coerce characters to either lower or upper case. - - For example: - - ```clj - (->sporadic-case \"hello world\") ;; => \"hElLo wOrLd\" - ```" - {:added "1.3" - :see-also ["->spongebob-case"]} - [^String s] - (letfn [(random-case - [l] - (if (rand-nth [true false]) - (str/upper-case l) - (str/lower-case l)))] - (->> s - seq - (map random-case) - (apply str)))) - - -(defn ->spongebob-case - "Take a string `s` and coerce characters alternatively between lower and upper case. - - For example: - - ```clj - (->spongebob-case \"spongebob\") ;; => \"sPoNgEbOb\" - ```" - {:added "1.3" - :see-also ["->sporadic-case"]} - [^String s] - (letfn [(spongebob-case - [acc l] - (let [casing-fn (if (odd? (count acc)) str/upper-case str/lower-case)] - (str acc (casing-fn l))))] - (reduce spongebob-case "" (seq s)))) diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index 4844b90..d85a24e 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -13,6 +13,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.recipes :as recipes.format] + [com.wallbrew.spoon.string :as spoon.str] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -54,13 +55,13 @@ :type "All Grain" :version 1} equipment/sample-equipment-wrapper - fermentables/sample-fermentables-wrapper - hops/sample-hops-wrapper + fermentablespec/sample-fermentables-wrapper + hopspec/sample-hops-wrapper mash/sample-mash-wrapper - miscs/sample-miscs-wrapper - styles/sample-style-wrapper - waters/sample-waters-wrapper - yeasts/sample-yeasts-wrapper)) + miscspec/sample-miscs-wrapper + stylespec/sample-style-wrapper + waterspec/sample-waters-wrapper + yeastspec/sample-yeasts-wrapper)) (def sample-recipe-wrapper diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 1095176..1616407 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -5,6 +5,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.yeasts :as yeasts.format] + [com.wallbrew.spoon.string :as spoon.str] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index c662e5b..2bed076 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.fermentables-test (:require [brewtility.data.fermentables :as fermentable.data] [brewtility.enrich.fermentables :as fermentable.enrich] - [clojure.spec.alpha :as s] + [clojure.spec.alpha :as spec] [common-beer-format.fermentables :as fermentable.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -126,16 +126,16 @@ (deftest enrich-fermentable-tests (testing "Ensure enrichment pattern functions generate conforming data" - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)) "Enrichment pattern should produce a valid fermentable object") - (is (s/valid? ::fermentable.format/fermentable-wrapper + (is (spec/valid? ::fermentable.format/fermentable-wrapper (fermentable.enrich/enrich-fermentable-wrapper fermentable.data/sample-fermentable-wrapper)) "Enrichment pattern should produce a valid fermentable object") - (is (s/valid? ::fermentable.format/fermentables + (is (spec/valid? ::fermentable.format/fermentables (fermentable.enrich/enrich-fermentables fermentable.data/sample-fermentables)) "Enrichment pattern should produce a valid fermentable object") - (is (s/valid? ::fermentable.format/fermentables-wrapper + (is (spec/valid? ::fermentable.format/fermentables-wrapper (fermentable.enrich/enrich-fermentables-wrapper fermentable.data/sample-fermentables-wrapper)) "Enrichment pattern should produce a valid fermentable object") (testing "Static data comparison for enrichment pattern functions" @@ -163,44 +163,44 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary fermentable" (letfn [(gen-fermentable [] (fermentable.data/generate-fermentable))] - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-add-after-boil (gen-fermentable))) "enrich-add-after-boil is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-coarse-fine-diff (gen-fermentable))) "enrich-coarse-fine-diff is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-moisture (gen-fermentable))) "enrich-moisture is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-diastatic-power (gen-fermentable))) "enrich-diastatic-power is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-protein (gen-fermentable))) "enrich-protein is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-recommend-mash (gen-fermentable))) "enrich-recommend-mash is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-ibu-gallons-per-pound (gen-fermentable))) "enrich-ibu-gallons-per-pound is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-display-color (gen-fermentable))) "enrich-display-color is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-display-amount (gen-fermentable))) "enrich-display-amount is a function to and from common-beer-format.fermentable/fermentable") - (is (s/valid? ::fermentable.format/fermentable + (is (spec/valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-fermentable (gen-fermentable))) "enrich-fermentable is a function to and from common-beer-format.fermentable/fermentable"))) (testing "Ensure enrichment pattern works against arbitrary fermentable wrappers" - (is (s/valid? ::fermentable.format/fermentable-wrapper + (is (spec/valid? ::fermentable.format/fermentable-wrapper (fermentable.enrich/enrich-fermentable-wrapper (fermentable.data/generate-fermentable-wrapper))) "enrich-fermentable-wrapper is a function to and from common-beer-format.fermentable/fermentable-wrapper") - (is (s/valid? ::fermentable.format/fermentables + (is (spec/valid? ::fermentable.format/fermentables (fermentable.enrich/enrich-fermentables (fermentable.data/generate-fermentables))) "enrich-fermentables is a function to and from common-beer-format.fermentable/fermentables") - (is (s/valid? ::fermentable.format/fermentables-wrapper + (is (spec/valid? ::fermentable.format/fermentables-wrapper (fermentable.enrich/enrich-fermentables-wrapper (fermentable.data/generate-fermentables-wrapper))) "enrich-fermentables-wrapper is a function to and from common-beer-format.fermentable/fermentables-wrapper"))) diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc index 227ba9d..9c85be0 100644 --- a/test/brewtility/enrich/hops_test.cljc +++ b/test/brewtility/enrich/hops_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.hops-test (:require [brewtility.data.hops :as hop.data] [brewtility.enrich.hops :as hop.enrich] - [clojure.spec.alpha :as s] + [clojure.spec.alpha :as spec] [common-beer-format.hops :as hop.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -13,16 +13,16 @@ (deftest enrich-hop-tests (testing "Ensure enrichment pattern functions generate conforming data" - (is (s/valid? ::hop.format/hop + (is (spec/valid? ::hop.format/hop (hop.enrich/enrich-hop hop.data/sample-hop)) "Enrichment pattern should produce a valid hop object") - (is (s/valid? ::hop.format/hop-wrapper + (is (spec/valid? ::hop.format/hop-wrapper (hop.enrich/enrich-hop-wrapper hop.data/sample-hop-wrapper)) "Enrichment pattern should produce a valid hop object") - (is (s/valid? ::hop.format/hops + (is (spec/valid? ::hop.format/hops (hop.enrich/enrich-hops hop.data/sample-hops)) "Enrichment pattern should produce a valid hop object") - (is (s/valid? ::hop.format/hops-wrapper + (is (spec/valid? ::hop.format/hops-wrapper (hop.enrich/enrich-hops-wrapper hop.data/sample-hops-wrapper)) "Enrichment pattern should produce a valid hop object") (testing "Static data comparison for enrichment pattern functions" @@ -41,20 +41,20 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary hop" (letfn [(gen-hop [] (hop.data/generate-hop))] - (is (s/valid? ::hop.format/hop + (is (spec/valid? ::hop.format/hop (hop.enrich/enrich-display-amount (gen-hop))) - "enrich-display-amount is a function to and from common-beer-format.hops/hop") - (is (s/valid? ::hop.format/hop + "enrich-display-amount is a function to and from common-beer-format.hopspec/hop") + (is (spec/valid? ::hop.format/hop (hop.enrich/enrich-display-time (gen-hop))) - "enrich-display-time is a function to and from common-beer-format.hops/hop"))) + "enrich-display-time is a function to and from common-beer-format.hopspec/hop"))) (testing "Ensure enrichment pattern works against arbitrary hop wrappers" - (is (s/valid? ::hop.format/hop-wrapper + (is (spec/valid? ::hop.format/hop-wrapper (hop.enrich/enrich-hop-wrapper (hop.data/generate-hop-wrapper))) - "enrich-hop-wrapper is a function to and from common-beer-format.hops/hop-wrapper") - (is (s/valid? ::hop.format/hops + "enrich-hop-wrapper is a function to and from common-beer-format.hopspec/hop-wrapper") + (is (spec/valid? ::hop.format/hops (hop.enrich/enrich-hops (hop.data/generate-hops))) - "enrich-hops is a function to and from common-beer-format.hops/hops") - (is (s/valid? ::hop.format/hops-wrapper + "enrich-hops is a function to and from common-beer-format.hopspec/hops") + (is (spec/valid? ::hop.format/hops-wrapper (hop.enrich/enrich-hops-wrapper (hop.data/generate-hops-wrapper))) - "enrich-hops-wrapper is a function to and from common-beer-format.hops/hops-wrapper"))) + "enrich-hops-wrapper is a function to and from common-beer-format.hopspec/hops-wrapper"))) diff --git a/test/brewtility/enrich/mash_test.cljc b/test/brewtility/enrich/mash_test.cljc index 3b1b735..4be1467 100644 --- a/test/brewtility/enrich/mash_test.cljc +++ b/test/brewtility/enrich/mash_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.mash-test (:require [brewtility.data.mash :as mash.data] [brewtility.enrich.mash :as mash.enrich] - [clojure.spec.alpha :as s] + [clojure.spec.alpha :as spec] [common-beer-format.mash :as mash.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -9,44 +9,44 @@ (deftest static-enrichment-tests (testing "Ensure enrichment pattern works against the static test mash steps" - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-display-step-temperature mash.data/sample-mash-step)) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-display-infuse-amount mash.data/sample-mash-step)) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-mash-step mash.data/sample-mash-step)) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against static test mash step wrappers" - (is (s/valid? ::mash.format/mash-step-wrapper + (is (spec/valid? ::mash.format/mash-step-wrapper (mash.enrich/enrich-mash-step-wrapper mash.data/sample-mash-step-wrapper)) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against static test mash steps" - (is (s/valid? ::mash.format/mash-steps + (is (spec/valid? ::mash.format/mash-steps (mash.enrich/enrich-mash-steps mash.data/sample-mash-steps)) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against static test mash steps wrapper" - (is (s/valid? ::mash.format/mash-steps + (is (spec/valid? ::mash.format/mash-steps (:mash-steps (mash.enrich/enrich-mash-steps-wrapper mash.data/sample-mash-steps-wrapper))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against static test mash" - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-grain-temperature mash.data/sample-mash)) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-tun-temperature mash.data/sample-mash)) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-sparge-temperature mash.data/sample-mash)) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-tun-weight mash.data/sample-mash)) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-mash mash.data/sample-mash)) "enrich-mash is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-wrapper + (is (spec/valid? ::mash.format/mash-wrapper (mash.enrich/enrich-mash-wrapper mash.data/sample-mash-wrapper)) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper")) (testing "Static data comparison for enrichment pattern functions" @@ -67,43 +67,43 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary mash steps" - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-display-step-temperature (mash.data/generate-mash-step))) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-display-infuse-amount (mash.data/generate-mash-step))) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-step + (is (spec/valid? ::mash.format/mash-step (mash.enrich/enrich-mash-step (mash.data/generate-mash-step))) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against arbitrary mash step wrappers" - (is (s/valid? ::mash.format/mash-step-wrapper + (is (spec/valid? ::mash.format/mash-step-wrapper (mash.enrich/enrich-mash-step-wrapper (mash.data/generate-mash-step-wrapper))) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash steps" - (is (s/valid? ::mash.format/mash-steps + (is (spec/valid? ::mash.format/mash-steps (mash.enrich/enrich-mash-steps (mash.data/generate-mash-steps))) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against arbitrary mash steps wrapper" - (is (s/valid? ::mash.format/mash-steps + (is (spec/valid? ::mash.format/mash-steps (:mash-steps (mash.enrich/enrich-mash-steps-wrapper (mash.data/generate-mash-steps-wrapper)))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash" - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-grain-temperature (mash.data/generate-mash))) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-tun-temperature (mash.data/generate-mash))) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-sparge-temperature (mash.data/generate-mash))) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-display-tun-weight (mash.data/generate-mash))) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash + (is (spec/valid? ::mash.format/mash (mash.enrich/enrich-mash (mash.data/generate-mash))) "enrich-mash is a function to and from common-beer-format.mash/mash") - (is (s/valid? ::mash.format/mash-wrapper + (is (spec/valid? ::mash.format/mash-wrapper (mash.enrich/enrich-mash-wrapper (mash.data/generate-mash-wrapper))) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper"))) diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc index 5b38844..bc8a688 100644 --- a/test/brewtility/string_test.cljc +++ b/test/brewtility/string_test.cljc @@ -4,11 +4,6 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) -(defn rand-str - "Generate a random string of length `len`." - [len] - (apply str (take len (repeatedly #(char (+ (rand 26) 65)))))) - (deftest prepare-for-compare-test (testing "Strings are appropriately re-cased and trimmed of whitespace" @@ -55,20 +50,3 @@ (is (true? (sut/includes? nil "" {:coerce? true}))) (is (true? (sut/includes? :carrot ":CARROT" {:coerce? true}))))) - -(deftest ->sporadic-case-tests - (testing "Re-cased strings are the `same` as their original value" - (is (sut/same? "clojure" (sut/->sporadic-case "clojure"))) - (is (sut/same? "100 lines of clojure" (sut/->sporadic-case "100 lines of clojure"))) - (is (sut/same? "clojure" (sut/->sporadic-case "CLOJURE")))) - (testing "Re-cased strings are stings" - (is (string? (sut/->sporadic-case (rand-str 1000)))))) - - -(deftest ->spongebob-case-tests - (testing "Re-cased strings are the `same` as their original value" - (is (sut/same? "clojure" (sut/->spongebob-case "clojure"))) - (is (sut/same? "100 lines of clojure" (sut/->spongebob-case "100 lines of clojure"))) - (is (sut/same? "clojure" (sut/->spongebob-case "CLOJURE")))) - (testing "Re-cased strings are stings" - (is (string? (sut/->spongebob-case (rand-str 1000)))))) From 240a8d3852b1e05e3d105c40c2fd85006f12714f Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 7 Jan 2023 23:35:35 +0000 Subject: [PATCH 15/44] Use spoons test functionality for spec --- test/brewtility/data/recipes.cljc | 13 +++-- test/brewtility/data/yeasts.cljc | 1 - test/brewtility/enrich/equipment_test.cljc | 44 ++++++++-------- test/brewtility/enrich/fermentables_test.cljc | 36 ++++++------- test/brewtility/enrich/hops_test.cljc | 20 ++++---- test/brewtility/enrich/mash_test.cljc | 50 +++++++++---------- 6 files changed, 81 insertions(+), 83 deletions(-) diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index d85a24e..4844b90 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -13,7 +13,6 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.recipes :as recipes.format] - [com.wallbrew.spoon.string :as spoon.str] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -55,13 +54,13 @@ :type "All Grain" :version 1} equipment/sample-equipment-wrapper - fermentablespec/sample-fermentables-wrapper - hopspec/sample-hops-wrapper + fermentables/sample-fermentables-wrapper + hops/sample-hops-wrapper mash/sample-mash-wrapper - miscspec/sample-miscs-wrapper - stylespec/sample-style-wrapper - waterspec/sample-waters-wrapper - yeastspec/sample-yeasts-wrapper)) + miscs/sample-miscs-wrapper + styles/sample-style-wrapper + waters/sample-waters-wrapper + yeasts/sample-yeasts-wrapper)) (def sample-recipe-wrapper diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 1616407..1095176 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -5,7 +5,6 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.yeasts :as yeasts.format] - [com.wallbrew.spoon.string :as spoon.str] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index e928205..c69ea1b 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.equipment-test (:require [brewtility.data.equipment :as equipment.data] [brewtility.enrich.equipment :as equipment.enrich] - [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.equipment :as equipment.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -67,8 +67,8 @@ :boil-size-suffix :full}) :display-boil-size)) "Broad settings can be overriden with boil-size specific settings") - (is (spec/valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) + (is (spoon.spec/test-valid? ::equipment.format/equipment + (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -100,7 +100,7 @@ :batch-size-suffix :full}) :display-batch-size)) "Broad settings can be overriden with batch-size specific settings") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -133,7 +133,7 @@ :tun-volume-suffix :full}) :display-tun-volume)) "Broad settings can be overriden with tun-volume specific settings") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -166,7 +166,7 @@ :tun-weight-suffix :full}) :display-tun-weight)) "Broad settings can be overriden with tun-weight specific settings") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -204,7 +204,7 @@ equipment.enrich/enrich-display-top-up-water :display-top-up-water)) ":display-top-up-water is not added if trub-chiller-loss is not present") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -242,7 +242,7 @@ equipment.enrich/enrich-display-lauter-deadspace :display-trub-chiller-loss)) ":display-trub-chiller-loss is not added if trub-chiller-loss is not present") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -282,7 +282,7 @@ :lauter-deadspace-suffix :full}) :display-lauter-deadspace)) "Display value will not be set if lauter-deadspace is not present") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -320,14 +320,14 @@ equipment.enrich/enrich-display-top-up-kettle :display-top-up-kettle)) ":display-top-up-kettle is not added if top-up-kettle is not present") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-equipment-tests (testing "Ensure enrichment pattern works for all equipment" - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object") (is (= {:display-top-up-kettle "0.132 gal" @@ -387,7 +387,7 @@ (deftest enrich-equipment-wrapper-tests (testing "Ensure enrichment pattern works for all equipment-wrapper" - (is (spec/valid? ::equipment.format/equipment-wrapper + (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) "Enrichment pattern should produce a valid equipment-wrapper object") (is (= {:equipment {:display-top-up-kettle "0.132 gal" @@ -451,35 +451,35 @@ ;; Which puts tight constraints on the test data, meaning actual generation of values would be ;; extremely unlikely or require highly complex generators. (letfn [(gen-equipment [] (assoc (equipment.data/generate-equipment) :calc-boil-volume false))] - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-boil-size (gen-equipment))) "enrich-display-boil-size is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-batch-size (gen-equipment))) "enrich-display-batch-size is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-volume (gen-equipment))) "enrich-display-tun-volume is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-weight (gen-equipment))) "enrich-display-tun-weight is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-top-up-water (gen-equipment))) "enrich-display-top-up-water is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) "enrich-display-trub-chiller-loss is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) "enrich-display-lauter-deadspace is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) "enrich-display-top-up-kettle is a function to and from common-beer-format.equipment/equipment") - (is (spec/valid? ::equipment.format/equipment + (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-equipment (gen-equipment))) "enrich-equipment is a function to and from common-beer-format.equipment/equipment"))) (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" - (is (spec/valid? ::equipment.format/equipment-wrapper + (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper (equipment.enrich/enrich-equipment-wrapper (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index 2bed076..3474157 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.fermentables-test (:require [brewtility.data.fermentables :as fermentable.data] [brewtility.enrich.fermentables :as fermentable.enrich] - [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.fermentables :as fermentable.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -126,16 +126,16 @@ (deftest enrich-fermentable-tests (testing "Ensure enrichment pattern functions generate conforming data" - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)) "Enrichment pattern should produce a valid fermentable object") - (is (spec/valid? ::fermentable.format/fermentable-wrapper + (is (spoon.spec/test-valid? ::fermentable.format/fermentable-wrapper (fermentable.enrich/enrich-fermentable-wrapper fermentable.data/sample-fermentable-wrapper)) "Enrichment pattern should produce a valid fermentable object") - (is (spec/valid? ::fermentable.format/fermentables + (is (spoon.spec/test-valid? ::fermentable.format/fermentables (fermentable.enrich/enrich-fermentables fermentable.data/sample-fermentables)) "Enrichment pattern should produce a valid fermentable object") - (is (spec/valid? ::fermentable.format/fermentables-wrapper + (is (spoon.spec/test-valid? ::fermentable.format/fermentables-wrapper (fermentable.enrich/enrich-fermentables-wrapper fermentable.data/sample-fermentables-wrapper)) "Enrichment pattern should produce a valid fermentable object") (testing "Static data comparison for enrichment pattern functions" @@ -163,44 +163,44 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary fermentable" (letfn [(gen-fermentable [] (fermentable.data/generate-fermentable))] - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-add-after-boil (gen-fermentable))) "enrich-add-after-boil is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-coarse-fine-diff (gen-fermentable))) "enrich-coarse-fine-diff is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-moisture (gen-fermentable))) "enrich-moisture is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-diastatic-power (gen-fermentable))) "enrich-diastatic-power is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-protein (gen-fermentable))) "enrich-protein is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-recommend-mash (gen-fermentable))) "enrich-recommend-mash is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-ibu-gallons-per-pound (gen-fermentable))) "enrich-ibu-gallons-per-pound is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-display-color (gen-fermentable))) "enrich-display-color is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-display-amount (gen-fermentable))) "enrich-display-amount is a function to and from common-beer-format.fermentable/fermentable") - (is (spec/valid? ::fermentable.format/fermentable + (is (spoon.spec/test-valid? ::fermentable.format/fermentable (fermentable.enrich/enrich-fermentable (gen-fermentable))) "enrich-fermentable is a function to and from common-beer-format.fermentable/fermentable"))) (testing "Ensure enrichment pattern works against arbitrary fermentable wrappers" - (is (spec/valid? ::fermentable.format/fermentable-wrapper + (is (spoon.spec/test-valid? ::fermentable.format/fermentable-wrapper (fermentable.enrich/enrich-fermentable-wrapper (fermentable.data/generate-fermentable-wrapper))) "enrich-fermentable-wrapper is a function to and from common-beer-format.fermentable/fermentable-wrapper") - (is (spec/valid? ::fermentable.format/fermentables + (is (spoon.spec/test-valid? ::fermentable.format/fermentables (fermentable.enrich/enrich-fermentables (fermentable.data/generate-fermentables))) "enrich-fermentables is a function to and from common-beer-format.fermentable/fermentables") - (is (spec/valid? ::fermentable.format/fermentables-wrapper + (is (spoon.spec/test-valid? ::fermentable.format/fermentables-wrapper (fermentable.enrich/enrich-fermentables-wrapper (fermentable.data/generate-fermentables-wrapper))) "enrich-fermentables-wrapper is a function to and from common-beer-format.fermentable/fermentables-wrapper"))) diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc index 9c85be0..5a36527 100644 --- a/test/brewtility/enrich/hops_test.cljc +++ b/test/brewtility/enrich/hops_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.hops-test (:require [brewtility.data.hops :as hop.data] [brewtility.enrich.hops :as hop.enrich] - [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.hops :as hop.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -13,16 +13,16 @@ (deftest enrich-hop-tests (testing "Ensure enrichment pattern functions generate conforming data" - (is (spec/valid? ::hop.format/hop + (is (spoon.spec/test-valid? ::hop.format/hop (hop.enrich/enrich-hop hop.data/sample-hop)) "Enrichment pattern should produce a valid hop object") - (is (spec/valid? ::hop.format/hop-wrapper + (is (spoon.spec/test-valid? ::hop.format/hop-wrapper (hop.enrich/enrich-hop-wrapper hop.data/sample-hop-wrapper)) "Enrichment pattern should produce a valid hop object") - (is (spec/valid? ::hop.format/hops + (is (spoon.spec/test-valid? ::hop.format/hops (hop.enrich/enrich-hops hop.data/sample-hops)) "Enrichment pattern should produce a valid hop object") - (is (spec/valid? ::hop.format/hops-wrapper + (is (spoon.spec/test-valid? ::hop.format/hops-wrapper (hop.enrich/enrich-hops-wrapper hop.data/sample-hops-wrapper)) "Enrichment pattern should produce a valid hop object") (testing "Static data comparison for enrichment pattern functions" @@ -41,20 +41,20 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary hop" (letfn [(gen-hop [] (hop.data/generate-hop))] - (is (spec/valid? ::hop.format/hop + (is (spoon.spec/test-valid? ::hop.format/hop (hop.enrich/enrich-display-amount (gen-hop))) "enrich-display-amount is a function to and from common-beer-format.hopspec/hop") - (is (spec/valid? ::hop.format/hop + (is (spoon.spec/test-valid? ::hop.format/hop (hop.enrich/enrich-display-time (gen-hop))) "enrich-display-time is a function to and from common-beer-format.hopspec/hop"))) (testing "Ensure enrichment pattern works against arbitrary hop wrappers" - (is (spec/valid? ::hop.format/hop-wrapper + (is (spoon.spec/test-valid? ::hop.format/hop-wrapper (hop.enrich/enrich-hop-wrapper (hop.data/generate-hop-wrapper))) "enrich-hop-wrapper is a function to and from common-beer-format.hopspec/hop-wrapper") - (is (spec/valid? ::hop.format/hops + (is (spoon.spec/test-valid? ::hop.format/hops (hop.enrich/enrich-hops (hop.data/generate-hops))) "enrich-hops is a function to and from common-beer-format.hopspec/hops") - (is (spec/valid? ::hop.format/hops-wrapper + (is (spoon.spec/test-valid? ::hop.format/hops-wrapper (hop.enrich/enrich-hops-wrapper (hop.data/generate-hops-wrapper))) "enrich-hops-wrapper is a function to and from common-beer-format.hopspec/hops-wrapper"))) diff --git a/test/brewtility/enrich/mash_test.cljc b/test/brewtility/enrich/mash_test.cljc index 4be1467..a54670c 100644 --- a/test/brewtility/enrich/mash_test.cljc +++ b/test/brewtility/enrich/mash_test.cljc @@ -1,7 +1,7 @@ (ns brewtility.enrich.mash-test (:require [brewtility.data.mash :as mash.data] [brewtility.enrich.mash :as mash.enrich] - [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.mash :as mash.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -9,44 +9,44 @@ (deftest static-enrichment-tests (testing "Ensure enrichment pattern works against the static test mash steps" - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-display-step-temperature mash.data/sample-mash-step)) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-display-infuse-amount mash.data/sample-mash-step)) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-mash-step mash.data/sample-mash-step)) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against static test mash step wrappers" - (is (spec/valid? ::mash.format/mash-step-wrapper + (is (spoon.spec/test-valid? ::mash.format/mash-step-wrapper (mash.enrich/enrich-mash-step-wrapper mash.data/sample-mash-step-wrapper)) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against static test mash steps" - (is (spec/valid? ::mash.format/mash-steps + (is (spoon.spec/test-valid? ::mash.format/mash-steps (mash.enrich/enrich-mash-steps mash.data/sample-mash-steps)) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against static test mash steps wrapper" - (is (spec/valid? ::mash.format/mash-steps + (is (spoon.spec/test-valid? ::mash.format/mash-steps (:mash-steps (mash.enrich/enrich-mash-steps-wrapper mash.data/sample-mash-steps-wrapper))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against static test mash" - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-grain-temperature mash.data/sample-mash)) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-tun-temperature mash.data/sample-mash)) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-sparge-temperature mash.data/sample-mash)) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-tun-weight mash.data/sample-mash)) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-mash mash.data/sample-mash)) "enrich-mash is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-wrapper + (is (spoon.spec/test-valid? ::mash.format/mash-wrapper (mash.enrich/enrich-mash-wrapper mash.data/sample-mash-wrapper)) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper")) (testing "Static data comparison for enrichment pattern functions" @@ -67,43 +67,43 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary mash steps" - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-display-step-temperature (mash.data/generate-mash-step))) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-display-infuse-amount (mash.data/generate-mash-step))) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-step + (is (spoon.spec/test-valid? ::mash.format/mash-step (mash.enrich/enrich-mash-step (mash.data/generate-mash-step))) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against arbitrary mash step wrappers" - (is (spec/valid? ::mash.format/mash-step-wrapper + (is (spoon.spec/test-valid? ::mash.format/mash-step-wrapper (mash.enrich/enrich-mash-step-wrapper (mash.data/generate-mash-step-wrapper))) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash steps" - (is (spec/valid? ::mash.format/mash-steps + (is (spoon.spec/test-valid? ::mash.format/mash-steps (mash.enrich/enrich-mash-steps (mash.data/generate-mash-steps))) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against arbitrary mash steps wrapper" - (is (spec/valid? ::mash.format/mash-steps + (is (spoon.spec/test-valid? ::mash.format/mash-steps (:mash-steps (mash.enrich/enrich-mash-steps-wrapper (mash.data/generate-mash-steps-wrapper)))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash" - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-grain-temperature (mash.data/generate-mash))) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-tun-temperature (mash.data/generate-mash))) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-sparge-temperature (mash.data/generate-mash))) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-display-tun-weight (mash.data/generate-mash))) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash + (is (spoon.spec/test-valid? ::mash.format/mash (mash.enrich/enrich-mash (mash.data/generate-mash))) "enrich-mash is a function to and from common-beer-format.mash/mash") - (is (spec/valid? ::mash.format/mash-wrapper + (is (spoon.spec/test-valid? ::mash.format/mash-wrapper (mash.enrich/enrich-mash-wrapper (mash.data/generate-mash-wrapper))) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper"))) From 61f068847255805847c1abcee7aff632472f7ea8 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 7 Jan 2023 23:52:49 +0000 Subject: [PATCH 16/44] Fix linting --- src/brewtility/enrich/fermentables.cljc | 2 +- src/brewtility/enrich/miscs.cljc | 4 +- src/brewtility/string.cljc | 5 ++ test/brewtility/data/equipment.cljc | 1 + test/brewtility/data/fermentables.cljc | 1 + test/brewtility/data/hops.cljc | 1 + test/brewtility/data/mash.cljc | 1 + test/brewtility/data/miscs.cljc | 1 + test/brewtility/data/recipes.cljc | 1 + test/brewtility/data/styles.cljc | 1 + test/brewtility/data/waters.cljc | 1 + test/brewtility/data/yeasts.cljc | 1 + test/brewtility/enrich/equipment_test.cljc | 40 ++++++++-------- test/brewtility/enrich/fermentables_test.cljc | 34 ++++++------- test/brewtility/enrich/hops_test.cljc | 18 +++---- test/brewtility/enrich/mash_test.cljc | 48 +++++++++---------- test/brewtility/string_test.cljc | 1 - 17 files changed, 86 insertions(+), 75 deletions(-) diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index fb4ce4e..b5b6515 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -24,7 +24,7 @@ "enrich-fermentables" "enrich-fermentables-wrapper"]} ([fermentable] (enrich-add-after-boil fermentable {})) - ([fermentable _opts] ;; Used to maintain signature parity with enricher pattern functions + ([fermentable _opts] ; Used to maintain signature parity with enricher pattern functions (if (contains? fermentable :add-after-boil) fermentable (assoc fermentable :add-after-boil false)))) diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index 30f7892..eeca5fb 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -21,7 +21,7 @@ "enrich-miscs" "enrich-miscs-wrapper"]} ([misc] (enrich-amount-is-weight misc {})) - ([misc _] ;; Used to maintain signature parity with enricher pattern functions + ([misc _] ; Used to maintain signature parity with enricher pattern functions (if (contains? misc :amount-is-weight) misc (assoc misc :amount-is-weight false)))) @@ -107,8 +107,6 @@ (impl/enrich-displayable-volume misc options))))) - - (defn enrich-misc "An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index 1d20222..0d2b526 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -5,13 +5,18 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} + + (def cast-to-uppercase? "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. Commonly, this is set for the `options` argument of `same?` and `includes?`. This option will be enabled if this key's value is truthy, and is disabled by default." :uppercase?) + #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} + + (def coerce-to-compare? "An option map key to coerce values to strings in `prepare-for-compare`. Commonly, this is set for the `options` argument of `same?` and `includes?`. diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index 76b7864..1072d2a 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.equipment "Namespace for static and generative test data for `common-beer-format.equipment/equipment` and `common-beer-format.equipment/equipment-wrapper`" (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.equipment :as equipment.format] diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index 544030e..6d06e40 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.fermentables "Namespace for static and generative test data for `common-beer-format.fermentables/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.fermentables :as fermentables.format] diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index 0ed0a19..3d33e37 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.hops "Namespace for static and generative test data for `common-beer-format.hops/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index cb4f108..aaf6999 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.mash "Namespace for static and generative test data for `common-beer-format.mash/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.mash :as mash.format] diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index b40f46f..2392431 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.miscs "Namespace for static and generative test data for `common-beer-format.miscs/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.miscs :as miscs.format] diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index 4844b90..0a24b3e 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -9,6 +9,7 @@ [brewtility.data.waters :as waters] [brewtility.data.yeasts :as yeasts] [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 22d7747..348d24c 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.styles "Namespace for static and generative test data for `common-beer-format.stylespec/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.styles :as style.format] diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 19b7144..88e08fe 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.waters "Namespace for static and generative test data for `common-beer-format.waters/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.waters :as waters.format] diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 1095176..d10259e 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -1,6 +1,7 @@ (ns brewtility.data.yeasts "Namespace for static and generative test data for `common-beer-format.yeasts/*` specs." (:require [clojure.spec.alpha :as spec] + [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index c69ea1b..9c090c7 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -101,7 +101,7 @@ :display-batch-size)) "Broad settings can be overriden with batch-size specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -134,7 +134,7 @@ :display-tun-volume)) "Broad settings can be overriden with tun-volume specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -167,7 +167,7 @@ :display-tun-weight)) "Broad settings can be overriden with tun-weight specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -205,7 +205,7 @@ :display-top-up-water)) ":display-top-up-water is not added if trub-chiller-loss is not present") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-top-up-water equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -243,7 +243,7 @@ :display-trub-chiller-loss)) ":display-trub-chiller-loss is not added if trub-chiller-loss is not present") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-trub-chiller-loss equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -283,7 +283,7 @@ :display-lauter-deadspace)) "Display value will not be set if lauter-deadspace is not present") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-lauter-deadspace equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -321,14 +321,14 @@ :display-top-up-kettle)) ":display-top-up-kettle is not added if top-up-kettle is not present") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) + (equipment.enrich/enrich-display-top-up-kettle equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) (deftest enrich-equipment-tests (testing "Ensure enrichment pattern works for all equipment" (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) + (equipment.enrich/enrich-equipment equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object") (is (= {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -388,7 +388,7 @@ (deftest enrich-equipment-wrapper-tests (testing "Ensure enrichment pattern works for all equipment-wrapper" (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper - (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) + (equipment.enrich/enrich-equipment-wrapper equipment.data/sample-equipment-wrapper)) "Enrichment pattern should produce a valid equipment-wrapper object") (is (= {:equipment {:display-top-up-kettle "0.132 gal" :display-batch-size "5.257 gal" @@ -452,35 +452,35 @@ ;; extremely unlikely or require highly complex generators. (letfn [(gen-equipment [] (assoc (equipment.data/generate-equipment) :calc-boil-volume false))] (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-boil-size (gen-equipment))) + (equipment.enrich/enrich-display-boil-size (gen-equipment))) "enrich-display-boil-size is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-batch-size (gen-equipment))) + (equipment.enrich/enrich-display-batch-size (gen-equipment))) "enrich-display-batch-size is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-volume (gen-equipment))) + (equipment.enrich/enrich-display-tun-volume (gen-equipment))) "enrich-display-tun-volume is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-tun-weight (gen-equipment))) + (equipment.enrich/enrich-display-tun-weight (gen-equipment))) "enrich-display-tun-weight is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-water (gen-equipment))) + (equipment.enrich/enrich-display-top-up-water (gen-equipment))) "enrich-display-top-up-water is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) + (equipment.enrich/enrich-display-trub-chiller-loss (gen-equipment))) "enrich-display-trub-chiller-loss is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) + (equipment.enrich/enrich-display-lauter-deadspace (gen-equipment))) "enrich-display-lauter-deadspace is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) + (equipment.enrich/enrich-display-top-up-kettle (gen-equipment))) "enrich-display-top-up-kettle is a function to and from common-beer-format.equipment/equipment") (is (spoon.spec/test-valid? ::equipment.format/equipment - (equipment.enrich/enrich-equipment (gen-equipment))) + (equipment.enrich/enrich-equipment (gen-equipment))) "enrich-equipment is a function to and from common-beer-format.equipment/equipment"))) (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper - (equipment.enrich/enrich-equipment-wrapper - (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) + (equipment.enrich/enrich-equipment-wrapper + (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index 3474157..7fd183d 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -127,16 +127,16 @@ (deftest enrich-fermentable-tests (testing "Ensure enrichment pattern functions generate conforming data" (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)) + (fermentable.enrich/enrich-fermentable fermentable.data/sample-fermentable)) "Enrichment pattern should produce a valid fermentable object") (is (spoon.spec/test-valid? ::fermentable.format/fermentable-wrapper - (fermentable.enrich/enrich-fermentable-wrapper fermentable.data/sample-fermentable-wrapper)) + (fermentable.enrich/enrich-fermentable-wrapper fermentable.data/sample-fermentable-wrapper)) "Enrichment pattern should produce a valid fermentable object") (is (spoon.spec/test-valid? ::fermentable.format/fermentables - (fermentable.enrich/enrich-fermentables fermentable.data/sample-fermentables)) + (fermentable.enrich/enrich-fermentables fermentable.data/sample-fermentables)) "Enrichment pattern should produce a valid fermentable object") (is (spoon.spec/test-valid? ::fermentable.format/fermentables-wrapper - (fermentable.enrich/enrich-fermentables-wrapper fermentable.data/sample-fermentables-wrapper)) + (fermentable.enrich/enrich-fermentables-wrapper fermentable.data/sample-fermentables-wrapper)) "Enrichment pattern should produce a valid fermentable object") (testing "Static data comparison for enrichment pattern functions" (is (= {:amount 0.45 @@ -164,43 +164,43 @@ (testing "Ensure enrichment pattern works against arbitrary fermentable" (letfn [(gen-fermentable [] (fermentable.data/generate-fermentable))] (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-add-after-boil (gen-fermentable))) + (fermentable.enrich/enrich-add-after-boil (gen-fermentable))) "enrich-add-after-boil is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-coarse-fine-diff (gen-fermentable))) + (fermentable.enrich/enrich-coarse-fine-diff (gen-fermentable))) "enrich-coarse-fine-diff is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-moisture (gen-fermentable))) + (fermentable.enrich/enrich-moisture (gen-fermentable))) "enrich-moisture is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-diastatic-power (gen-fermentable))) + (fermentable.enrich/enrich-diastatic-power (gen-fermentable))) "enrich-diastatic-power is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-protein (gen-fermentable))) + (fermentable.enrich/enrich-protein (gen-fermentable))) "enrich-protein is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-recommend-mash (gen-fermentable))) + (fermentable.enrich/enrich-recommend-mash (gen-fermentable))) "enrich-recommend-mash is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-ibu-gallons-per-pound (gen-fermentable))) + (fermentable.enrich/enrich-ibu-gallons-per-pound (gen-fermentable))) "enrich-ibu-gallons-per-pound is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-display-color (gen-fermentable))) + (fermentable.enrich/enrich-display-color (gen-fermentable))) "enrich-display-color is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-display-amount (gen-fermentable))) + (fermentable.enrich/enrich-display-amount (gen-fermentable))) "enrich-display-amount is a function to and from common-beer-format.fermentable/fermentable") (is (spoon.spec/test-valid? ::fermentable.format/fermentable - (fermentable.enrich/enrich-fermentable (gen-fermentable))) + (fermentable.enrich/enrich-fermentable (gen-fermentable))) "enrich-fermentable is a function to and from common-beer-format.fermentable/fermentable"))) (testing "Ensure enrichment pattern works against arbitrary fermentable wrappers" (is (spoon.spec/test-valid? ::fermentable.format/fermentable-wrapper - (fermentable.enrich/enrich-fermentable-wrapper (fermentable.data/generate-fermentable-wrapper))) + (fermentable.enrich/enrich-fermentable-wrapper (fermentable.data/generate-fermentable-wrapper))) "enrich-fermentable-wrapper is a function to and from common-beer-format.fermentable/fermentable-wrapper") (is (spoon.spec/test-valid? ::fermentable.format/fermentables - (fermentable.enrich/enrich-fermentables (fermentable.data/generate-fermentables))) + (fermentable.enrich/enrich-fermentables (fermentable.data/generate-fermentables))) "enrich-fermentables is a function to and from common-beer-format.fermentable/fermentables") (is (spoon.spec/test-valid? ::fermentable.format/fermentables-wrapper - (fermentable.enrich/enrich-fermentables-wrapper (fermentable.data/generate-fermentables-wrapper))) + (fermentable.enrich/enrich-fermentables-wrapper (fermentable.data/generate-fermentables-wrapper))) "enrich-fermentables-wrapper is a function to and from common-beer-format.fermentable/fermentables-wrapper"))) diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc index 5a36527..ef95b0f 100644 --- a/test/brewtility/enrich/hops_test.cljc +++ b/test/brewtility/enrich/hops_test.cljc @@ -14,16 +14,16 @@ (deftest enrich-hop-tests (testing "Ensure enrichment pattern functions generate conforming data" (is (spoon.spec/test-valid? ::hop.format/hop - (hop.enrich/enrich-hop hop.data/sample-hop)) + (hop.enrich/enrich-hop hop.data/sample-hop)) "Enrichment pattern should produce a valid hop object") (is (spoon.spec/test-valid? ::hop.format/hop-wrapper - (hop.enrich/enrich-hop-wrapper hop.data/sample-hop-wrapper)) + (hop.enrich/enrich-hop-wrapper hop.data/sample-hop-wrapper)) "Enrichment pattern should produce a valid hop object") (is (spoon.spec/test-valid? ::hop.format/hops - (hop.enrich/enrich-hops hop.data/sample-hops)) + (hop.enrich/enrich-hops hop.data/sample-hops)) "Enrichment pattern should produce a valid hop object") (is (spoon.spec/test-valid? ::hop.format/hops-wrapper - (hop.enrich/enrich-hops-wrapper hop.data/sample-hops-wrapper)) + (hop.enrich/enrich-hops-wrapper hop.data/sample-hops-wrapper)) "Enrichment pattern should produce a valid hop object") (testing "Static data comparison for enrichment pattern functions" (is (= {:amount 0.0638 @@ -42,19 +42,19 @@ (testing "Ensure enrichment pattern works against arbitrary hop" (letfn [(gen-hop [] (hop.data/generate-hop))] (is (spoon.spec/test-valid? ::hop.format/hop - (hop.enrich/enrich-display-amount (gen-hop))) + (hop.enrich/enrich-display-amount (gen-hop))) "enrich-display-amount is a function to and from common-beer-format.hopspec/hop") (is (spoon.spec/test-valid? ::hop.format/hop - (hop.enrich/enrich-display-time (gen-hop))) + (hop.enrich/enrich-display-time (gen-hop))) "enrich-display-time is a function to and from common-beer-format.hopspec/hop"))) (testing "Ensure enrichment pattern works against arbitrary hop wrappers" (is (spoon.spec/test-valid? ::hop.format/hop-wrapper - (hop.enrich/enrich-hop-wrapper (hop.data/generate-hop-wrapper))) + (hop.enrich/enrich-hop-wrapper (hop.data/generate-hop-wrapper))) "enrich-hop-wrapper is a function to and from common-beer-format.hopspec/hop-wrapper") (is (spoon.spec/test-valid? ::hop.format/hops - (hop.enrich/enrich-hops (hop.data/generate-hops))) + (hop.enrich/enrich-hops (hop.data/generate-hops))) "enrich-hops is a function to and from common-beer-format.hopspec/hops") (is (spoon.spec/test-valid? ::hop.format/hops-wrapper - (hop.enrich/enrich-hops-wrapper (hop.data/generate-hops-wrapper))) + (hop.enrich/enrich-hops-wrapper (hop.data/generate-hops-wrapper))) "enrich-hops-wrapper is a function to and from common-beer-format.hopspec/hops-wrapper"))) diff --git a/test/brewtility/enrich/mash_test.cljc b/test/brewtility/enrich/mash_test.cljc index a54670c..bc307df 100644 --- a/test/brewtility/enrich/mash_test.cljc +++ b/test/brewtility/enrich/mash_test.cljc @@ -10,44 +10,44 @@ (deftest static-enrichment-tests (testing "Ensure enrichment pattern works against the static test mash steps" (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-display-step-temperature mash.data/sample-mash-step)) + (mash.enrich/enrich-display-step-temperature mash.data/sample-mash-step)) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-display-infuse-amount mash.data/sample-mash-step)) + (mash.enrich/enrich-display-infuse-amount mash.data/sample-mash-step)) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-mash-step mash.data/sample-mash-step)) + (mash.enrich/enrich-mash-step mash.data/sample-mash-step)) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against static test mash step wrappers" (is (spoon.spec/test-valid? ::mash.format/mash-step-wrapper - (mash.enrich/enrich-mash-step-wrapper mash.data/sample-mash-step-wrapper)) + (mash.enrich/enrich-mash-step-wrapper mash.data/sample-mash-step-wrapper)) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against static test mash steps" (is (spoon.spec/test-valid? ::mash.format/mash-steps - (mash.enrich/enrich-mash-steps mash.data/sample-mash-steps)) + (mash.enrich/enrich-mash-steps mash.data/sample-mash-steps)) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against static test mash steps wrapper" (is (spoon.spec/test-valid? ::mash.format/mash-steps - (:mash-steps (mash.enrich/enrich-mash-steps-wrapper mash.data/sample-mash-steps-wrapper))) + (:mash-steps (mash.enrich/enrich-mash-steps-wrapper mash.data/sample-mash-steps-wrapper))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against static test mash" (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-grain-temperature mash.data/sample-mash)) + (mash.enrich/enrich-display-grain-temperature mash.data/sample-mash)) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-tun-temperature mash.data/sample-mash)) + (mash.enrich/enrich-display-tun-temperature mash.data/sample-mash)) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-sparge-temperature mash.data/sample-mash)) + (mash.enrich/enrich-display-sparge-temperature mash.data/sample-mash)) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-tun-weight mash.data/sample-mash)) + (mash.enrich/enrich-display-tun-weight mash.data/sample-mash)) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-mash mash.data/sample-mash)) + (mash.enrich/enrich-mash mash.data/sample-mash)) "enrich-mash is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-wrapper - (mash.enrich/enrich-mash-wrapper mash.data/sample-mash-wrapper)) + (mash.enrich/enrich-mash-wrapper mash.data/sample-mash-wrapper)) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper")) (testing "Static data comparison for enrichment pattern functions" (is (= {:name "Single Step Infusion, 68 C" @@ -68,42 +68,42 @@ (deftest generative-enrichment-tests (testing "Ensure enrichment pattern works against arbitrary mash steps" (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-display-step-temperature (mash.data/generate-mash-step))) + (mash.enrich/enrich-display-step-temperature (mash.data/generate-mash-step))) "enrich-display-step-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-display-infuse-amount (mash.data/generate-mash-step))) + (mash.enrich/enrich-display-infuse-amount (mash.data/generate-mash-step))) "enrich-display-infuse-amount is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-step - (mash.enrich/enrich-mash-step (mash.data/generate-mash-step))) + (mash.enrich/enrich-mash-step (mash.data/generate-mash-step))) "enrich-mash-step is a function to and from common-beer-format.mash/mash")) (testing "Ensure enrichment pattern works against arbitrary mash step wrappers" (is (spoon.spec/test-valid? ::mash.format/mash-step-wrapper - (mash.enrich/enrich-mash-step-wrapper (mash.data/generate-mash-step-wrapper))) + (mash.enrich/enrich-mash-step-wrapper (mash.data/generate-mash-step-wrapper))) "enrich-mash-step-wrapper is a function to and from common-beer-format.mash/mash-step-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash steps" (is (spoon.spec/test-valid? ::mash.format/mash-steps - (mash.enrich/enrich-mash-steps (mash.data/generate-mash-steps))) + (mash.enrich/enrich-mash-steps (mash.data/generate-mash-steps))) "enrich-mash-steps is a function to and from common-beer-format.mash/mash-steps")) (testing "Ensure enrichment pattern works against arbitrary mash steps wrapper" (is (spoon.spec/test-valid? ::mash.format/mash-steps - (:mash-steps (mash.enrich/enrich-mash-steps-wrapper (mash.data/generate-mash-steps-wrapper)))) + (:mash-steps (mash.enrich/enrich-mash-steps-wrapper (mash.data/generate-mash-steps-wrapper)))) "enrich-mash-steps-wrapper is a function to and from common-beer-format.mash/mash-steps-wrapper")) (testing "Ensure enrichment pattern works against arbitrary mash" (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-grain-temperature (mash.data/generate-mash))) + (mash.enrich/enrich-display-grain-temperature (mash.data/generate-mash))) "enrich-display-grain-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-tun-temperature (mash.data/generate-mash))) + (mash.enrich/enrich-display-tun-temperature (mash.data/generate-mash))) "enrich-display-tun-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-sparge-temperature (mash.data/generate-mash))) + (mash.enrich/enrich-display-sparge-temperature (mash.data/generate-mash))) "enrich-display-sparge-temperature is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-display-tun-weight (mash.data/generate-mash))) + (mash.enrich/enrich-display-tun-weight (mash.data/generate-mash))) "enrich-display-tun-weight is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash - (mash.enrich/enrich-mash (mash.data/generate-mash))) + (mash.enrich/enrich-mash (mash.data/generate-mash))) "enrich-mash is a function to and from common-beer-format.mash/mash") (is (spoon.spec/test-valid? ::mash.format/mash-wrapper - (mash.enrich/enrich-mash-wrapper (mash.data/generate-mash-wrapper))) + (mash.enrich/enrich-mash-wrapper (mash.data/generate-mash-wrapper))) "enrich-mash-wrapper is a function to and from common-beer-format.mash/mash-wrapper"))) diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc index bc8a688..2e5cff3 100644 --- a/test/brewtility/string_test.cljc +++ b/test/brewtility/string_test.cljc @@ -4,7 +4,6 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) - (deftest prepare-for-compare-test (testing "Strings are appropriately re-cased and trimmed of whitespace" (is (= "" (sut/prepare-for-compare " "))) From f9985bee87ab1fd264eb1d96f9a114d15e86e9bc Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 16 Jan 2023 21:00:07 +0000 Subject: [PATCH 17/44] Enrichers for miscs --- test/brewtility/data/miscs.cljc | 1 - test/brewtility/enrich/miscs_test.cljc | 144 +++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 test/brewtility/enrich/miscs_test.cljc diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index 2392431..b40f46f 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.miscs "Namespace for static and generative test data for `common-beer-format.miscs/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.miscs :as miscs.format] diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc new file mode 100644 index 0000000..8b5571e --- /dev/null +++ b/test/brewtility/enrich/miscs_test.cljc @@ -0,0 +1,144 @@ +(ns brewtility.enrich.miscs-test + (:require [brewtility.data.miscs :as miscs.data] + [brewtility.enrich.miscs :as miscs.enrich] + [com.wallbrew.spoon.spec :as spoon.spec] + [common-beer-format.miscs :as miscs.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + +(deftest enrich-amount-is-weight-test + (testing "Ensure enricher doesn't alter the value of existing `:amount is weight` keys" + (is (nil? (:amount-is-weight miscs.data/sample-misc)) + "miscs.data/sample-misc does not set `amount-is-weight`") + (is (false? (-> miscs.data/sample-misc + miscs.enrich/enrich-amount-is-weight + :amount-is-weight)) + "miscs.data/sample-misc does not set `amount-is-weight`, so the enricher sets the value to false") + (is (false? (-> miscs.data/sample-misc + (assoc :amount-is-weight false) + miscs.enrich/enrich-amount-is-weight + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained") + (is (true? (-> miscs.data/sample-misc + (assoc :amount-is-weight true) + miscs.enrich/enrich-amount-is-weight + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained")) + (testing "The two-arity version of `enrich-amount0is0-weight` has no behavioral differences" + (is (false? (-> miscs.data/sample-misc + (miscs.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "miscs.data/sample-misc does not set `amount-is-weight`, so the enricher sets the value to false") + (is (false? (-> miscs.data/sample-misc + (assoc :amount-is-weight false) + (miscs.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained") + (is (true? (-> miscs.data/sample-misc + (assoc :amount-is-weight true) + (miscs.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained"))) + +(deftest enrich-display-time-test + (testing "Ensure enricher correctly defaults to setting display time to minutes" + (is (= "15.0 m" (-> miscs.data/sample-misc + miscs.enrich/enrich-display-time + :display-time)) + "miscs.data/sample-misc sets the time to 15.0, which is the default unit") + (is (= "15.555 m" (-> miscs.data/sample-misc + (assoc :time 15.555) + miscs.enrich/enrich-display-time + :display-time)) + "enrich-display-time defaults precision to 3") + (is (= "15.56 m" (-> miscs.data/sample-misc + (assoc :time 15.555) + (miscs.enrich/enrich-display-time {:misc-time-precision 2}) + :display-time)) + "enrich-display-time can be configured to use a different precision") + (is (= "900.0 s" (-> miscs.data/sample-misc + (assoc :time 15.0) + (miscs.enrich/enrich-display-time {:misc-time-target-units :second}) + :display-time)) + "enrich-display-time unites can be configured to use seconds") + (is (= "15.0 minute" (-> miscs.data/sample-misc + (assoc :time 15.0) + (miscs.enrich/enrich-display-time {:misc-time-suffix :full}) + :display-time)) + "enrich-display-time can be configured to use full suffixes") + (is (= "15.56 m" (-> miscs.data/sample-misc + (assoc :time 15.555) + (miscs.enrich/enrich-display-time {:precision 2}) + :display-time)) + "enrich-display-time can be configured to use a different precision with default settings keys") + (is (= "15.0 m" (-> miscs.data/sample-misc + (assoc :time 15.0) + (miscs.enrich/enrich-display-time {:system-of-measure :metric}) + :display-time)) + "enrich-display-time unites can be configured with default settings keys") + (is (= "15.0 minute" (-> miscs.data/sample-misc + (assoc :time 15.0) + (miscs.enrich/enrich-display-time {:suffix :full}) + :display-time)) + "enrich-display-time can be configured to use full suffixes with default settings keys")) + (testing "Ensure resulting `misc` still conforms to the spec" + (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc miscs.enrich/enrich-display-time)) + "miscs.data/sample-misc conforms to the spec"))) + + +;; +;; Whole object enrichment tests +;; + +(deftest enrich-misc-tests + (testing "Ensure enrichment pattern functions generate conforming data" + (is (spoon.spec/test-valid? ::miscs.format/misc + (miscs.enrich/enrich-misc miscs.data/sample-misc)) + "Enrichment pattern should produce a valid misc object") + (is (spoon.spec/test-valid? ::miscs.format/misc-wrapper + (miscs.enrich/enrich-misc-wrapper miscs.data/sample-misc-wrapper)) + "Enrichment pattern should produce a valid misc object") + (is (spoon.spec/test-valid? ::miscs.format/miscs + (miscs.enrich/enrich-miscs miscs.data/sample-miscs)) + "Enrichment pattern should produce a valid misc object") + (is (spoon.spec/test-valid? ::miscs.format/miscs-wrapper + (miscs.enrich/enrich-miscs-wrapper miscs.data/sample-miscs-wrapper)) + "Enrichment pattern should produce a valid misc object") + (testing "Static data comparison for enrichment pattern functions" + (is (= {:amount 0.01 + :display-time "15.0 m" + :amount-is-weight false + :use "Boil" + :name "Irish Moss" + :time 15.0 + :type "Fining" + :notes "Used as a clarifying agent during the last few minutes of the boil" + :version 1} + (miscs.enrich/enrich-misc miscs.data/sample-misc)))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary misc" + (letfn [(gen-misc [] (miscs.data/generate-misc))] + (is (spoon.spec/test-valid? ::miscs.format/misc + (miscs.enrich/enrich-amount-is-weight (gen-misc))) + "enrich-amount-is-weight is a function to and from common-beer-format.misc/misc") + (is (spoon.spec/test-valid? ::miscs.format/misc + (miscs.enrich/enrich-display-time (gen-misc))) + "enrich-display-time is a function to and from common-beer-format.misc/misc") + (is (spoon.spec/test-valid? ::miscs.format/misc + (miscs.enrich/enrich-display-amount (gen-misc))) + "enrich-display-amount is a function to and from common-beer-format.misc/misc") + (is (spoon.spec/test-valid? ::miscs.format/misc + (miscs.enrich/enrich-misc (gen-misc))) + "enrich-misc is a function to and from common-beer-format.misc/misc"))) + (testing "Ensure enrichment pattern works against arbitrary misc wrappers" + (is (spoon.spec/test-valid? ::miscs.format/misc-wrapper + (miscs.enrich/enrich-misc-wrapper (miscs.data/generate-misc-wrapper))) + "enrich-misc-wrapper is a function to and from common-beer-format.misc/misc-wrapper") + (is (spoon.spec/test-valid? ::miscs.format/miscs + (miscs.enrich/enrich-miscs (miscs.data/generate-miscs))) + "enrich-miscs is a function to and from common-beer-format.misc/miscs") + (is (spoon.spec/test-valid? ::miscs.format/miscs-wrapper + (miscs.enrich/enrich-miscs-wrapper (miscs.data/generate-miscs-wrapper))) + "enrich-miscs-wrapper is a function to and from common-beer-format.misc/miscs-wrapper"))) From 57fdb26fce1fc626ee14aab463117a540e3c70e9 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 16 Jan 2023 22:46:56 +0000 Subject: [PATCH 18/44] Add water enrichers --- src/brewtility/enrich/miscs.cljc | 30 ++--- src/brewtility/enrich/waters.cljc | 171 ++++++++++++++++++++++++ test/brewtility/enrich/miscs_test.cljc | 103 +++++++++++++- test/brewtility/enrich/waters_test.cljc | 103 ++++++++++++++ 4 files changed, 391 insertions(+), 16 deletions(-) create mode 100644 src/brewtility/enrich/waters.cljc create mode 100644 test/brewtility/enrich/waters_test.cljc diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index eeca5fb..e3125e1 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -1,10 +1,10 @@ (ns brewtility.enrich.miscs - "Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscss.cljc) maps" + "Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps" {:added "1.3" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" + "brewtility.enrich.hops" "brewtility.enrich.mash" - "brewtility.enrich.miscs" "brewtility.enrich.recipes" "brewtility.enrich.styles" "brewtility.enrich.waters" @@ -66,42 +66,42 @@ (defn enrich-display-amount - "An enricher pattern function to render a human-readable display time of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. + "An enricher pattern function to render a human-readable display amount of a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is in a given system. If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. Otherwise, it will be treated as a volume in liters. An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:system-of-measure`: The unit system of measure to convert the time into. Defaults to `:us`. Acceptable values are: + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the time Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the amount Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-misc` and `enrich-misc-wrapper`, this function also supports the following keys: - - `:misc-amount-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. + - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:misc-amount-suffix`: The suffix type to append to the time. Supersedes `:suffix`." + - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" "enrich-miscs-wrapper"]} ([misc] (enrich-display-amount misc {})) - ([misc {:keys [misc-time-target-units - misc-time-precision - misc-time-suffix] + ([misc {:keys [misc-amount-target-units + misc-amount-precision + misc-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :time - :display-key :display-time - :fine-grain-target-units misc-time-target-units - :fine-grain-precision misc-time-precision - :fine-grain-suffix misc-time-suffix})] + (let [options (merge opts {:value-key :amount + :display-key :display-amount + :fine-grain-target-units misc-amount-target-units + :fine-grain-precision misc-amount-precision + :fine-grain-suffix misc-amount-suffix})] (if (:amount-is-weight misc) (impl/enrich-displayable-weight misc options) (impl/enrich-displayable-volume misc options))))) diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc new file mode 100644 index 0000000..6cb1fc2 --- /dev/null +++ b/src/brewtility/enrich/waters.cljc @@ -0,0 +1,171 @@ +(ns brewtility.enrich.waters + "Enricher-pattern functions for [waters](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.fermentables" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + +(defn enrich-display-amount + "An enricher pattern function to render a human-readable display amount of a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-water` and `enrich-water-wrapper`, this function also supports the following keys: + - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-water" + "enrich-water-wrapper" + "enrich-waters" + "enrich-waters-wrapper"]} + ([water] (enrich-display-amount water {})) + ([water {:keys [water-amount-target-units + water-amount-precision + water-amount-suffix] + :as opts}] + (let [options (merge opts {:value-key :amount + :display-key :display-amount + :fine-grain-target-units water-amount-target-units + :fine-grain-precision water-amount-precision + :fine-grain-suffix water-amount-suffix})] + (impl/enrich-displayable-volume water options)))) + +(defn enrich-water + "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc). + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-water-wrapper" + "enrich-waters" + "enrich-waters-wrapper"]} + ([water] (enrich-water water {})) + ([water opts] + (-> water + (enrich-display-amount opts)))) + +(defn enrich-water-wrapper + "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-water" + "enrich-waters" + "enrich-waters-wrapper"]} + ([water] (enrich-water-wrapper water {})) + ([water opts] + (update water :water enrich-water opts))) + +(defn enrich-waters + "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-water" + "enrich-water-wrapper" + "enrich-waters-wrapper"]} + ([waters] (enrich-waters waters {})) + ([waters opts] + (map #(enrich-water % opts) waters))) + +(defn enrich-waters-wrapper + "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + - [[enrich-display-amount]] + - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-display-amount" + "enrich-water" + "enrich-water-wrapper" + "enrich-waters" + "enrich-waters-wrapper"]} + ([waters] (enrich-waters waters {})) + ([waters opts] + (update waters :waters enrich-waters opts))) diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc index 8b5571e..cd297fb 100644 --- a/test/brewtility/enrich/miscs_test.cljc +++ b/test/brewtility/enrich/miscs_test.cljc @@ -41,7 +41,7 @@ "Explicitly setting `:amount-is-weight` to false causes the value to be retained"))) (deftest enrich-display-time-test - (testing "Ensure enricher correctly defaults to setting display time to minutes" + (testing "Ensure enricher correctly defaults to setting display time" (is (= "15.0 m" (-> miscs.data/sample-misc miscs.enrich/enrich-display-time :display-time)) @@ -85,6 +85,106 @@ (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc miscs.enrich/enrich-display-time)) "miscs.data/sample-misc conforms to the spec"))) +(deftest enrich-display-amount-test + (testing "Ensure enricher correctly defaults to setting display amount as a weight" + (let [weighted-misc (assoc miscs.data/sample-misc :amount-is-weight true)] + (is (= "0.022 lb" (-> weighted-misc + miscs.enrich/enrich-display-amount + :display-amount)) + "miscs.data/sample-misc sets the amount to 15.0, which is the default unit") + (is (= "34.293 lb" (-> weighted-misc + (assoc :amount 15.555) + miscs.enrich/enrich-display-amount + :display-amount)) + "enrich-display-amount defaults precision to 3") + (is (= "34.29 lb" (-> weighted-misc + (assoc :amount 15.555) + (miscs.enrich/enrich-display-amount {:misc-amount-precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision") + (is (= "15000.0 g" (-> weighted-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:misc-amount-target-units :gram}) + :display-amount)) + "enrich-display-amount unites can be configured to use seconds") + (is (= "33.069 pound" (-> weighted-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:misc-amount-suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes") + (is (= "34.29 lb" (-> weighted-misc + (assoc :amount 15.555) + (miscs.enrich/enrich-display-amount {:precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision with default settings keys") + (is (= "15.0 kg" (-> weighted-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:system-of-measure :metric}) + :display-amount)) + "enrich-display-amount unites can be configured with default settings keys") + (is (= "33.069 pound" (-> weighted-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + (testing "Ensure enricher correctly defaults to setting display amount as a volume" + (let [volume-misc (assoc miscs.data/sample-misc :amount-is-weight false)] + (is (= "0.003 gal" (-> volume-misc + miscs.enrich/enrich-display-amount + :display-amount)) + "miscs.data/sample-misc sets the amount to 15.0, which is the default unit") + (is (= "4.109 gal" (-> volume-misc + (assoc :amount 15.555) + miscs.enrich/enrich-display-amount + :display-amount)) + "enrich-display-amount defaults precision to 3") + (is (= "4.11 gal" (-> volume-misc + (assoc :amount 15.555) + (miscs.enrich/enrich-display-amount {:misc-amount-precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision") + (is (= "3043.263 tsp" (-> volume-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:misc-amount-target-units :teaspoon}) + :display-amount)) + "enrich-display-amount unites can be configured to use seconds") + (is (= "3.963 US gallon" (-> volume-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:misc-amount-suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes") + (is (= "4.11 gal" (-> volume-misc + (assoc :amount 15.555) + (miscs.enrich/enrich-display-amount {:precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision with default settings keys") + (is (= "15.0 l" (-> volume-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:system-of-measure :metric}) + :display-amount)) + "enrich-display-amount unites can be configured with default settings keys") + (is (= "3.963 US gallon" (-> volume-misc + (assoc :amount 15.0) + (miscs.enrich/enrich-display-amount {:suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + (testing "Ensure resulting `misc` still conforms to the spec" + (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc + (assoc :amount-is-weight true) + miscs.enrich/enrich-display-amount)) + "miscs.data/sample-misc conforms to the spec if the amount is a weight") + (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc + (assoc :amount-is-weight false) + miscs.enrich/enrich-display-amount)) + "miscs.data/sample-misc conforms to the spec if the amount is a volume") + (is (spoon.spec/test-valid? ::miscs.format/misc (-> (miscs.data/generate-misc) + (assoc :amount-is-weight true) + miscs.enrich/enrich-display-amount)) + "miscs.data/sample-misc conforms to the spec if the amount is a weight") + (is (spoon.spec/test-valid? ::miscs.format/misc (-> (miscs.data/generate-misc) + (assoc :amount-is-weight false) + miscs.enrich/enrich-display-amount)) + "miscs.data/sample-misc conforms to the spec if the amount is a volume"))) ;; ;; Whole object enrichment tests @@ -113,6 +213,7 @@ :time 15.0 :type "Fining" :notes "Used as a clarifying agent during the last few minutes of the boil" + :display-amount "0.003 gal" :version 1} (miscs.enrich/enrich-misc miscs.data/sample-misc)))))) diff --git a/test/brewtility/enrich/waters_test.cljc b/test/brewtility/enrich/waters_test.cljc new file mode 100644 index 0000000..cb742c4 --- /dev/null +++ b/test/brewtility/enrich/waters_test.cljc @@ -0,0 +1,103 @@ +(ns brewtility.enrich.waters-test + (:require [brewtility.data.waters :as waters.data] + [brewtility.enrich.waters :as waters.enrich] + [com.wallbrew.spoon.spec :as spoon.spec] + [common-beer-format.waters :as waters.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + +(deftest enrich-display-amount-test + (testing "Ensure :display-amount renders correctly" + (is (= "5.283 gal" (-> waters.data/sample-water + waters.enrich/enrich-display-amount + :display-amount)) + "waters.data/sample-water sets the amount to 15.0, which is the default unit") + (is (= "4.109 gal" (-> waters.data/sample-water + (assoc :amount 15.555) + waters.enrich/enrich-display-amount + :display-amount)) + "enrich-display-amount defaults precision to 3") + (is (= "4.11 gal" (-> waters.data/sample-water + (assoc :amount 15.555) + (waters.enrich/enrich-display-amount {:water-amount-precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision") + (is (= "3043.263 tsp" (-> waters.data/sample-water + (assoc :amount 15.0) + (waters.enrich/enrich-display-amount {:water-amount-target-units :teaspoon}) + :display-amount)) + "enrich-display-amount unites can be configured to use seconds") + (is (= "3.963 US gallon" (-> waters.data/sample-water + (assoc :amount 15.0) + (waters.enrich/enrich-display-amount {:water-amount-suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes") + (is (= "4.11 gal" (-> waters.data/sample-water + (assoc :amount 15.555) + (waters.enrich/enrich-display-amount {:precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision with default settings keys") + (is (= "15.0 l" (-> waters.data/sample-water + (assoc :amount 15.0) + (waters.enrich/enrich-display-amount {:system-of-measure :metric}) + :display-amount)) + "enrich-display-amount unites can be configured with default settings keys") + (is (= "3.963 US gallon" (-> waters.data/sample-water + (assoc :amount 15.0) + (waters.enrich/enrich-display-amount {:suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + +;; +;; Whole object enrichment tests +;; + +(deftest enrich-water-tests + (testing "Ensure enrichment pattern functions generate conforming data" + (is (spoon.spec/test-valid? ::waters.format/water + (waters.enrich/enrich-water waters.data/sample-water)) + "Enrichment pattern should produce a valid water object") + (is (spoon.spec/test-valid? ::waters.format/water-wrapper + (waters.enrich/enrich-water-wrapper waters.data/sample-water-wrapper)) + "Enrichment pattern should produce a valid water object") + (is (spoon.spec/test-valid? ::waters.format/waters + (waters.enrich/enrich-waters waters.data/sample-waters)) + "Enrichment pattern should produce a valid water object") + (is (spoon.spec/test-valid? ::waters.format/waters-wrapper + (waters.enrich/enrich-waters-wrapper waters.data/sample-waters-wrapper)) + "Enrichment pattern should produce a valid water object") + (testing "Static data comparison for enrichment pattern functions" + (is (= {:amount 20.0 + :name "Chicago" + :sulfate 725.0 + :magnesium 45.0 + :calcium 295.0 + :bicarbonate 300.0 + :display-amount "5.283 gal" + :notes "The best there is" + :sodium 55.0 + :ph 8.0 + :chloride 25.0 + :version 1} + (waters.enrich/enrich-water waters.data/sample-water)))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary water" + (letfn [(gen-water [] (waters.data/generate-water))] + (is (spoon.spec/test-valid? ::waters.format/water + (waters.enrich/enrich-display-amount (gen-water))) + "enrich-display-amount is a function to and from common-beer-format.water/water") + (is (spoon.spec/test-valid? ::waters.format/water + (waters.enrich/enrich-water (gen-water))) + "enrich-water is a function to and from common-beer-format.water/water"))) + (testing "Ensure enrichment pattern works against arbitrary water wrappers" + (is (spoon.spec/test-valid? ::waters.format/water-wrapper + (waters.enrich/enrich-water-wrapper (waters.data/generate-water-wrapper))) + "enrich-water-wrapper is a function to and from common-beer-format.water/water-wrapper") + (is (spoon.spec/test-valid? ::waters.format/waters + (waters.enrich/enrich-waters (waters.data/generate-waters))) + "enrich-waters is a function to and from common-beer-format.water/waters") + (is (spoon.spec/test-valid? ::waters.format/waters-wrapper + (waters.enrich/enrich-waters-wrapper (waters.data/generate-waters-wrapper))) + "enrich-waters-wrapper is a function to and from common-beer-format.water/waters-wrapper"))) From db1fd67cbb690a8f267010af611069e2dbc0003e Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 16 Jan 2023 22:48:51 +0000 Subject: [PATCH 19/44] Fix spacing --- src/brewtility/enrich/waters.cljc | 9 +++++++-- test/brewtility/enrich/miscs_test.cljc | 6 +++++- test/brewtility/enrich/waters_test.cljc | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc index 6cb1fc2..c0b9f50 100644 --- a/src/brewtility/enrich/waters.cljc +++ b/src/brewtility/enrich/waters.cljc @@ -11,6 +11,7 @@ "brewtility.enrich.yeast"]} (:require [brewtility.enrich.impl :as impl])) + (defn enrich-display-amount "An enricher pattern function to render a human-readable display amount of a [water](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) is in a given system. @@ -46,7 +47,8 @@ :fine-grain-target-units water-amount-target-units :fine-grain-precision water-amount-precision :fine-grain-suffix water-amount-suffix})] - (impl/enrich-displayable-volume water options)))) + (impl/enrich-displayable-volume water options)))) + (defn enrich-water "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc). @@ -79,8 +81,9 @@ (-> water (enrich-display-amount opts)))) + (defn enrich-water-wrapper - "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. + "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. An option map may be passed as an optional second argument. The following keys are supported for controlling high-level behavior: @@ -109,6 +112,7 @@ ([water opts] (update water :water enrich-water opts))) + (defn enrich-waters "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. @@ -139,6 +143,7 @@ ([waters opts] (map #(enrich-water % opts) waters))) + (defn enrich-waters-wrapper "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc index cd297fb..c475685 100644 --- a/test/brewtility/enrich/miscs_test.cljc +++ b/test/brewtility/enrich/miscs_test.cljc @@ -6,6 +6,7 @@ #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + (deftest enrich-amount-is-weight-test (testing "Ensure enricher doesn't alter the value of existing `:amount is weight` keys" (is (nil? (:amount-is-weight miscs.data/sample-misc)) @@ -40,6 +41,7 @@ :amount-is-weight)) "Explicitly setting `:amount-is-weight` to false causes the value to be retained"))) + (deftest enrich-display-time-test (testing "Ensure enricher correctly defaults to setting display time" (is (= "15.0 m" (-> miscs.data/sample-misc @@ -85,6 +87,7 @@ (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc miscs.enrich/enrich-display-time)) "miscs.data/sample-misc conforms to the spec"))) + (deftest enrich-display-amount-test (testing "Ensure enricher correctly defaults to setting display amount as a weight" (let [weighted-misc (assoc miscs.data/sample-misc :amount-is-weight true)] @@ -169,7 +172,7 @@ :display-amount)) "enrich-display-amount can be configured to use full suffixes with default settings keys"))) (testing "Ensure resulting `misc` still conforms to the spec" - (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc + (is (spoon.spec/test-valid? ::miscs.format/misc (-> miscs.data/sample-misc (assoc :amount-is-weight true) miscs.enrich/enrich-display-amount)) "miscs.data/sample-misc conforms to the spec if the amount is a weight") @@ -186,6 +189,7 @@ miscs.enrich/enrich-display-amount)) "miscs.data/sample-misc conforms to the spec if the amount is a volume"))) + ;; ;; Whole object enrichment tests ;; diff --git a/test/brewtility/enrich/waters_test.cljc b/test/brewtility/enrich/waters_test.cljc index cb742c4..7eddd11 100644 --- a/test/brewtility/enrich/waters_test.cljc +++ b/test/brewtility/enrich/waters_test.cljc @@ -6,6 +6,7 @@ #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + (deftest enrich-display-amount-test (testing "Ensure :display-amount renders correctly" (is (= "5.283 gal" (-> waters.data/sample-water @@ -48,6 +49,7 @@ :display-amount)) "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + ;; ;; Whole object enrichment tests ;; From 30454bdac2bc8aec51774b5690a80e95c7b925fb Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 16 Jan 2023 23:11:14 +0000 Subject: [PATCH 20/44] Add symbolic keys pattern for enrichers --- src/brewtility/enrich/equipment.cljc | 80 ++++++++++++------------- src/brewtility/enrich/fermentables.cljc | 10 ++-- src/brewtility/enrich/hops.cljc | 20 +++---- src/brewtility/enrich/impl.cljc | 42 ++++++++++--- src/brewtility/enrich/mash.cljc | 60 +++++++++---------- src/brewtility/enrich/miscs.cljc | 20 +++---- src/brewtility/enrich/waters.cljc | 10 ++-- test/brewtility/data/equipment.cljc | 1 - test/brewtility/data/fermentables.cljc | 1 - test/brewtility/data/hops.cljc | 1 - test/brewtility/data/mash.cljc | 1 - test/brewtility/data/recipes.cljc | 1 - test/brewtility/data/styles.cljc | 1 - test/brewtility/data/waters.cljc | 1 - test/brewtility/data/yeasts.cljc | 1 - 15 files changed, 133 insertions(+), 117 deletions(-) diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc index 9775930..994383e 100644 --- a/src/brewtility/enrich/equipment.cljc +++ b/src/brewtility/enrich/equipment.cljc @@ -83,11 +83,11 @@ {:keys [boil-size-target-units boil-size-precision boil-size-suffix] :as opts}] (let [options (merge opts - {:value-key :boil-size - :display-key :display-boil-size - :fine-grain-target-units boil-size-target-units - :fine-grain-precision boil-size-precision - :fine-grain-suffix boil-size-suffix})] + {impl/value-key :boil-size + impl/display-key :display-boil-size + impl/fine-grain-target-units boil-size-target-units + impl/fine-grain-precision boil-size-precision + impl/fine-grain-suffix boil-size-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -118,11 +118,11 @@ {:keys [batch-size-target-units batch-size-precision batch-size-suffix] :as opts}] (let [options (merge opts - {:value-key :batch-size - :display-key :display-batch-size - :fine-grain-target-units batch-size-target-units - :fine-grain-precision batch-size-precision - :fine-grain-suffix batch-size-suffix})] + {impl/value-key :batch-size + impl/display-key :display-batch-size + impl/fine-grain-target-units batch-size-target-units + impl/fine-grain-precision batch-size-precision + impl/fine-grain-suffix batch-size-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -153,11 +153,11 @@ {:keys [tun-volume-target-units tun-volume-precision tun-volume-suffix] :as opts}] (let [options (merge opts - {:value-key :tun-volume - :display-key :display-tun-volume - :fine-grain-target-units tun-volume-target-units - :fine-grain-precision tun-volume-precision - :fine-grain-suffix tun-volume-suffix})] + {impl/value-key :tun-volume + impl/display-key :display-tun-volume + impl/fine-grain-target-units tun-volume-target-units + impl/fine-grain-precision tun-volume-precision + impl/fine-grain-suffix tun-volume-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -188,11 +188,11 @@ {:keys [tun-weight-target-units tun-weight-precision tun-weight-suffix] :as opts}] (let [options (merge opts - {:value-key :tun-weight - :display-key :display-tun-weight - :fine-grain-target-units tun-weight-target-units - :fine-grain-precision tun-weight-precision - :fine-grain-suffix tun-weight-suffix})] + {impl/value-key :tun-weight + impl/display-key :display-tun-weight + impl/fine-grain-target-units tun-weight-target-units + impl/fine-grain-precision tun-weight-precision + impl/fine-grain-suffix tun-weight-suffix})] (impl/enrich-displayable-weight equipment options)))) @@ -223,11 +223,11 @@ {:keys [top-up-water-target-units top-up-water-precision top-up-water-suffix] :as opts}] (let [options (merge opts - {:value-key :top-up-water - :display-key :display-top-up-water - :fine-grain-target-units top-up-water-target-units - :fine-grain-precision top-up-water-precision - :fine-grain-suffix top-up-water-suffix})] + {impl/value-key :top-up-water + impl/display-key :display-top-up-water + impl/fine-grain-target-units top-up-water-target-units + impl/fine-grain-precision top-up-water-precision + impl/fine-grain-suffix top-up-water-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -258,11 +258,11 @@ {:keys [trub-chiller-loss-target-units trub-chiller-loss-precision trub-chiller-loss-suffix] :as opts}] (let [options (merge opts - {:value-key :trub-chiller-loss - :display-key :display-trub-chiller-loss - :fine-grain-target-units trub-chiller-loss-target-units - :fine-grain-precision trub-chiller-loss-precision - :fine-grain-suffix trub-chiller-loss-suffix})] + {impl/value-key :trub-chiller-loss + impl/display-key :display-trub-chiller-loss + impl/fine-grain-target-units trub-chiller-loss-target-units + impl/fine-grain-precision trub-chiller-loss-precision + impl/fine-grain-suffix trub-chiller-loss-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -293,11 +293,11 @@ {:keys [lauter-deadspace-target-units lauter-deadspace-precision lauter-deadspace-suffix] :as opts}] (let [options (merge opts - {:value-key :lauter-deadspace - :display-key :display-lauter-deadspace - :fine-grain-target-units lauter-deadspace-target-units - :fine-grain-precision lauter-deadspace-precision - :fine-grain-suffix lauter-deadspace-suffix})] + {impl/value-key :lauter-deadspace + impl/display-key :display-lauter-deadspace + impl/fine-grain-target-units lauter-deadspace-target-units + impl/fine-grain-precision lauter-deadspace-precision + impl/fine-grain-suffix lauter-deadspace-suffix})] (impl/enrich-displayable-volume equipment options)))) @@ -328,11 +328,11 @@ {:keys [top-up-kettle-target-units top-up-kettle-precision top-up-kettle-suffix] :as opts}] (let [options (merge opts - {:value-key :top-up-kettle - :display-key :display-top-up-kettle - :fine-grain-target-units top-up-kettle-target-units - :fine-grain-precision top-up-kettle-precision - :fine-grain-suffix top-up-kettle-suffix})] + {impl/value-key :top-up-kettle + impl/display-key :display-top-up-kettle + impl/fine-grain-target-units top-up-kettle-target-units + impl/fine-grain-precision top-up-kettle-precision + impl/fine-grain-suffix top-up-kettle-suffix})] (impl/enrich-displayable-volume equipment options)))) diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index b5b6515..5815dad 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -263,11 +263,11 @@ fermentable-amount-precision fermentable-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :amount - :display-key :display-amount - :fine-grain-target-units fermentable-amount-target-units - :fine-grain-precision fermentable-amount-precision - :fine-grain-suffix fermentable-amount-suffix})] + (let [options (merge opts {impl/value-key :amount + impl/display-key :display-amount + impl/fine-grain-target-units fermentable-amount-target-units + impl/fine-grain-precision fermentable-amount-precision + impl/fine-grain-suffix fermentable-amount-suffix})] (impl/enrich-displayable-weight fermentable options)))) diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc index c48f642..e423d5c 100644 --- a/src/brewtility/enrich/hops.cljc +++ b/src/brewtility/enrich/hops.cljc @@ -43,11 +43,11 @@ hop-amount-precision hop-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :amount - :display-key :display-amount - :fine-grain-target-units hop-amount-target-units - :fine-grain-precision hop-amount-precision - :fine-grain-suffix hop-amount-suffix})] + (let [options (merge opts {impl/value-key :amount + impl/display-key :display-amount + impl/fine-grain-target-units hop-amount-target-units + impl/fine-grain-precision hop-amount-precision + impl/fine-grain-suffix hop-amount-suffix})] (impl/enrich-displayable-weight hop options)))) @@ -81,11 +81,11 @@ hop-time-precision hop-time-suffix] :as opts}] - (let [options (merge opts {:value-key :time - :display-key :display-time - :fine-grain-target-units hop-time-target-units - :fine-grain-precision hop-time-precision - :fine-grain-suffix hop-time-suffix})] + (let [options (merge opts {impl/value-key :time + impl/display-key :display-time + impl/fine-grain-target-units hop-time-target-units + impl/fine-grain-precision hop-time-precision + impl/fine-grain-suffix hop-time-suffix})] (impl/enrich-displayable-time hop options)))) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 4070da9..1db3819 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -15,6 +15,26 @@ options/suffix options/short}) +(def ^:const value-key + "The key to source data from in `->displayable` functions" + :value-key) + +(def ^:const display-key + "The key to store displayable data in in `->displayable` functions" + :display-key) + +(def ^:const fine-grain-target-units + "The target units to use for fine-grain toggling of displayable units in `->displayable` functions" + :fine-grain-target-units) + +(def ^:const fine-grain-precision + "The suffix to use for fine-grain setting of precision in `->displayable` functions" + :fine-grain-precision) + +(def ^:const fine-grain-suffix + "The suffix to use for fine-grain setting of precision in `->displayable` functions" + :fine-grain-suffix) + @@ -183,6 +203,7 @@ (throw (ex-info "Invalid displayable volume enrichment options: " errors))))) +#_{:clj-kondo/ignore [:shadowed-var]} (defn enrich-displayable-volume "A function to enrich a map with a human-readable version of a volume at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -190,7 +211,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `:fine-grain-target-units` > `system-of-measure` + `impl/fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -199,7 +220,7 @@ :no-doc true :see-also ["enrich-displayable-weight" "enrich-displayable-time"]} [source-data - {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us suffix :short precision 3}}] @@ -241,6 +262,7 @@ (throw (ex-info "Invalid displayable weight enrichment options: " errors))))) +#_{:clj-kondo/ignore [:shadowed-var]} (defn enrich-displayable-weight "A function to enrich a map with a human-readable version of a weight at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -248,7 +270,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `:fine-grain-target-units` > `system-of-measure` + `impl/fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -282,7 +304,7 @@ {:added "1.3.0" :no-doc true :see-also ["enrich-displayable-time"]} - [{:keys [target-units system-of-measure precision suffix] + [{:keys [precision suffix system-of-measure target-units] :as opts}] (let [valid-target? (contains? time/measurements target-units) valid-system? (contains? options/systems-of-measure system-of-measure) @@ -298,6 +320,7 @@ (throw (ex-info "Invalid displayable time enrichment options: " errors))))) +#_{:clj-kondo/ignore [:shadowed-var]} (defn enrich-displayable-time "A function to enrich a map with a human-readable version of a time at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -305,7 +328,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `:fine-grain-target-units` > `system-of-measure` + `impl/fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -314,7 +337,7 @@ :no-doc true :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} [source-data - {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us suffix :short precision 3}}] @@ -339,7 +362,7 @@ {:added "1.3.0" :no-doc true :see-also ["enrich-displayable-temperature"]} - [{:keys [target-units system-of-measure precision suffix] + [{:keys [precision suffix system-of-measure target-units] :as opts}] (let [valid-target? (contains? temperature/measurements target-units) valid-system? (contains? options/systems-of-measure system-of-measure) @@ -355,6 +378,7 @@ (throw (ex-info "Invalid displayable temperature enrichment options: " errors))))) +#_{:clj-kondo/ignore [:shadowed-var]} (defn enrich-displayable-temperature "A function to enrich a map with a human-readable version of a temperature at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -362,7 +386,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `:fine-grain-target-units` > `system-of-measure` + `impl/fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -371,7 +395,7 @@ :no-doc true :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} [source-data - {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us suffix :short precision 3}}] diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc index 8e651a5..1c7940c 100644 --- a/src/brewtility/enrich/mash.cljc +++ b/src/brewtility/enrich/mash.cljc @@ -45,11 +45,11 @@ display-temperature-precision display-temperature-suffix] :as opts}] - (let [options (merge opts {:value-key :step-temp - :display-key :display-step-temp - :fine-grain-target-units display-temperature-target-units - :fine-grain-precision display-temperature-precision - :fine-grain-suffix display-temperature-suffix})] + (let [options (merge opts {impl/value-key :step-temp + impl/display-key :display-step-temp + impl/fine-grain-target-units display-temperature-target-units + impl/fine-grain-precision display-temperature-precision + impl/fine-grain-suffix display-temperature-suffix})] (impl/enrich-displayable-temperature mash-step options)))) @@ -86,11 +86,11 @@ display-infuse-amount-precision display-infuse-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :infuse-amount - :display-key :display-infuse-amt - :fine-grain-target-units display-infuse-amount-target-units - :fine-grain-precision display-infuse-amount-precision - :fine-grain-suffix display-infuse-amount-suffix})] + (let [options (merge opts {impl/value-key :infuse-amount + impl/display-key :display-infuse-amt + impl/fine-grain-target-units display-infuse-amount-target-units + impl/fine-grain-precision display-infuse-amount-precision + impl/fine-grain-suffix display-infuse-amount-suffix})] (impl/enrich-displayable-volume mash-step options)))) @@ -277,11 +277,11 @@ display-grain-temperature-precision display-grain-temperature-suffix] :as opts}] - (let [options (merge opts {:value-key :grain-temp - :display-key :display-grain-temp - :fine-grain-target-units display-grain-temperature-target-units - :fine-grain-precision display-grain-temperature-precision - :fine-grain-suffix display-grain-temperature-suffix})] + (let [options (merge opts {impl/value-key :grain-temp + impl/display-key :display-grain-temp + impl/fine-grain-target-units display-grain-temperature-target-units + impl/fine-grain-precision display-grain-temperature-precision + impl/fine-grain-suffix display-grain-temperature-suffix})] (impl/enrich-displayable-temperature mash options)))) @@ -314,11 +314,11 @@ display-tun-temperature-precision display-tun-temperature-suffix] :as opts}] - (let [options (merge opts {:value-key :tun-temp - :display-key :display-tun-temp - :fine-grain-target-units display-tun-temperature-target-units - :fine-grain-precision display-tun-temperature-precision - :fine-grain-suffix display-tun-temperature-suffix})] + (let [options (merge opts {impl/value-key :tun-temp + impl/display-key :display-tun-temp + impl/fine-grain-target-units display-tun-temperature-target-units + impl/fine-grain-precision display-tun-temperature-precision + impl/fine-grain-suffix display-tun-temperature-suffix})] (impl/enrich-displayable-temperature mash options)))) @@ -351,11 +351,11 @@ display-sparge-temperature-precision display-sparge-temperature-suffix] :as opts}] - (let [options (merge opts {:value-key :sparge-temp - :display-key :display-sparge-temp - :fine-grain-target-units display-sparge-temperature-target-units - :fine-grain-precision display-sparge-temperature-precision - :fine-grain-suffix display-sparge-temperature-suffix})] + (let [options (merge opts {impl/value-key :sparge-temp + impl/display-key :display-sparge-temp + impl/fine-grain-target-units display-sparge-temperature-target-units + impl/fine-grain-precision display-sparge-temperature-precision + impl/fine-grain-suffix display-sparge-temperature-suffix})] (impl/enrich-displayable-temperature mash options)))) @@ -388,11 +388,11 @@ display-tun-weight-precision display-tun-weight-suffix] :as opts}] - (let [options (merge opts {:value-key :tun-weight - :display-key :display-tun-weight - :fine-grain-target-units display-tun-weight-target-units - :fine-grain-precision display-tun-weight-precision - :fine-grain-suffix display-tun-weight-suffix})] + (let [options (merge opts {impl/value-key :tun-weight + impl/display-key :display-tun-weight + impl/fine-grain-target-units display-tun-weight-target-units + impl/fine-grain-precision display-tun-weight-precision + impl/fine-grain-suffix display-tun-weight-suffix})] (impl/enrich-displayable-weight mash options)))) diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index e3125e1..4e7478d 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -57,11 +57,11 @@ misc-time-precision misc-time-suffix] :as opts}] - (let [options (merge opts {:value-key :time - :display-key :display-time - :fine-grain-target-units misc-time-target-units - :fine-grain-precision misc-time-precision - :fine-grain-suffix misc-time-suffix})] + (let [options (merge opts {impl/value-key :time + impl/display-key :display-time + impl/fine-grain-target-units misc-time-target-units + impl/fine-grain-precision misc-time-precision + impl/fine-grain-suffix misc-time-suffix})] (impl/enrich-displayable-time misc options)))) @@ -97,11 +97,11 @@ misc-amount-precision misc-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :amount - :display-key :display-amount - :fine-grain-target-units misc-amount-target-units - :fine-grain-precision misc-amount-precision - :fine-grain-suffix misc-amount-suffix})] + (let [options (merge opts {impl/value-key :amount + impl/display-key :display-amount + impl/fine-grain-target-units misc-amount-target-units + impl/fine-grain-precision misc-amount-precision + impl/fine-grain-suffix misc-amount-suffix})] (if (:amount-is-weight misc) (impl/enrich-displayable-weight misc options) (impl/enrich-displayable-volume misc options))))) diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc index c0b9f50..b8a4c2d 100644 --- a/src/brewtility/enrich/waters.cljc +++ b/src/brewtility/enrich/waters.cljc @@ -42,11 +42,11 @@ water-amount-precision water-amount-suffix] :as opts}] - (let [options (merge opts {:value-key :amount - :display-key :display-amount - :fine-grain-target-units water-amount-target-units - :fine-grain-precision water-amount-precision - :fine-grain-suffix water-amount-suffix})] + (let [options (merge opts {impl/value-key :amount + impl/display-key :display-amount + impl/fine-grain-target-units water-amount-target-units + impl/fine-grain-precision water-amount-precision + impl/fine-grain-suffix water-amount-suffix})] (impl/enrich-displayable-volume water options)))) diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index 1072d2a..76b7864 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.equipment "Namespace for static and generative test data for `common-beer-format.equipment/equipment` and `common-beer-format.equipment/equipment-wrapper`" (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.equipment :as equipment.format] diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index 6d06e40..544030e 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.fermentables "Namespace for static and generative test data for `common-beer-format.fermentables/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.fermentables :as fermentables.format] diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index 3d33e37..0ed0a19 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.hops "Namespace for static and generative test data for `common-beer-format.hops/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index aaf6999..cb4f108 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.mash "Namespace for static and generative test data for `common-beer-format.mash/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.mash :as mash.format] diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index 0a24b3e..4844b90 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -9,7 +9,6 @@ [brewtility.data.waters :as waters] [brewtility.data.yeasts :as yeasts] [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 348d24c..22d7747 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.styles "Namespace for static and generative test data for `common-beer-format.stylespec/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.styles :as style.format] diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 88e08fe..19b7144 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.waters "Namespace for static and generative test data for `common-beer-format.waters/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.waters :as waters.format] diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index d10259e..1095176 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -1,7 +1,6 @@ (ns brewtility.data.yeasts "Namespace for static and generative test data for `common-beer-format.yeasts/*` specs." (:require [clojure.spec.alpha :as spec] - [com.wallbrew.spoon.spec :as spoon.spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] From 82ec958850642e14c5d45b0ce278d8ad122025c7 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Tue, 17 Jan 2023 02:13:21 +0000 Subject: [PATCH 21/44] Add yeast enrichers --- src/brewtility/color.cljc | 26 +- src/brewtility/enrich/fermentables.cljc | 11 +- src/brewtility/enrich/impl.cljc | 61 +++-- src/brewtility/enrich/mash.cljc | 5 + src/brewtility/enrich/miscs.cljc | 2 +- src/brewtility/enrich/yeasts.cljc | 321 ++++++++++++++++++++++++ src/brewtility/static.cljc | 108 +++++++- src/brewtility/string.cljc | 4 +- test/brewtility/enrich/yeasts_test.cljc | 221 ++++++++++++++++ 9 files changed, 714 insertions(+), 45 deletions(-) create mode 100644 src/brewtility/enrich/yeasts.cljc create mode 100644 test/brewtility/enrich/yeasts_test.cljc diff --git a/src/brewtility/color.cljc b/src/brewtility/color.cljc index f0c04c0..26f6492 100644 --- a/src/brewtility/color.cljc +++ b/src/brewtility/color.cljc @@ -1,23 +1,27 @@ (ns brewtility.color "Namespace for calculating beer colors" - {:added "1.0"}) + {:added "1.0"} + (:require [brewtility.static :as static])) (def ^:const color-systems "The color systems available across brewtility" - #{:srm :ebc :lovibond :rgba}) + #{static/srm + static/ebc + static/lovibond + static/rgba}) (def ^:const color-system->display-name "A map from color system names to their full and short unit names" - {:srm {:full "standard reference method" - :short "srm"} - :ebc {:full "ebc" - :short "ebc"} - :lovibond {:full "degrees lovibond" - :short "°L"} - :rgba {:full "" - :short ""}}) + {static/srm {static/full "standard reference method" + static/short "srm"} + static/ebc {static/full "ebc" + static/short "ebc"} + static/lovibond {static/full "degrees lovibond" + static/short "°L"} + static/rgba {static/full "" + static/short ""}}) ;; @@ -226,7 +230,7 @@ "rgba(3,4,3,1)") -(def srm-color-map +(def ^:const srm-color-map "A map of integer values to their closest SRM value as an RGBa color code" {1 srm-1 2 srm-2 diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 5815dad..a0c4a1b 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -11,7 +11,8 @@ "brewtility.enrich.yeast"]} (:require [brewtility.color :as color] [brewtility.enrich.impl :as impl] - [brewtility.predicates.fermentables :as fermentables.predicate])) + [brewtility.predicates.fermentables :as fermentables.predicate] + [brewtility.static :as static])) (defn enrich-add-after-boil @@ -209,12 +210,12 @@ ([fermentable {:keys [color-system suffix] :as opts}] (let [source-color-system (if (fermentables.predicate/grain? fermentable opts) - :lovibond - :srm) + static/lovibond + static/srm) target-color-system (or color-system source-color-system) - suffix (or suffix :short)] + suffix (or suffix static/short)] (if (and (contains? color/color-systems target-color-system) - (contains? #{:full :short} suffix)) + (contains? #{static/full static/short} suffix)) (let [source-color (if (fermentables.predicate/grain? fermentable opts) (:color fermentable) (color/srm->lovibond (:color fermentable))) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 1db3819..656a4ac 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -15,22 +15,27 @@ options/suffix options/short}) + (def ^:const value-key "The key to source data from in `->displayable` functions" :value-key) + (def ^:const display-key "The key to store displayable data in in `->displayable` functions" :display-key) + (def ^:const fine-grain-target-units "The target units to use for fine-grain toggling of displayable units in `->displayable` functions" :fine-grain-target-units) + (def ^:const fine-grain-precision "The suffix to use for fine-grain setting of precision in `->displayable` functions" :fine-grain-precision) + (def ^:const fine-grain-suffix "The suffix to use for fine-grain setting of precision in `->displayable` functions" :fine-grain-suffix) @@ -107,17 +112,17 @@ (def ^:private ^:const default-time-by-system - {:imperial :minute - :metric :minute - :us :minute - :si :minute}) + {static/imperial :minute + static/metric :minute + static/us-customary :minute + static/international-system :minute}) (def ^:private ^:const default-temperature-by-system - {:imperial :fahrenheit - :metric :celsius - :us :fahrenheit - :si :celsius}) + {static/imperial :fahrenheit + static/metric :celsius + static/us-customary :fahrenheit + static/international-system :celsius}) (defn target-unit-error @@ -164,7 +169,7 @@ " conversion : " precision ". Must be an integer.")] - (assoc error-map :precision error-msg))) + (assoc error-map static/precision error-msg))) (defn suffix-error @@ -204,6 +209,8 @@ #_{:clj-kondo/ignore [:shadowed-var]} + + (defn enrich-displayable-volume "A function to enrich a map with a human-readable version of a volume at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -222,7 +229,7 @@ [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us - suffix :short + suffix static/short precision 3}}] (if-let [source-value (get source-data value-key)] @@ -232,9 +239,9 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-volume-opts {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + static/system-of-measure system-of-measure + static/precision precision + static/suffix suffix})] (assoc source-data display-key (->displayable-volume source-value :liter target-units opts))) source-data)) @@ -263,6 +270,8 @@ #_{:clj-kondo/ignore [:shadowed-var]} + + (defn enrich-displayable-weight "A function to enrich a map with a human-readable version of a weight at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -290,9 +299,9 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-weight-opts {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + static/system-of-measure system-of-measure + static/precision precision + static/suffix suffix})] (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) @@ -321,6 +330,8 @@ #_{:clj-kondo/ignore [:shadowed-var]} + + (defn enrich-displayable-time "A function to enrich a map with a human-readable version of a time at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -339,7 +350,7 @@ [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us - suffix :short + suffix static/short precision 3}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-time (get default-time-by-system system-of-measure) @@ -348,9 +359,9 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-time-opts {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + static/system-of-measure system-of-measure + static/precision precision + static/suffix suffix})] (assoc source-data display-key (->displayable-time source-value :minute target-units opts))) source-data)) @@ -379,6 +390,8 @@ #_{:clj-kondo/ignore [:shadowed-var]} + + (defn enrich-displayable-temperature "A function to enrich a map with a human-readable version of a temperature at `value-key`. If invalid options are passed, the function throws an Exception with information on the invalid options. @@ -397,7 +410,7 @@ [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure :us - suffix :short + suffix static/short precision 3}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) @@ -406,8 +419,8 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-temperature-opts {:target-units target-units - :system-of-measure system-of-measure - :precision precision - :suffix suffix})] + static/system-of-measure system-of-measure + static/precision precision + static/suffix suffix})] (assoc source-data display-key (->displayable-temperature source-value :celsius target-units opts))) source-data)) diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc index 1c7940c..ed8e409 100644 --- a/src/brewtility/enrich/mash.cljc +++ b/src/brewtility/enrich/mash.cljc @@ -34,6 +34,11 @@ - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." {:added "1.3" :see-also ["brewtility.enrich.impl/->displayable-temperature" + "brewtility.static/system-of-measure" + "brewtility.static/imperial" + "brewtility.static/metric" + "brewtility.static/us-customary" + "brewtility.static/international-system" "enrich-mash-step" "enrich-mash-step-wrapper" "enrich-mash-steps" diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index 4e7478d..485e390 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -108,7 +108,7 @@ (defn enrich-misc - "An enricher pattern function to derive as many values from an [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). + "An enricher pattern function to derive as many values from a [misc record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc). An option map may be passed as an optional second argument. The following keys are supported for controlling high-level behavior: diff --git a/src/brewtility/enrich/yeasts.cljc b/src/brewtility/enrich/yeasts.cljc new file mode 100644 index 0000000..7763b2b --- /dev/null +++ b/src/brewtility/enrich/yeasts.cljc @@ -0,0 +1,321 @@ +(ns brewtility.enrich.yeasts + "Enricher-pattern functions for [yeasts](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps" + {:added "1.3" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.fermentables" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.yeasts" + "brewtility.enrich.recipes" + "brewtility.enrich.styles" + "brewtility.enrich.waters"]} + (:require [brewtility.enrich.impl :as impl])) + + +(defn enrich-amount-is-weight + "An enricher pattern function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) should be measured by weight/volume. + When this feild is not present, it is assumed to be false." + {:added "1.3" + :see-also ["enrich-yeast" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast] (enrich-amount-is-weight yeast {})) + ([yeast _] ; Used to maintain signature parity with enricher pattern functions + (if (contains? yeast :amount-is-weight) + yeast + (assoc yeast :amount-is-weight false)))) + +(defn enrich-display-amount + "An enricher pattern function to render a human-readable display amount of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. + If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. + Otherwise, it will be treated as a volume in liters. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the amount Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-yeast` and `enrich-yeast-wrapper`, this function also supports the following keys: + - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `:yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-yeast" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast] (enrich-display-amount yeast {})) + ([yeast {:keys [yeast-amount-target-units + yeast-amount-precision + yeast-amount-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :amount + impl/display-key :display-amount + impl/fine-grain-target-units yeast-amount-target-units + impl/fine-grain-precision yeast-amount-precision + impl/fine-grain-suffix yeast-amount-suffix})] + (if (:amount-is-weight yeast) + (impl/enrich-displayable-weight yeast options) + (impl/enrich-displayable-volume yeast options))))) + +(defn enrich-display-min-temperature + "An enricher pattern function to render a human-readable display minimum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. + If the `min-temperature` key is not present, the map will not be changed. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-yeast` and `enrich-yeast-wrapper`, this function also supports the following keys: + - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-yeast" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast] (enrich-display-min-temperature yeast {})) + ([yeast {:keys [yeast-min-temperature-target-units + yeast-min-temperature-precision + yeast-min-temperature-suffix] + :as opts}] + (if (:min-temperature yeast) + (let [options (merge opts {impl/value-key :min-temperature + impl/display-key :disp-min-temp + impl/fine-grain-target-units yeast-min-temperature-target-units + impl/fine-grain-precision yeast-min-temperature-precision + impl/fine-grain-suffix yeast-min-temperature-suffix})] + (impl/enrich-displayable-temperature yeast options)) + yeast))) + +(defn enrich-display-max-temperature + "An enricher pattern function to render a human-readable display maximum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. + If the `max-temperature` key is not present, the map will not be changed. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the max-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the max-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-yeast` and `enrich-yeast-wrapper`, this function also supports the following keys: + - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. + - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-yeast" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast] (enrich-display-max-temperature yeast {})) + ([yeast {:keys [yeast-max-temperature-target-units + yeast-max-temperature-precision + yeast-max-temperature-suffix] + :as opts}] + (if (:max-temperature yeast) + (let [options (merge opts {impl/value-key :max-temperature + impl/display-key :disp-max-temp + impl/fine-grain-target-units yeast-max-temperature-target-units + impl/fine-grain-precision yeast-max-temperature-precision + impl/fine-grain-suffix yeast-max-temperature-suffix})] + (impl/enrich-displayable-temperature yeast options)) + yeast))) + +(defn enrich-yeast + "An enricher pattern function to derive as many values from a [yeast record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + + - [[enrich-display-amount]] + - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-min-temperature]] + - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`. + - [[enrich-display-max-temperature]] + - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. + - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-amount-is-weight" + "enrich-display-amount" + "enrich-display-min-temperature" + "enrich-display-max-temperature" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast] (enrich-yeast yeast {})) + ([yeast opts] + (-> yeast + (enrich-amount-is-weight opts) + (enrich-display-amount opts) + (enrich-display-min-temperature opts) + (enrich-display-max-temperature opts)))) + +(defn enrich-yeast-wrapper + "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + + - [[enrich-display-amount]] + - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-min-temperature]] + - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`. + - [[enrich-display-max-temperature]] + - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. + - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-amount-is-weight" + "enrich-display-amount" + "enrich-display-min-temperature" + "enrich-display-max-temperature" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeast-wrapper] (enrich-yeast-wrapper yeast-wrapper {})) + ([yeast-wrapper opts] + (update yeast-wrapper :yeast enrich-yeast opts))) + +(defn enrich-yeasts + "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + + - [[enrich-display-amount]] + - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-min-temperature]] + - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`. + - [[enrich-display-max-temperature]] + - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. + - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-amount-is-weight" + "enrich-display-amount" + "enrich-display-min-temperature" + "enrich-display-max-temperature" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeasts] (enrich-yeasts yeasts {})) + ([yeasts opts] + (map #(enrich-yeast-wrapper % opts) yeasts))) + +(defn enrich-yeasts-wrapper + "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. + + An option map may be passed as an optional second argument. + The following keys are supported for controlling high-level behavior: + + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to displayable units. Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"°L\"` for `:lovibond`. + - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. + + To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: + + - [[enrich-display-amount]] + - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. + - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`. + - [[enrich-display-min-temperature]] + - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`. + - [[enrich-display-max-temperature]] + - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. + - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." + {:added "1.3" + :see-also ["enrich-amount-is-weight" + "enrich-display-amount" + "enrich-display-min-temperature" + "enrich-display-max-temperature" + "enrich-yeast-wrapper" + "enrich-yeasts" + "enrich-yeasts-wrapper"]} + ([yeasts-wrapper] (enrich-yeasts-wrapper yeasts-wrapper {})) + ([yeasts-wrapper opts] + (update yeasts-wrapper :yeasts enrich-yeasts opts))) + \ No newline at end of file diff --git a/src/brewtility/static.cljc b/src/brewtility/static.cljc index e7c6e87..242e019 100644 --- a/src/brewtility/static.cljc +++ b/src/brewtility/static.cljc @@ -1,3 +1,107 @@ (ns brewtility.static - "A namespace of static symbolic keywords and values used in the option maps throughout brewtility." - {:added "1.3"}) + "A namespace of static symbolic keywords and values used in the option maps throughout brewtility. + + Implemented as part of the Symbolic Keyword pattern" + {:added "1.3"} + (:refer-clojure :exclude [short])) + + +(def ^:const system-of-measure + "The system of measure used in the recipe or for a given unit. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Brewility supports the following systems of measure: + - [British imperial](https://en.wikipedia.org/wiki/Imperial_units) + - [Metric system](https://en.wikipedia.org/wiki/Metric_system) + - [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) + - [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units)" + :system-of-measure) + + +(def ^:const imperial + "The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :imperial) + + +(def ^:const metric + "The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :metric) + + +(def ^:const us-customary + "The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions.." + :us) + + +(def ^:const international-system + "The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :si) + + +(def ^:const precision + "The number of decimal places to which a value is rounded. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :precision) + + +(def ^:const suffix + "The type of suffix to add on to displayed units of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Brewility supports the following suffix types: + - `:short` - A short suffix. (e.g. \"tsp\" instead of \"teaspoon\") + - `:full` - The full name as a suffix (e.g. \"teaspoon\")" + :suffix) + + +(def ^:const short + "A short suffix. + (e.g. \"tsp\" instead of \"teaspoon\") + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :short) + + +(def ^:const full + "The full name as a suffix. + (e.g. \"teaspoon\") + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :full) + + +(def ^:const srm + "The [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) color system. + + Commonly used with `brewtility.color` and in argument maps for enricher functions." + :srm) + + +(def ^:const ebc + "The [European Brewery Convention](https://en.wikipedia.org/wiki/European_Brewery_Convention) color system. + + Commonly used with `brewtility.color` and in argument maps for enricher functions." + :ebc) + + +(def ^:const lovibond + "The [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) color system. + + Commonly used with `brewtility.color` and in argument maps for enricher functions." + :lovibond) + + +(def ^:const rgba + "The [RGBA](https://en.wikipedia.org/wiki/RGBA_color_space) color system. + + Commonly used with `brewtility.color` and in argument maps for enricher functions." + :rgba) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc index 0d2b526..643d3bc 100644 --- a/src/brewtility/string.cljc +++ b/src/brewtility/string.cljc @@ -7,7 +7,7 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(def cast-to-uppercase? +(def ^:const cast-to-uppercase? "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. Commonly, this is set for the `options` argument of `same?` and `includes?`. This option will be enabled if this key's value is truthy, and is disabled by default." @@ -17,7 +17,7 @@ #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(def coerce-to-compare? +(def ^:const coerce-to-compare? "An option map key to coerce values to strings in `prepare-for-compare`. Commonly, this is set for the `options` argument of `same?` and `includes?`. This option will be enabled if this key's value is truthy, and is disabled by default." diff --git a/test/brewtility/enrich/yeasts_test.cljc b/test/brewtility/enrich/yeasts_test.cljc new file mode 100644 index 0000000..1f93d60 --- /dev/null +++ b/test/brewtility/enrich/yeasts_test.cljc @@ -0,0 +1,221 @@ +(ns brewtility.enrich.yeasts-test + (:require [brewtility.data.yeasts :as yeasts.data] + [brewtility.enrich.yeasts :as yeasts.enrich] + [com.wallbrew.spoon.spec :as spoon.spec] + [common-beer-format.yeasts :as yeasts.format] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(deftest enrich-amount-is-weight-test + (testing "Ensure enricher doesn't alter the value of existing `:amount is weight` keys" + (is (nil? (:amount-is-weight yeasts.data/sample-yeast)) + "yeasts.data/sample-yeast does not set `amount-is-weight`") + (is (false? (-> yeasts.data/sample-yeast + yeasts.enrich/enrich-amount-is-weight + :amount-is-weight)) + "yeasts.data/sample-yeast does not set `amount-is-weight`, so the enricher sets the value to false") + (is (false? (-> yeasts.data/sample-yeast + (assoc :amount-is-weight false) + yeasts.enrich/enrich-amount-is-weight + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained") + (is (true? (-> yeasts.data/sample-yeast + (assoc :amount-is-weight true) + yeasts.enrich/enrich-amount-is-weight + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained")) + (testing "The two-arity version of `enrich-amount0is0-weight` has no behavioral differences" + (is (false? (-> yeasts.data/sample-yeast + (yeasts.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "yeasts.data/sample-yeast does not set `amount-is-weight`, so the enricher sets the value to false") + (is (false? (-> yeasts.data/sample-yeast + (assoc :amount-is-weight false) + (yeasts.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained") + (is (true? (-> yeasts.data/sample-yeast + (assoc :amount-is-weight true) + (yeasts.enrich/enrich-amount-is-weight :some-value) + :amount-is-weight)) + "Explicitly setting `:amount-is-weight` to false causes the value to be retained"))) + + +(deftest enrich-display-amount-test + (testing "Ensure enricher correctly defaults to setting display amount as a weight" + (let [weighted-yeast (assoc yeasts.data/sample-yeast :amount-is-weight true)] + (is (= "0.551 lb" (-> weighted-yeast + yeasts.enrich/enrich-display-amount + :display-amount)) + "yeasts.data/sample-yeast sets the amount to 15.0, which is the default unit") + (is (= "34.293 lb" (-> weighted-yeast + (assoc :amount 15.555) + yeasts.enrich/enrich-display-amount + :display-amount)) + "enrich-display-amount defaults precision to 3") + (is (= "34.29 lb" (-> weighted-yeast + (assoc :amount 15.555) + (yeasts.enrich/enrich-display-amount {:yeast-amount-precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision") + (is (= "15000.0 g" (-> weighted-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:yeast-amount-target-units :gram}) + :display-amount)) + "enrich-display-amount unites can be configured to use seconds") + (is (= "33.069 pound" (-> weighted-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:yeast-amount-suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes") + (is (= "34.29 lb" (-> weighted-yeast + (assoc :amount 15.555) + (yeasts.enrich/enrich-display-amount {:precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision with default settings keys") + (is (= "15.0 kg" (-> weighted-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:system-of-measure :metric}) + :display-amount)) + "enrich-display-amount unites can be configured with default settings keys") + (is (= "33.069 pound" (-> weighted-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + (testing "Ensure enricher correctly defaults to setting display amount as a volume" + (let [volume-yeast (assoc yeasts.data/sample-yeast :amount-is-weight false)] + (is (= "0.066 gal" (-> volume-yeast + yeasts.enrich/enrich-display-amount + :display-amount)) + "yeasts.data/sample-yeast sets the amount to 15.0, which is the default unit") + (is (= "4.109 gal" (-> volume-yeast + (assoc :amount 15.555) + yeasts.enrich/enrich-display-amount + :display-amount)) + "enrich-display-amount defaults precision to 3") + (is (= "4.11 gal" (-> volume-yeast + (assoc :amount 15.555) + (yeasts.enrich/enrich-display-amount {:yeast-amount-precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision") + (is (= "3043.263 tsp" (-> volume-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:yeast-amount-target-units :teaspoon}) + :display-amount)) + "enrich-display-amount unites can be configured to use seconds") + (is (= "3.963 US gallon" (-> volume-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:yeast-amount-suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes") + (is (= "4.11 gal" (-> volume-yeast + (assoc :amount 15.555) + (yeasts.enrich/enrich-display-amount {:precision 2}) + :display-amount)) + "enrich-display-amount can be configured to use a different precision with default settings keys") + (is (= "15.0 l" (-> volume-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:system-of-measure :metric}) + :display-amount)) + "enrich-display-amount unites can be configured with default settings keys") + (is (= "3.963 US gallon" (-> volume-yeast + (assoc :amount 15.0) + (yeasts.enrich/enrich-display-amount {:suffix :full}) + :display-amount)) + "enrich-display-amount can be configured to use full suffixes with default settings keys"))) + (testing "Ensure resulting `yeast` still conforms to the spec" + (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> yeasts.data/sample-yeast + (assoc :amount-is-weight true) + yeasts.enrich/enrich-display-amount)) + "yeasts.data/sample-yeast conforms to the spec if the amount is a weight") + (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> yeasts.data/sample-yeast + (assoc :amount-is-weight false) + yeasts.enrich/enrich-display-amount)) + "yeasts.data/sample-yeast conforms to the spec if the amount is a volume") + (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> (yeasts.data/generate-yeast) + (assoc :amount-is-weight true) + yeasts.enrich/enrich-display-amount)) + "yeasts.data/sample-yeast conforms to the spec if the amount is a weight") + (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> (yeasts.data/generate-yeast) + (assoc :amount-is-weight false) + yeasts.enrich/enrich-display-amount)) + "yeasts.data/sample-yeast conforms to the spec if the amount is a volume"))) + + +;; +;; Whole object enrichment tests +;; + +(deftest enrich-yeast-tests + (testing "Ensure enrichment pattern functions generate conforming data" + (is (spoon.spec/test-valid? ::yeasts.format/yeast + (yeasts.enrich/enrich-yeast yeasts.data/sample-yeast)) + "Enrichment pattern should produce a valid yeast object") + (is (spoon.spec/test-valid? ::yeasts.format/yeast-wrapper + (yeasts.enrich/enrich-yeast-wrapper yeasts.data/sample-yeast-wrapper)) + "Enrichment pattern should produce a valid yeast object") + (is (spoon.spec/test-valid? ::yeasts.format/yeasts + (yeasts.enrich/enrich-yeasts yeasts.data/sample-yeasts)) + "Enrichment pattern should produce a valid yeast object") + (is (spoon.spec/test-valid? ::yeasts.format/yeasts-wrapper + (yeasts.enrich/enrich-yeasts-wrapper yeasts.data/sample-yeasts-wrapper)) + "Enrichment pattern should produce a valid yeast object") + (testing "Static data comparison for enrichment pattern functions" + (is (= {:amount 0.25 + :amount-is-weight false + :attenuation 73.0 + :best-for "Irish Dry Stouts" + :disp-max-temp "71.96 f" + :disp-min-temp "62.06 f" + :display-amount "0.066 gal" + :flocculation "Medium" + :form "Liquid" + :laboratory "Wyeast Labs" + :max-temperature 22.2 + :min-temperature 16.7 + :name "Irish Ale" + :notes "Dry, fruity flavor characteristic of stouts. Full bodied, dry, clean flavor." + :product-id "1084" + :type "Ale" + :version 1} + (yeasts.enrich/enrich-yeast yeasts.data/sample-yeast))) + (is (= {:amount 0.25 + :amount-is-weight false + :attenuation 73.0 + :best-for "Irish Dry Stouts" + :display-amount "0.066 gal" + :flocculation "Medium" + :form "Liquid" + :laboratory "Wyeast Labs" + :name "Irish Ale" + :notes "Dry, fruity flavor characteristic of stouts. Full bodied, dry, clean flavor." + :product-id "1084" + :type "Ale" + :version 1} + (yeasts.enrich/enrich-yeast (dissoc yeasts.data/sample-yeast :max-temperature :min-temperature))))))) + + +(deftest generative-enrichment-tests + (testing "Ensure enrichment pattern works against arbitrary yeast" + (letfn [(gen-yeast [] (yeasts.data/generate-yeast))] + (is (spoon.spec/test-valid? ::yeasts.format/yeast + (yeasts.enrich/enrich-amount-is-weight (gen-yeast))) + "enrich-amount-is-weight is a function to and from common-beer-format.yeast/yeast") + (is (spoon.spec/test-valid? ::yeasts.format/yeast + (yeasts.enrich/enrich-display-amount (gen-yeast))) + "enrich-display-amount is a function to and from common-beer-format.yeast/yeast") + (is (spoon.spec/test-valid? ::yeasts.format/yeast + (yeasts.enrich/enrich-yeast (gen-yeast))) + "enrich-yeast is a function to and from common-beer-format.yeast/yeast"))) + (testing "Ensure enrichment pattern works against arbitrary yeast wrappers" + (is (spoon.spec/test-valid? ::yeasts.format/yeast-wrapper + (yeasts.enrich/enrich-yeast-wrapper (yeasts.data/generate-yeast-wrapper))) + "enrich-yeast-wrapper is a function to and from common-beer-format.yeast/yeast-wrapper") + (is (spoon.spec/test-valid? ::yeasts.format/yeasts + (yeasts.enrich/enrich-yeasts (yeasts.data/generate-yeasts))) + "enrich-yeasts is a function to and from common-beer-format.yeast/yeasts") + (is (spoon.spec/test-valid? ::yeasts.format/yeasts-wrapper + (yeasts.enrich/enrich-yeasts-wrapper (yeasts.data/generate-yeasts-wrapper))) + "enrich-yeasts-wrapper is a function to and from common-beer-format.yeast/yeasts-wrapper"))) From e2bb3b454b5474d20e6d678773dea089ca3fd7df Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Wed, 18 Jan 2023 14:26:05 +0000 Subject: [PATCH 22/44] Add symbolic keys for units of measure --- src/brewtility/enrich/equipment.cljc | 5 +- src/brewtility/enrich/impl.cljc | 67 +++-- src/brewtility/enrich/yeasts.cljc | 10 +- src/brewtility/predicates/miscs.cljc | 1 - src/brewtility/predicates/styles.cljc | 1 - src/brewtility/predicates/yeasts.cljc | 13 - src/brewtility/static.cljc | 282 +++++++++++++++++++- test/brewtility/color_test.cljc | 81 ++++++ test/brewtility/data/styles.cljc | 26 -- test/brewtility/enrich/equipment_test.cljc | 2 +- test/brewtility/enrich/impl_test.cljc | 45 +++- test/brewtility/enrich/yeasts_test.cljc | 16 +- test/brewtility/predicates/miscs_test.cljc | 1 - test/brewtility/predicates/styles_test.cljc | 1 - test/brewtility/predicates/yeasts_test.cljc | 1 - test/brewtility/units_test.cljc | 3 +- 16 files changed, 459 insertions(+), 96 deletions(-) create mode 100644 test/brewtility/color_test.cljc diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc index 994383e..6736760 100644 --- a/src/brewtility/enrich/equipment.cljc +++ b/src/brewtility/enrich/equipment.cljc @@ -11,7 +11,8 @@ "brewtility.enrich.yeast"]} (:require [brewtility.calculations :as calc] [brewtility.enrich.impl :as impl] - [brewtility.precision :as precision])) + [brewtility.precision :as precision] + [brewtility.static :as static])) (defn enrich-calculated-boil-size @@ -40,7 +41,7 @@ ([{:keys [calc-boil-volume] :as equipment} {:keys [safe-calculating-boil-size precision] - :or {precision 3}}] + :or {precision static/default-precision}}] (try (if calc-boil-volume (let [derived-boil-size (precision/->precision (calc/calculate-equipment-boil-volume equipment) precision)] diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 656a4ac..694704d 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -15,7 +15,6 @@ options/suffix options/short}) - (def ^:const value-key "The key to source data from in `->displayable` functions" :value-key) @@ -41,8 +40,6 @@ :fine-grain-suffix) - - ;; TODO: Pluralize strings (defn ->displayable-volume "Convert a volume then render it to a displayable value." @@ -84,6 +81,7 @@ (time/convert source-units target-units) (time/display target-units opts)))) + ;; TODO: Pluralize strings (defn ->displayable-temperature "Convert a temperature then render it to a displayable value." @@ -97,6 +95,7 @@ (temperature/convert source-units target-units) (temperature/display target-units opts)))) + (def ^:private default-volume-by-system {options/imperial options/imperial-gallon options/metric options/litre @@ -112,17 +111,17 @@ (def ^:private ^:const default-time-by-system - {static/imperial :minute - static/metric :minute - static/us-customary :minute - static/international-system :minute}) + {options/imperial options/minute + options/metric options/minute + options/us-customary options/minute + options/international-system options/minute}) (def ^:private ^:const default-temperature-by-system - {static/imperial :fahrenheit - static/metric :celsius - static/us-customary :fahrenheit - static/international-system :celsius}) + {options/imperial options/fahrenheit + options/metric options/celsius + options/us-customary options/fahrenheit + options/international-system options/celsius}) (defn target-unit-error @@ -169,7 +168,7 @@ " conversion : " precision ". Must be an integer.")] - (assoc error-map static/precision error-msg))) + (assoc error-map options/precision error-msg))) (defn suffix-error @@ -228,9 +227,9 @@ :see-also ["enrich-displayable-weight" "enrich-displayable-time"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure :us - suffix static/short - precision 3}}] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-volume (get default-volume-by-system system-of-measure) @@ -239,9 +238,9 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-volume-opts {:target-units target-units - static/system-of-measure system-of-measure - static/precision precision - static/suffix suffix})] + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] (assoc source-data display-key (->displayable-volume source-value :liter target-units opts))) source-data)) @@ -299,9 +298,9 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-weight-opts {:target-units target-units - static/system-of-measure system-of-measure - static/precision precision - static/suffix suffix})] + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) source-data)) @@ -349,9 +348,9 @@ :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure :us - suffix static/short - precision 3}}] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-time (get default-time-by-system system-of-measure) target-units (or fine-grain-target-units system-of-measure-time) @@ -359,10 +358,10 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-time-opts {:target-units target-units - static/system-of-measure system-of-measure - static/precision precision - static/suffix suffix})] - (assoc source-data display-key (->displayable-time source-value :minute target-units opts))) + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-time source-value options/minute target-units opts))) source-data)) @@ -409,9 +408,9 @@ :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure :us - suffix static/short - precision 3}}] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] (if-let [source-value (get source-data value-key)] (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) target-units (or fine-grain-target-units system-of-measure-temperature) @@ -419,8 +418,8 @@ suffix (or fine-grain-suffix suffix) opts (verify-enrich-displayable-temperature-opts {:target-units target-units - static/system-of-measure system-of-measure - static/precision precision - static/suffix suffix})] + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] (assoc source-data display-key (->displayable-temperature source-value :celsius target-units opts))) source-data)) diff --git a/src/brewtility/enrich/yeasts.cljc b/src/brewtility/enrich/yeasts.cljc index 7763b2b..cff47a9 100644 --- a/src/brewtility/enrich/yeasts.cljc +++ b/src/brewtility/enrich/yeasts.cljc @@ -26,6 +26,7 @@ yeast (assoc yeast :amount-is-weight false)))) + (defn enrich-display-amount "An enricher pattern function to render a human-readable display amount of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. If the `amount-is-weight` key evaluates truthy, the `amount` will be treated as a weight in kilograms. @@ -67,6 +68,7 @@ (impl/enrich-displayable-weight yeast options) (impl/enrich-displayable-volume yeast options))))) + (defn enrich-display-min-temperature "An enricher pattern function to render a human-readable display minimum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. If the `min-temperature` key is not present, the map will not be changed. @@ -106,7 +108,8 @@ impl/fine-grain-suffix yeast-min-temperature-suffix})] (impl/enrich-displayable-temperature yeast options)) yeast))) - + + (defn enrich-display-max-temperature "An enricher pattern function to render a human-readable display maximum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. If the `max-temperature` key is not present, the map will not be changed. @@ -147,6 +150,7 @@ (impl/enrich-displayable-temperature yeast options)) yeast))) + (defn enrich-yeast "An enricher pattern function to derive as many values from a [yeast record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. @@ -193,6 +197,7 @@ (enrich-display-min-temperature opts) (enrich-display-max-temperature opts)))) + (defn enrich-yeast-wrapper "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. @@ -235,6 +240,7 @@ ([yeast-wrapper opts] (update yeast-wrapper :yeast enrich-yeast opts))) + (defn enrich-yeasts "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. @@ -277,6 +283,7 @@ ([yeasts opts] (map #(enrich-yeast-wrapper % opts) yeasts))) + (defn enrich-yeasts-wrapper "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. @@ -318,4 +325,3 @@ ([yeasts-wrapper] (enrich-yeasts-wrapper yeasts-wrapper {})) ([yeasts-wrapper opts] (update yeasts-wrapper :yeasts enrich-yeasts opts))) - \ No newline at end of file diff --git a/src/brewtility/predicates/miscs.cljc b/src/brewtility/predicates/miscs.cljc index 4f38ac6..4a50b0f 100644 --- a/src/brewtility/predicates/miscs.cljc +++ b/src/brewtility/predicates/miscs.cljc @@ -32,7 +32,6 @@ (spoon.string/same-text? "spice" misc-type opts)))) - (defn fining? "A predicate function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) is used to remove yeast and protein haze. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/predicates/styles.cljc b/src/brewtility/predicates/styles.cljc index a4347f1..fcb2d4d 100644 --- a/src/brewtility/predicates/styles.cljc +++ b/src/brewtility/predicates/styles.cljc @@ -32,7 +32,6 @@ (spoon.string/same-text? "lager" style-type opts)))) - (defn ale? "A predicate function to determine if a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) is for ales. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/predicates/yeasts.cljc b/src/brewtility/predicates/yeasts.cljc index 465766f..5b92adf 100644 --- a/src/brewtility/predicates/yeasts.cljc +++ b/src/brewtility/predicates/yeasts.cljc @@ -14,7 +14,6 @@ [com.wallbrew.spoon.string :as spoon.string])) - ;; ;; :type functions ;; @@ -37,7 +36,6 @@ (spoon.string/same-text? "ale" yeast-type opts)))) - (defn lager? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for lager. An option map can be passed to this function as an optional second parameter. @@ -56,7 +54,6 @@ (spoon.string/same-text? "lager" yeast-type opts)))) - (defn wheat? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is for wheat beers. An option map can be passed to this function as an optional second parameter. @@ -75,7 +72,6 @@ (spoon.string/same-text? "wheat" yeast-type opts)))) - (defn wine? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common wine strain. An option map can be passed to this function as an optional second parameter. @@ -94,7 +90,6 @@ (spoon.string/same-text? "wine" yeast-type opts)))) - (defn champagne? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a common champagne strain. An option map can be passed to this function as an optional second parameter. @@ -113,7 +108,6 @@ (spoon.string/same-text? "champagne" yeast-type opts)))) - ;; ;; :form functions ;; @@ -135,7 +129,6 @@ (spoon.string/same-text? "liquid" yeast-form opts)))) - (defn dry? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in dry form. An option map can be passed to this function as an optional second parameter. @@ -153,7 +146,6 @@ (spoon.string/same-text? "dry" yeast-form opts)))) - (defn slant? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in slant form. Typically, this is a solid growth of yeast cells in a test tube. @@ -172,7 +164,6 @@ (spoon.string/same-text? "slant" yeast-form opts)))) - (defn culture? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is a living culture. An option map can be passed to this function as an optional second parameter. @@ -190,7 +181,6 @@ (spoon.string/same-text? "culture" yeast-form opts)))) - ;; ;; :flocculation functions ;; @@ -212,7 +202,6 @@ (spoon.string/same-text? "low" yeast-flocculation opts)))) - (defn medium-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a medium amount of floc. An option map can be passed to this function as an optional second parameter. @@ -230,7 +219,6 @@ (spoon.string/same-text? "medium" yeast-flocculation opts)))) - (defn high-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a high amount of floc. An option map can be passed to this function as an optional second parameter. @@ -248,7 +236,6 @@ (spoon.string/same-text? "high" yeast-flocculation opts)))) - (defn very-high-flocculation? "A predicate function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) generates a very high amount of floc. An option map can be passed to this function as an optional second parameter. diff --git a/src/brewtility/static.cljc b/src/brewtility/static.cljc index 242e019..1d49b68 100644 --- a/src/brewtility/static.cljc +++ b/src/brewtility/static.cljc @@ -1,11 +1,20 @@ (ns brewtility.static "A namespace of static symbolic keywords and values used in the option maps throughout brewtility. - Implemented as part of the Symbolic Keyword pattern" + Implemented as part of the Symbolic Keyword pattern." {:added "1.3"} - (:refer-clojure :exclude [short])) + (:refer-clojure :exclude [short second])) +;; Defaults + +(def ^:const default-precision + "The default precision to use in `->displayable` functions" + 3) + + +;; Systems of Measure + (def ^:const system-of-measure "The system of measure used in the recipe or for a given unit. @@ -46,6 +55,9 @@ :si) +;; Enricher Setting Keys + + (def ^:const precision "The number of decimal places to which a value is rounded. @@ -79,6 +91,8 @@ :full) +;; Color Systems + (def ^:const srm "The [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) color system. @@ -105,3 +119,267 @@ Commonly used with `brewtility.color` and in argument maps for enricher functions." :rgba) + + +;; Volume Units + +(def ^:const american-fluid-ounce + "The [American fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#American_fluid_ounce) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :american-fluid-ounce) + + +(def ^:const american-gallon + "The [American gallon](https://en.wikipedia.org/wiki/Gallon#Us_liquid_gallon) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :american-gallon) + + +(def ^:const american-pint + "The [American pint](https://en.wikipedia.org/wiki/Pint#US_liquid_pint) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :american-pint) + + +(def ^:const american-quart + "The [American quart](https://en.wikipedia.org/wiki/Quart#US_liquid_quart) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :american-quart) + + +(def ^:const cup + "The [cup](https://en.wikipedia.org/wiki/Cup_(unit)) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :cup) + + +(def ^:const imperial-fluid-ounce + "The [Imperial fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#Imperial_fluid_ounce) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :imperial-fluid-ounce) + + +(def ^:const imperial-gallon + "The [Imperial gallon](https://en.wikipedia.org/wiki/Gallon#Imperial_gallon) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :imperial-gallon) + + +(def ^:const imperial-pint + "The [Imperial pint](https://en.wikipedia.org/wiki/Pint#Imperial_pint) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :imperial-pint) + + +(def ^:const imperial-quart + "The [Imperial quart](https://en.wikipedia.org/wiki/Quart#Imperial_quart) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :imperial-quart) + + +(def ^:const liter + "The [liter](https://en.wikipedia.org/wiki/Liter) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." + :liter) + + +(def ^:const litre + "The [liter](https://en.wikipedia.org/wiki/Litre) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." + :litre) + + +(def ^:const milliliter + "The [milliliter](https://en.wikipedia.org/wiki/Milliliter) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." + :milliliter) + + +(def ^:const millilitre + "The [milliliter](https://en.wikipedia.org/wiki/Millilitre) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." + :millilitre) + + +(def ^:const teaspoon + "The [teaspoon](https://en.wikipedia.org/wiki/Teaspoon) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :teaspoon) + + +(def ^:const tablespoon + "The [tablespoon](https://en.wikipedia.org/wiki/Tablespoon) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :tablespoon) + + +;; Weight/Mass Units + +(def ^:const gram + "The [gram](https://en.wikipedia.org/wiki/Gram) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :gram) + + +(def ^:const kilogram + "The [kilogram](https://en.wikipedia.org/wiki/Kilogram) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :kilogram) + + +(def ^:const milligram + "The [milligram](https://en.wikipedia.org/wiki/Milligram) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :milligram) + + +(def ^:const ounce + "The [ounce](https://en.wikipedia.org/wiki/Ounce#International_avoirdupois_ounce) unit of measure; specifically, the International avoirdupois ounce. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :ounce) + + +(def ^:const pound + "The [pound](https://en.wikipedia.org/wiki/Pound_(mass)) unit of measure + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :pound) + + +;; Temperature Units + +(def ^:const celsius + "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." + :celsius) + + +(def ^:const c + "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." + :c) + + +(def ^:const centigrade + "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." + :centigrade) + + +(def ^:const fahrenheit + "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." + :fahrenheit) + + +(def ^:const f + "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." + :f) + + +(def ^:const kelvin + "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." + :kelvin) + + +(def ^:const k + "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions. + Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." + :k) + + +;; Time Units + +(def ^:const day + "The [day](https://en.wikipedia.org/wiki/Day) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :day) + + +(def ^:const hour + "The [hour](https://en.wikipedia.org/wiki/Hour) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :hour) + + +(def ^:const microsecond + "The [microsecond](https://en.wikipedia.org/wiki/Microsecond) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :microsecond) + + +(def ^:const millisecond + "The [millisecond](https://en.wikipedia.org/wiki/Millisecond) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :millisecond) + + +(def ^:const minute + "The [minute](https://en.wikipedia.org/wiki/Minute) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :minute) + + +(def ^:const nanosecond + "The [nanosecond](https://en.wikipedia.org/wiki/Nanosecond) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :nanosecond) + + +(def ^:const second + "The [second](https://en.wikipedia.org/wiki/Second) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :second) + + +(def ^:const week + "The [week](https://en.wikipedia.org/wiki/Week) unit of measure. + + Commonly used with `brewtility.units` and in argument maps for enricher functions." + :week) diff --git a/test/brewtility/color_test.cljc b/test/brewtility/color_test.cljc new file mode 100644 index 0000000..dd34ee8 --- /dev/null +++ b/test/brewtility/color_test.cljc @@ -0,0 +1,81 @@ +(ns brewtility.color-test + (:require [brewtility.color :as sut] + [brewtility.precision :as bp] + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + + +(deftest srm->rgba-test + (testing "SRM color lookup behaves as expected" + (is (= sut/srm-1 (sut/srm->rgba 1))) + (is (= sut/srm-2 (sut/srm->rgba 2))) + (is (= sut/srm-3 (sut/srm->rgba 3))) + (is (= sut/srm-4 (sut/srm->rgba 4))) + (is (= sut/srm-5 (sut/srm->rgba 5))) + (is (= sut/srm-6 (sut/srm->rgba 6))) + (is (= sut/srm-7 (sut/srm->rgba 7))) + (is (= sut/srm-8 (sut/srm->rgba 8))) + (is (= sut/srm-9 (sut/srm->rgba 9))) + (is (= sut/srm-10 (sut/srm->rgba 10))) + (is (= sut/srm-11 (sut/srm->rgba 11))) + (is (= sut/srm-12 (sut/srm->rgba 12))) + (is (= sut/srm-13 (sut/srm->rgba 13))) + (is (= sut/srm-14 (sut/srm->rgba 14))) + (is (= sut/srm-15 (sut/srm->rgba 15))) + (is (= sut/srm-16 (sut/srm->rgba 16))) + (is (= sut/srm-17 (sut/srm->rgba 17))) + (is (= sut/srm-18 (sut/srm->rgba 18))) + (is (= sut/srm-19 (sut/srm->rgba 19))) + (is (= sut/srm-20 (sut/srm->rgba 20))) + (is (= sut/srm-21 (sut/srm->rgba 21))) + (is (= sut/srm-22 (sut/srm->rgba 22))) + (is (= sut/srm-23 (sut/srm->rgba 23))) + (is (= sut/srm-24 (sut/srm->rgba 24))) + (is (= sut/srm-25 (sut/srm->rgba 25))) + (is (= sut/srm-26 (sut/srm->rgba 26))) + (is (= sut/srm-27 (sut/srm->rgba 27))) + (is (= sut/srm-28 (sut/srm->rgba 28))) + (is (= sut/srm-29 (sut/srm->rgba 29))) + (is (= sut/srm-30 (sut/srm->rgba 30))) + (is (= sut/srm-31 (sut/srm->rgba 31))) + (is (= sut/srm-32 (sut/srm->rgba 32))) + (is (= sut/srm-33 (sut/srm->rgba 33))) + (is (= sut/srm-34 (sut/srm->rgba 34))) + (is (= sut/srm-35 (sut/srm->rgba 35))) + (is (= sut/srm-36 (sut/srm->rgba 36))) + (is (= sut/srm-37 (sut/srm->rgba 37))) + (is (= sut/srm-38 (sut/srm->rgba 38))) + (is (= sut/srm-39 (sut/srm->rgba 39))) + (is (= sut/srm-40 (sut/srm->rgba 40))) + (is (= sut/srm-1 (sut/srm->rgba 0))) + (is (= sut/srm-1 (sut/srm->rgba -1))) + (is (= sut/srm-6 (sut/srm->rgba 6.2))) + (is (= sut/srm-6 (sut/srm->rgba 6.8))) + (is (= sut/srm-40 (sut/srm->rgba 41))))) + + +(deftest lovibond->rgba-test + (testing "lovibond -> SRM -> rgba lookup behaves as expected" + (is (= sut/srm-13 (sut/lovibond->rgba 10.16))) + (is (= sut/srm-1 (sut/lovibond->rgba 0.56))) + (is (= sut/srm-1 (sut/lovibond->rgba -0.18))) + (is (= sut/srm-6 (sut/lovibond->rgba 5.14))) + (is (= sut/srm-6 (sut/lovibond->rgba 5.58))) + (is (= sut/srm-40 (sut/lovibond->rgba 30.83))))) + + +(deftest ebc->rgba-test + (testing "EBC -> SRM -> rgba lookup behaves as expected" + (is (= sut/srm-13 (sut/ebc->rgba 25.61))) + (is (= sut/srm-1 (sut/ebc->rgba 0))) + (is (= sut/srm-1 (sut/ebc->rgba -1.97))) + (is (= sut/srm-6 (sut/ebc->rgba 12.21))) + (is (= sut/srm-6 (sut/ebc->rgba 13.40))) + (is (= sut/srm-40 (sut/ebc->rgba 80.77))))) + + +(deftest conversion-test + (testing "Ensure various color unit conversions behave as expected" + (is (= 10.0 (bp/->2dp (sut/lovibond->srm 7.94)) (bp/->2dp (sut/ebc->srm 19.69)))) + (is (= 23.2 (bp/->2dp (sut/srm->lovibond 30.66)) (bp/->2dp (sut/ebc->lovibond 60.38)))) + (is (= -45.53 (bp/->2dp (sut/srm->ebc -23.11)) (bp/->2dp (sut/lovibond->ebc -16.5)))))) diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 22d7747..58613f3 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -47,16 +47,6 @@ {:styles sample-styles}) -(def sample-styles - "A hard-coded sample styles for static unit tests" - [sample-style-wrapper]) - - -(def sample-styles-wrapper - "A hard-coded sample styles-wrapper for static unit tests" - {:styles sample-styles}) - - (defn generate-style "Generate a random style object" {:added "1.4" @@ -89,22 +79,6 @@ (gen/generate (spec/gen ::style.format/styles-wrapper))) -(defn generate-styles - "Generate a random styles object" - {:added "1.3" - :no-doc true} - [] - (gen/generate (spec/gen ::style.format/styles))) - - -(defn generate-styles-wrapper - "Generate a random styles-wrapper object" - {:added "1.3" - :no-doc true} - [] - (gen/generate (spec/gen ::style.format/styles-wrapper))) - - (deftest static-test-data-check (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" (is (spoon.spec/test-valid? ::style.format/style sample-style) diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index 9c090c7..86bad64 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -481,6 +481,6 @@ (testing "Ensure enrichment pattern works against arbitrary equipment wrappers" (is (spoon.spec/test-valid? ::equipment.format/equipment-wrapper (equipment.enrich/enrich-equipment-wrapper - (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) + (assoc-in (equipment.data/generate-equipment-wrapper) [:equipment :calc-boil-volume] false))) "enrich-equipment-wrapper is a function to and from common-beer-format.equipment/equipment-wrapper"))) diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index 1ae5322..d17fd9f 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -1,5 +1,6 @@ (ns brewtility.enrich.impl-test (:require [brewtility.enrich.impl :as sut] + [brewtility.static :as static] [clojure.string :as str] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) @@ -19,7 +20,21 @@ (is (= "5.678 liter" (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 3 :suffix :full})) - "Conversion may override the default suffix"))) + "Conversion may override the default suffix")) + (testing "Ensure ->displayable-volume supports its full suite of options with static keys" + (is (= "5.678 l" + (sut/->displayable-volume 1.5 static/american-gallon static/liter) + (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision static/default-precision + static/suffix static/short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names with static keys") + (is (= "5.7 l" + (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision 1 + static/suffix static/short})) + "Conversion may override the default precision with static keys") + (is (= "5.678 liter" + (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision 3 + static/suffix static/full})) + "Conversion may override the default suffix with static keys"))) (deftest ->displayable-weight-test @@ -183,6 +198,13 @@ (testing "Ensure verify-enrich-displayable-volume-opts returns valid opts" (is (= valid-opts (sut/verify-enrich-displayable-volume-opts valid-opts)) "Valid opts are returned unchanged")) + (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units static/teaspoon + static/system-of-measure static/metric + static/precision 2 + static/suffix static/full}] + (is (= valid-opts-w-keys (sut/verify-enrich-displayable-volume-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) @@ -212,6 +234,13 @@ (testing "Ensure verify-enrich-displayable-weight-opts returns valid opts" (is (= valid-opts (sut/verify-enrich-displayable-weight-opts valid-opts)) "Valid opts are returned unchanged")) + (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units static/pound + static/system-of-measure static/metric + static/precision 2 + static/suffix static/full}] + (is (= valid-opts-w-keys (sut/verify-enrich-displayable-weight-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) @@ -241,6 +270,13 @@ (testing "Ensure verify-enrich-displayable-time-opts returns valid opts" (is (= valid-opts (sut/verify-enrich-displayable-time-opts valid-opts)) "Valid opts are returned unchanged")) + (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units static/minute + static/system-of-measure static/metric + static/precision 2 + static/suffix static/full}] + (is (= valid-opts-w-keys (sut/verify-enrich-displayable-time-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) @@ -270,6 +306,13 @@ (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts" (is (= valid-opts (sut/verify-enrich-displayable-temperature-opts valid-opts)) "Valid opts are returned unchanged")) + (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units static/c + static/system-of-measure static/metric + static/precision 2 + static/suffix static/full}] + (is (= valid-opts-w-keys (sut/verify-enrich-displayable-temperature-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) diff --git a/test/brewtility/enrich/yeasts_test.cljc b/test/brewtility/enrich/yeasts_test.cljc index 1f93d60..dbf3691 100644 --- a/test/brewtility/enrich/yeasts_test.cljc +++ b/test/brewtility/enrich/yeasts_test.cljc @@ -127,20 +127,20 @@ "enrich-display-amount can be configured to use full suffixes with default settings keys"))) (testing "Ensure resulting `yeast` still conforms to the spec" (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> yeasts.data/sample-yeast - (assoc :amount-is-weight true) - yeasts.enrich/enrich-display-amount)) + (assoc :amount-is-weight true) + yeasts.enrich/enrich-display-amount)) "yeasts.data/sample-yeast conforms to the spec if the amount is a weight") (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> yeasts.data/sample-yeast - (assoc :amount-is-weight false) - yeasts.enrich/enrich-display-amount)) + (assoc :amount-is-weight false) + yeasts.enrich/enrich-display-amount)) "yeasts.data/sample-yeast conforms to the spec if the amount is a volume") (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> (yeasts.data/generate-yeast) - (assoc :amount-is-weight true) - yeasts.enrich/enrich-display-amount)) + (assoc :amount-is-weight true) + yeasts.enrich/enrich-display-amount)) "yeasts.data/sample-yeast conforms to the spec if the amount is a weight") (is (spoon.spec/test-valid? ::yeasts.format/yeast (-> (yeasts.data/generate-yeast) - (assoc :amount-is-weight false) - yeasts.enrich/enrich-display-amount)) + (assoc :amount-is-weight false) + yeasts.enrich/enrich-display-amount)) "yeasts.data/sample-yeast conforms to the spec if the amount is a volume"))) diff --git a/test/brewtility/predicates/miscs_test.cljc b/test/brewtility/predicates/miscs_test.cljc index d9b591d..bb1bd63 100644 --- a/test/brewtility/predicates/miscs_test.cljc +++ b/test/brewtility/predicates/miscs_test.cljc @@ -6,7 +6,6 @@ [common-beer-format.miscs :as cbf-miscs])) - ;; ;; :type function tests ;; diff --git a/test/brewtility/predicates/styles_test.cljc b/test/brewtility/predicates/styles_test.cljc index 269fb70..38baf37 100644 --- a/test/brewtility/predicates/styles_test.cljc +++ b/test/brewtility/predicates/styles_test.cljc @@ -6,7 +6,6 @@ [common-beer-format.styles :as cbf-styles])) - ;; ;; :type function tests ;; diff --git a/test/brewtility/predicates/yeasts_test.cljc b/test/brewtility/predicates/yeasts_test.cljc index d0d77d3..c7b4a83 100644 --- a/test/brewtility/predicates/yeasts_test.cljc +++ b/test/brewtility/predicates/yeasts_test.cljc @@ -6,7 +6,6 @@ [common-beer-format.yeasts :as cbf-yeasts])) - ;; ;; :type function tests ;; diff --git a/test/brewtility/units_test.cljc b/test/brewtility/units_test.cljc index 991a91e..0b34d85 100644 --- a/test/brewtility/units_test.cljc +++ b/test/brewtility/units_test.cljc @@ -58,8 +58,7 @@ (precision/->2dp (sut/convert options/color 7.94 options/lovibond options/srm)) (precision/->2dp (sut/convert options/color 19.69 options/ebc options/srm)))) (is (= 10.0 - (precision/->2dp (sut/convert options/color 7.94 :lovibond :srm)) - (precision/->2dp (sut/convert options/color 19.69 :ebc :srm)))) + (precision/->2dp (sut/convert options/color 7.94 :lovibond :srm)))) (is (= 23.2 (precision/->2dp (sut/convert options/color 30.66 options/srm options/lovibond)) (precision/->2dp (sut/convert options/color 60.38 options/ebc options/lovibond)))) From 404bb77dc34b50844e7023283176333d0289d3cc Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 00:51:31 +0000 Subject: [PATCH 23/44] Finish rebasing --- doc/symbolic-keywords.md | 44 +-- src/brewtility/color.cljc | 332 ------------------- src/brewtility/enrich/equipment.cljc | 28 +- src/brewtility/enrich/fermentables.cljc | 56 ++-- src/brewtility/enrich/hops.cljc | 14 +- src/brewtility/enrich/impl.cljc | 147 ++++++++- src/brewtility/enrich/mash.cljc | 31 +- src/brewtility/enrich/miscs.cljc | 16 +- src/brewtility/enrich/styles.cljc | 13 + src/brewtility/enrich/waters.cljc | 12 +- src/brewtility/enrich/yeasts.cljc | 18 +- src/brewtility/predicates/equipment.cljc | 2 +- src/brewtility/static.cljc | 385 ----------------------- src/brewtility/string.cljc | 84 ----- test/brewtility/color_test.cljc | 81 ----- test/brewtility/data/equipment.cljc | 4 +- test/brewtility/data/fermentables.cljc | 4 +- test/brewtility/data/hops.cljc | 4 +- test/brewtility/data/mash.cljc | 6 +- test/brewtility/data/miscs.cljc | 6 +- test/brewtility/data/recipes.cljc | 6 +- test/brewtility/data/styles.cljc | 4 +- test/brewtility/data/waters.cljc | 14 +- test/brewtility/data/yeasts.cljc | 14 +- test/brewtility/enrich/impl_test.cljc | 52 +-- test/brewtility/enrich/miscs_test.cljc | 36 +-- test/brewtility/enrich/waters_test.cljc | 4 +- test/brewtility/enrich/yeasts_test.cljc | 12 +- test/brewtility/runner.cljs | 14 + test/brewtility/string_test.cljc | 51 --- 30 files changed, 354 insertions(+), 1140 deletions(-) delete mode 100644 src/brewtility/color.cljc create mode 100644 src/brewtility/enrich/styles.cljc delete mode 100644 src/brewtility/static.cljc delete mode 100644 src/brewtility/string.cljc delete mode 100644 test/brewtility/color_test.cljc delete mode 100644 test/brewtility/string_test.cljc diff --git a/doc/symbolic-keywords.md b/doc/symbolic-keywords.md index 67bc5cd..cdda860 100644 --- a/doc/symbolic-keywords.md +++ b/doc/symbolic-keywords.md @@ -1,51 +1,51 @@ -# Symbolic Keyword Pattern +# Symbolic Keywords In many clojure libraries, the behavior of complex functions may be controlled by a map. For example: ```clojure -(:require [brewtility.string :as b-str]) - -(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" -(sut/prepare-for-compare " 100 lines of CODE" {:uppercase? true}) ;; => "100 LINES OF CODE" +(:require [brewtility.units :as units]) +(units/display :volume 1.5 :liter) ;; => "1.5 l" +(units/display :volume 1.5 :liter {:suffix :full}) ;; => "1.5 liter" ``` -This allows us to easily extend the definition of a single function to fulfil multiple complex needs; however, option maps come with considerable drawbacks. +This allows us to easily extend the definition of a single function to fulfill multiple complex needs; however, option maps come with considerable drawbacks. When a map is keyed with keywords, it is easy to introduce subtle, hard-to-detect errors. -Since most of these functions select default values for keys not present, typos can lead to large differences in behavior. +Since most of these functions select default values for keys not present, typos can lead to meaningful differences in behavior. For example: ```clojure -(:require [brewtility.string :as b-str]) +(:require [brewtility.units :as units]) +(units/display :volume 1.5 :liter) ;; => "1.5 l" -(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" -(sut/prepare-for-compare " 100 lines of CODE" {:uppercased? true}) ;; => "100 lines of code" +;; Not the missing "f" in the key :sufix +(units/display :volume 1.5 :liter {:sufix :full}) ;; => "1.5 l" ``` Because keywords aren't picked up by the auto-complete features of most editors, they're vulnerable to all classes of transpositional errors. Further, the options themselves are unable to carry metadata and documentation with them, making them little more than magic values. -For this reason, it is often helpful for libraries to include symbols which point to the magic keywords used in option maps. +For this reason, it is helpful for libraries to include symbols which point to the "magic" keywords used in option maps. This has several benefits: -- Misspelled or incorrect options are compile-time errors, instead of runtime bugs +- Misspelled or incorrect option keys are compile-time errors, instead of runtime bugs - Symbols can carry metadata like documentation, deprecation notices, and point to alternative options - Context-aware editors can auto-complete options Here's can example: ```clojure -(:require [brewtility.string :as b-str]) - -(def compare-with-uppercase? - "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. - This option will be enabled if this key's value is truthy." - :uppercase?) +(:require [brewtility.units :as units] + [brewtility.units.options :as options]) -(sut/prepare-for-compare " 100 lines of CODE") ;; => "100 lines of code" -(sut/prepare-for-compare " 100 lines of CODE" {compare-with-uppercase? true}) ;; => "100 LINES OF CODE" +(units/display options/volume 1.5 options/liter) ;; => "1.5 l" +(units/display options/volume 1.5 options/liter {options/suffix options/full}) ;; => "1.5 liter" ``` Most option maps in `brewtility` support symbolic keywords. -Options relevant to only one namespace are colocated with the functionality they control. -High-level options which control behavior throughout brewtility can be found in `brewtility.static`. +These keywords are available in the namespaces ending in `.options`. +These files live as close to the code relying on them as possible; +for example, the options for all unit conversion operations (e.g. `brewtility.units`, `brewtility.units.time`, `brewtility.units.color`, etc.) are available in `brewtility.units.options`. + +Further, the option keywords are preferred for library development. +A single source of truth for the name of a common option, such as `precision`, limits the possibility of incorrectly retrieving the values used by that option. diff --git a/src/brewtility/color.cljc b/src/brewtility/color.cljc deleted file mode 100644 index 26f6492..0000000 --- a/src/brewtility/color.cljc +++ /dev/null @@ -1,332 +0,0 @@ -(ns brewtility.color - "Namespace for calculating beer colors" - {:added "1.0"} - (:require [brewtility.static :as static])) - - -(def ^:const color-systems - "The color systems available across brewtility" - #{static/srm - static/ebc - static/lovibond - static/rgba}) - - -(def ^:const color-system->display-name - "A map from color system names to their full and short unit names" - {static/srm {static/full "standard reference method" - static/short "srm"} - static/ebc {static/full "ebc" - static/short "ebc"} - static/lovibond {static/full "degrees lovibond" - static/short "°L"} - static/rgba {static/full "" - static/short ""}}) - - -;; -;; SRM Beer Colors (https://en.wikipedia.org/wiki/Standard_Reference_Method) -;; -(def ^:const srm-1 - "An SRM of 1 mapped to an RGBa color code" - - "rgba(255,230,153,1)") - - -(def ^:const srm-2 - "An SRM of 2 mapped to an RGBa color code" - - "rgba(255,216,120,1)") - - -(def ^:const srm-3 - "An SRM of 3 mapped to an RGBa color code" - - "rgba(255,202,90,1)") - - -(def ^:const srm-4 - "An SRM of 4 mapped to an RGBa color code" - "rgba(255,191,66,1)") - - -(def ^:const srm-5 - "An SRM of 5 mapped to an RGBa color code" - "rgba(251,177,35,1)") - - -(def ^:const srm-6 - "An SRM of 6 mapped to an RGBa color code" - "rgba(248,166,0,1)") - - -(def ^:const srm-7 - "An SRM of 7 mapped to an RGBa color code" - "rgba(243,156,0,1)") - - -(def ^:const srm-8 - "An SRM of 8 mapped to an RGBa color code" - "rgba(234,143,0,1)") - - -(def ^:const srm-9 - "An SRM of 9 mapped to an RGBa color code" - "rgba(229,133,0,1)") - - -(def ^:const srm-10 - "An SRM of 10 mapped to an RGBa color code" - "rgba(222,124,0,1)") - - -(def ^:const srm-11 - "An SRM of 11 mapped to an RGBa color code" - "rgba(215,114,0,1)") - - -(def ^:const srm-12 - "An SRM of 12 mapped to an RGBa color code" - "rgba(207,105,0,1)") - - -(def ^:const srm-13 - "An SRM of 13 mapped to an RGBa color code" - "rgba(203,98,0,1)") - - -(def ^:const srm-14 - "An SRM of 14 mapped to an RGBa color code" - "rgba(195,89,0,1)") - - -(def ^:const srm-15 - "An SRM of 15 mapped to an RGBa color code" - "rgba(187,81,0,1)") - - -(def ^:const srm-16 - "An SRM of 16 mapped to an RGBa color code" - "rgba(181,76,0,1)") - - -(def ^:const srm-17 - "An SRM of 17 mapped to an RGBa color code" - "rgba(176,69,0,1)") - - -(def ^:const srm-18 - "An SRM of 18 mapped to an RGBa color code" - "rgba(166,62,0,1)") - - -(def ^:const srm-19 - "An SRM of 19 mapped to an RGBa color code" - "rgba(161,55,0,1)") - - -(def ^:const srm-20 - "An SRM of 20 mapped to an RGBa color code" - "rgba(155,50,0,1)") - - -(def ^:const srm-21 - "An SRM of 21 mapped to an RGBa color code" - "rgba(149,45,0,1)") - - -(def ^:const srm-22 - "An SRM of 22 mapped to an RGBa color code" - "rgba(142,41,0,1)") - - -(def ^:const srm-23 - "An SRM of 23 mapped to an RGBa color code" - "rgba(136,35,0,1)") - - -(def ^:const srm-24 - "An SRM of 24 mapped to an RGBa color code" - "rgba(130,30,0,1)") - - -(def ^:const srm-25 - "An SRM of 25 mapped to an RGBa color code" - "rgba(123,26,0,1)") - - -(def ^:const srm-26 - "An SRM of 26 mapped to an RGBa color code" - "rgba(119,25,0,1)") - - -(def ^:const srm-27 - "An SRM of 27 mapped to an RGBa color code" - "rgba(112,20,0,1)") - - -(def ^:const srm-28 - "An SRM of 28 mapped to an RGBa color code" - "rgba(106,14,0,1)") - - -(def ^:const srm-29 - "An SRM of 29 mapped to an RGBa color code" - "rgba(102,13,0,1)") - - -(def ^:const srm-30 - "An SRM of 30 mapped to an RGBa color code" - "rgba(94,11,0,1)") - - -(def ^:const srm-31 - "An SRM of 31 mapped to an RGBa color code" - "rgba(90,10,2,1)") - - -(def ^:const srm-32 - "An SRM of 32 mapped to an RGBa color code" - "rgba(96,9,3,1)") - - -(def ^:const srm-33 - "An SRM of 33 mapped to an RGBa color code" - "rgba(82,9,7,1)") - - -(def ^:const srm-34 - "An SRM of 34 mapped to an RGBa color code" - "rgba(76,5,5,1)") - - -(def ^:const srm-35 - "An SRM of 35 mapped to an RGBa color code" - "rgba(71,6,6,1)") - - -(def ^:const srm-36 - "An SRM of 36 mapped to an RGBa color code" - "rgba(68,6,7,1)") - - -(def ^:const srm-37 - "An SRM of 37 mapped to an RGBa color code" - "rgba(63,7,8,1)") - - -(def ^:const srm-38 - "An SRM of 38 mapped to an RGBa color code" - "rgba(59,6,7,1)") - - -(def ^:const srm-39 - "An SRM of 39 mapped to an RGBa color code" - "rgba(58,7,11,1)") - - -(def ^:const srm-40 - "An SRM of 40 mapped to an RGBa color code" - "rgba(3,4,3,1)") - - -(def ^:const srm-color-map - "A map of integer values to their closest SRM value as an RGBa color code" - {1 srm-1 - 2 srm-2 - 3 srm-3 - 4 srm-4 - 5 srm-5 - 6 srm-6 - 7 srm-7 - 8 srm-8 - 9 srm-9 - 10 srm-10 - 11 srm-11 - 12 srm-12 - 13 srm-13 - 14 srm-14 - 15 srm-15 - 16 srm-16 - 17 srm-17 - 18 srm-18 - 19 srm-19 - 20 srm-20 - 21 srm-21 - 22 srm-22 - 23 srm-23 - 24 srm-24 - 25 srm-25 - 26 srm-26 - 27 srm-27 - 28 srm-28 - 29 srm-29 - 30 srm-30 - 31 srm-31 - 32 srm-32 - 33 srm-33 - 34 srm-34 - 35 srm-35 - 36 srm-36 - 37 srm-37 - 38 srm-38 - 39 srm-39 - 40 srm-40}) - - -(defn lovibond->srm - "Convert the color described in degrees `lovibond` to the equivalent SRM color" - {:added "1.0"} - [lovibond] - (- (* lovibond 1.3546) 0.76)) - - -(defn srm->ebc - "Convert the color described by the `srm` to the equivalent EBC color" - {:added "1.0"} - [srm] - (* srm 1.97)) - - -(defn ebc->srm - "Convert the color described by the `ebc` to the equivalent SRM color" - {:added "1.0"} - [ebc] - (* ebc 0.508)) - - -(defn srm->lovibond - "Convert the color described in 'srm` to the equivalent degrees Lovibond" - {:added "1.0"} - [srm] - (/ (+ srm 0.76) 1.3546)) - - -(def lovibond->ebc - "Convert the color described in degrees 'lovibond` to the equivalent EBC color" - (comp srm->ebc lovibond->srm)) - - -(def ebc->lovibond - "Convert the color described in 'ebc` to the equivalent degrees Lovibond" - (comp srm->lovibond ebc->srm)) - - -(defn srm->rgba - "Given `srm-number`, return the closest, bounded applicable RGBA color string. - OPINIONATED: The provided `srm-number` will be bound to the common range from 1 to 40 - Decimal-like values are trimmed, not rounded." - {:added "1.0"} - [srm-number] - (let [srm-color (min (max (int srm-number) 1) 40)] - (get srm-color-map srm-color))) - - -(def lovibond->rgba - "Given `lovibond-number`, return the closest, bounded applicable RGBA color string." - (comp srm->rgba lovibond->srm)) - - -(def ebc->rgba - "Given `ebc-number`, return the closest, bounded applicable RGBA color string." - (comp srm->rgba ebc->srm)) diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc index 6736760..19b0349 100644 --- a/src/brewtility/enrich/equipment.cljc +++ b/src/brewtility/enrich/equipment.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.equipment "Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.fermentables" "brewtility.enrich.hops" "brewtility.enrich.mash" @@ -12,7 +12,7 @@ (:require [brewtility.calculations :as calc] [brewtility.enrich.impl :as impl] [brewtility.precision :as precision] - [brewtility.static :as static])) + [brewtility.units.options :as options])) (defn enrich-calculated-boil-size @@ -33,7 +33,7 @@ Defaults to `false`. - `:precision` - The number of decimal places to round the calculated value to. Defaults to `3`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.calculations/calculate-equipment-boil-volume" "enrich-equipment" "enrich-equipment-wrapper"]} @@ -41,7 +41,7 @@ ([{:keys [calc-boil-volume] :as equipment} {:keys [safe-calculating-boil-size precision] - :or {precision static/default-precision}}] + :or {precision options/default-precision}}] (try (if calc-boil-volume (let [derived-boil-size (precision/->precision (calc/calculate-equipment-boil-volume equipment) precision)] @@ -77,7 +77,7 @@ - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-boil-size equipment {})) ([equipment @@ -112,7 +112,7 @@ - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-batch-size equipment {})) ([equipment @@ -147,7 +147,7 @@ - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-tun-volume equipment {})) ([equipment @@ -182,7 +182,7 @@ - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-tun-weight equipment {})) ([equipment @@ -217,7 +217,7 @@ - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-top-up-water equipment {})) ([equipment @@ -252,7 +252,7 @@ - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-trub-chiller-loss equipment {})) ([equipment @@ -287,7 +287,7 @@ - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-lauter-deadspace equipment {})) ([equipment @@ -322,7 +322,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-top-up-kettle equipment {})) ([equipment @@ -390,7 +390,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-calculated-boil-size" "enrich-calculated-boil-size" "enrich-diplay-tun-volume" @@ -469,7 +469,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-calculated-boil-size" "enrich-calculated-boil-size" "enrich-diplay-tun-volume" diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index a0c4a1b..7d0dcb5 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.fermentables "Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.hops" "brewtility.enrich.mash" @@ -9,17 +9,17 @@ "brewtility.enrich.styles" "brewtility.enrich.waters" "brewtility.enrich.yeast"]} - (:require [brewtility.color :as color] - [brewtility.enrich.impl :as impl] + (:require [brewtility.enrich.impl :as impl] [brewtility.predicates.fermentables :as fermentables.predicate] - [brewtility.static :as static])) + [brewtility.units.color :as color] + [brewtility.units.options :as options])) (defn enrich-add-after-boil "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the :add-after-boil field is not present, this function will explicitly set it to false." - {:added "1.3" + {:added "2.0" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -41,7 +41,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -66,7 +66,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -91,7 +91,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -116,7 +116,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -141,7 +141,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -166,7 +166,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.predicates.fermentables/extract?" "enrich-fermentable" "enrich-fermentable-wrapper" @@ -200,7 +200,7 @@ - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -210,25 +210,25 @@ ([fermentable {:keys [color-system suffix] :as opts}] (let [source-color-system (if (fermentables.predicate/grain? fermentable opts) - static/lovibond - static/srm) + options/lovibond + options/srm) target-color-system (or color-system source-color-system) - suffix (or suffix static/short)] - (if (and (contains? color/color-systems target-color-system) - (contains? #{static/full static/short} suffix)) + suffix (or suffix options/short)] + (if (and (contains? color/measurements target-color-system) + (contains? #{options/full options/short} suffix)) (let [source-color (if (fermentables.predicate/grain? fermentable opts) (:color fermentable) - (color/srm->lovibond (:color fermentable))) + (color/convert (:color fermentable) options/srm options/lovibond)) target-color (case target-color-system ; TODO: Add this functionality to the `units` namespace :lovibond source-color - :srm (color/lovibond->srm source-color) - :ebc (color/lovibond->ebc source-color) - :rgba (color/lovibond->rgba source-color)) - suffix-string (get-in color/color-system->display-name [target-color-system suffix]) + :srm (color/convert source-color options/lovibond options/srm) + :ebc (color/convert source-color options/lovibond options/ebc) + :rgba (color/convert source-color options/lovibond options/rgba)) + suffix-string (get-in color/measurements->display-name [target-color-system suffix]) display-value (str target-color suffix-string)] (assoc fermentable :display-color display-value)) (throw (ex-info "Invalid options for displaying fermentable color" {:color-system target-color-system - :allowed-color-systems color/color-systems + :allowed-color-systems color/measurements :suffix suffix :allowed-suffixes #{:full :short}})))))) @@ -254,7 +254,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -304,7 +304,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -363,7 +363,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -413,7 +413,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -463,7 +463,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc index e423d5c..d239d33 100644 --- a/src/brewtility/enrich/hops.cljc +++ b/src/brewtility/enrich/hops.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.hops "Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.mash" @@ -32,7 +32,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.string/same?" "enrich-hop" "enrich-hop-wrapper" @@ -71,7 +71,7 @@ - `:hop-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - `:hop-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-hop" "enrich-hop-wrapper" "enrich-hops" @@ -114,7 +114,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" @@ -152,7 +152,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop" @@ -188,7 +188,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" @@ -224,7 +224,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 694704d..53d1a05 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -2,7 +2,8 @@ {:no-doc true :added "2.1" :implementation-only true} - (:require [brewtility.units.options :as options] + (:require [brewtility.units.color :as color] + [brewtility.units.options :as options] [brewtility.units.temperature :as temperature] [brewtility.units.time :as time] [brewtility.units.volume :as volume] @@ -45,7 +46,10 @@ "Convert a volume then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-weight" "->displayable-time" "->displayable-temperature"]} + :see-also ["->displayable-weight" + "->displayable-time" + "->displayable-temperature" + "->displayable-color"]} ([source-value source-units target-units] (->displayable-volume source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -59,7 +63,10 @@ "Convert a weight then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-volume" "->displayable-time" "->displayable-temperature"]} + :see-also ["->displayable-volume" + "->displayable-time" + "->displayable-temperature" + "->displayable-color"]} ([source-value source-units target-units] (->displayable-weight source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -73,7 +80,10 @@ "Convert a time then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-volume" "->displayable-time"]} + :see-also ["->displayable-volume" + "->displayable-weight" + "->displayable-temperature" + "->displayable-color"]} ([source-value source-units target-units] (->displayable-time source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -87,7 +97,10 @@ "Convert a temperature then render it to a displayable value." {:added "1.3.0" :no-doc true - :see-also ["->displayable-volume" "->displayable-time"]} + :see-also ["->displayable-volume" + "->displayable-weight" + "->displayable-time" + "->displayable-color"]} ([source-value source-units target-units] (->displayable-temperature source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -95,6 +108,22 @@ (temperature/convert source-units target-units) (temperature/display target-units opts)))) +;; TODO: Pluralize strings +(defn ->displayable-color + "Convert a color then render it to a displayable value." + {:added "1.3.0" + :no-doc true + :see-also ["->displayable-volume" + "->displayable-weight" + "->displayable-time" + "->displayable-temperature"]} + ([source-value source-units target-units] + (->displayable-color source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] + (-> source-value + (color/convert source-units target-units) + (color/display target-units opts)))) + (def ^:private default-volume-by-system {options/imperial options/imperial-gallon @@ -131,6 +160,7 @@ :see-also ["systems-of-meaure-error" "precision-error" "suffix-error"]} [error-map conversion-type target-units] (let [allowed-values (case conversion-type + :color color/measurements :volume volume/measurements :weight weight/measurements :time time/measurements @@ -144,6 +174,33 @@ (assoc error-map :units error-msg))) +(defn source-unit-error + "A function to accumulate error messages in `error-map` if `source-units` is not a valid unit for `conversion-type`. + + Note: This is only used for color conversion at this time. + BeerXML prescribes the system of measure for all other units." + {:added "1.3.0" + :no-doc true + :see-also ["systems-of-meaure-error" + "precision-error" + "suffix-error" + "target-unit-error"]} + [error-map conversion-type source-units] + (let [allowed-values (case conversion-type + :color color/measurements + :temperature temperature/measurements + :time time/measurements + :volume volume/measurements + :weight weight/measurements) + error-msg (str "Invalid unit for " + (name conversion-type) + " conversion : `" + source-units + "`. Allowed values are: " + allowed-values)] + (assoc error-map :units error-msg))) + + (defn systems-of-meaure-error "A function to accumulate error messages in `error-map` if `system-of-measure` is not valid for `conversion-type`" {:added "1.3.0" @@ -224,7 +281,10 @@ If these options are valid, the function will convert the volume to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-weight" "enrich-displayable-time"]} + :see-also ["enrich-displayable-color" + "enrich-displayable-weight" + "enrich-displayable-temperature" + "enrich-displayable-time"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary @@ -285,7 +345,10 @@ If these options are valid, the function will convert the weight to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-volume" "enrich-displayable-time"]} + :see-also ["enrich-displayable-volume" + "enrich-displayable-color" + "enrich-displayable-temperature" + "enrich-displayable-time"]} [source-data {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] :or {system-of-measure options/us-customary @@ -345,7 +408,10 @@ If these options are valid, the function will convert the time to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} + :see-also ["enrich-displayable-volume" + "enrich-displayable-weight" + "enrich-displayable-temperature" + "enrich-displayable-color"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary @@ -405,7 +471,10 @@ If these options are valid, the function will convert the temperature to the target units and return the original value with the new value added at `display-key`" {:added "1.3.0" :no-doc true - :see-also ["enrich-displayable-volume" "enrich-displayable-weight"]} + :see-also ["enrich-displayable-volume" + "enrich-displayable-weight" + "enrich-displayable-color" + "enrich-displayable-time"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary @@ -423,3 +492,63 @@ options/suffix suffix})] (assoc source-data display-key (->displayable-temperature source-value :celsius target-units opts))) source-data)) + + +(defn verify-enrich-displayable-color-opts + "A function to verify the options map passed to `->displayable-color` + This requires the user to supply valid values for: `target-units`, `precision`, and `suffix`. + If any of these are invalid, an Exception is thrown with information on the invalid options." + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-color"]} + [{:keys [target-units source-units precision suffix] + :as opts}] + (let [valid-target? (contains? color/srm->measurement target-units) + valid-source? (contains? color/measurement->srm source-units) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :color target-units) + (not valid-source?) (source-unit-error :color source-units) + (not valid-precision?) (precision-error :color precision) + (not valid-suffix?) (suffix-error :color suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable color enrichment options: " errors))))) + + +#_{:clj-kondo/ignore [:shadowed-var]} + + +(defn enrich-displayable-color + "A function to enrich a map with a human-readable version of a color at `value-key`. + If invalid options are passed, the function throws an Exception with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the color to the target system and return the original value with the new value added at `display-key`" + {:added "1.3.0" + :no-doc true + :see-also ["enrich-displayable-volume" + "enrich-displayable-weight" + "enrich-displayable-temperature" + "enrich-displayable-time"]} + [source-data + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix value-key source-units] + :or {suffix options/short + precision options/default-precision}}] + (if-let [source-value (get source-data value-key)] + (let [target-units fine-grain-target-units + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (verify-enrich-displayable-color-opts + {:target-units target-units + :source-units source-units + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-color source-value source-units target-units opts))) + source-data)) diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc index ed8e409..4031179 100644 --- a/src/brewtility/enrich/mash.cljc +++ b/src/brewtility/enrich/mash.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.mash "Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.mash-steps" "brewtility.enrich.fermentables" @@ -32,13 +32,8 @@ - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.impl/->displayable-temperature" - "brewtility.static/system-of-measure" - "brewtility.static/imperial" - "brewtility.static/metric" - "brewtility.static/us-customary" - "brewtility.static/international-system" "enrich-mash-step" "enrich-mash-step-wrapper" "enrich-mash-steps" @@ -78,7 +73,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.string/same?" "enrich-mash-step" "enrich-mash-step-wrapper" @@ -124,7 +119,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step-wrapper" @@ -164,7 +159,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -202,7 +197,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -240,7 +235,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -273,7 +268,7 @@ - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -310,7 +305,7 @@ - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -347,7 +342,7 @@ - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -384,7 +379,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.impl/->displayable-weight" "enrich-mash" "enrich-mash-wrapper"]} @@ -442,7 +437,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-display-grain-temperature" @@ -504,7 +499,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-display-grain-temperature" diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index 485e390..d757530 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.miscs "Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -15,7 +15,7 @@ (defn enrich-amount-is-weight "An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. When this feild is not present, it is assumed to be false." - {:added "1.3" + {:added "2.0" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -47,7 +47,7 @@ - `:misc-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - `:misc-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -87,7 +87,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -132,7 +132,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -172,7 +172,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -209,7 +209,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -246,7 +246,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc new file mode 100644 index 0000000..5163ddf --- /dev/null +++ b/src/brewtility/enrich/styles.cljc @@ -0,0 +1,13 @@ +(ns brewtility.enrich.styles + "Enricher-pattern functions for [styles](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps" + {:added "2.0" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.fermentables" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.recipes" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc index b8a4c2d..4cee76f 100644 --- a/src/brewtility/enrich/waters.cljc +++ b/src/brewtility/enrich/waters.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.waters "Enricher-pattern functions for [waters](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -32,7 +32,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-water" "enrich-water-wrapper" "enrich-waters" @@ -71,7 +71,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-water-wrapper" "enrich-waters" @@ -103,7 +103,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-water" "enrich-waters" @@ -134,7 +134,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-water" "enrich-water-wrapper" @@ -165,7 +165,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-display-amount" "enrich-water" "enrich-water-wrapper" diff --git a/src/brewtility/enrich/yeasts.cljc b/src/brewtility/enrich/yeasts.cljc index cff47a9..e3b2690 100644 --- a/src/brewtility/enrich/yeasts.cljc +++ b/src/brewtility/enrich/yeasts.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.yeasts "Enricher-pattern functions for [yeasts](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps" - {:added "1.3" + {:added "2.0" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -15,7 +15,7 @@ (defn enrich-amount-is-weight "An enricher pattern function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) should be measured by weight/volume. When this feild is not present, it is assumed to be false." - {:added "1.3" + {:added "2.0" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -49,7 +49,7 @@ - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -90,7 +90,7 @@ - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -131,7 +131,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -181,7 +181,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -228,7 +228,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -271,7 +271,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -314,7 +314,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "1.3" + {:added "2.0" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" diff --git a/src/brewtility/predicates/equipment.cljc b/src/brewtility/predicates/equipment.cljc index 2e9a603..ddddea4 100644 --- a/src/brewtility/predicates/equipment.cljc +++ b/src/brewtility/predicates/equipment.cljc @@ -1,5 +1,5 @@ (ns brewtility.predicates.equipment - "Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps" + "Predicate functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps." {:added "1.5" :see-also ["brewtility.predicates.fermentables" "brewtility.predicates.hops" diff --git a/src/brewtility/static.cljc b/src/brewtility/static.cljc deleted file mode 100644 index 1d49b68..0000000 --- a/src/brewtility/static.cljc +++ /dev/null @@ -1,385 +0,0 @@ -(ns brewtility.static - "A namespace of static symbolic keywords and values used in the option maps throughout brewtility. - - Implemented as part of the Symbolic Keyword pattern." - {:added "1.3"} - (:refer-clojure :exclude [short second])) - - -;; Defaults - -(def ^:const default-precision - "The default precision to use in `->displayable` functions" - 3) - - -;; Systems of Measure - -(def ^:const system-of-measure - "The system of measure used in the recipe or for a given unit. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Brewility supports the following systems of measure: - - [British imperial](https://en.wikipedia.org/wiki/Imperial_units) - - [Metric system](https://en.wikipedia.org/wiki/Metric_system) - - [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) - - [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units)" - :system-of-measure) - - -(def ^:const imperial - "The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :imperial) - - -(def ^:const metric - "The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :metric) - - -(def ^:const us-customary - "The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions.." - :us) - - -(def ^:const international-system - "The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :si) - - -;; Enricher Setting Keys - - -(def ^:const precision - "The number of decimal places to which a value is rounded. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :precision) - - -(def ^:const suffix - "The type of suffix to add on to displayed units of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Brewility supports the following suffix types: - - `:short` - A short suffix. (e.g. \"tsp\" instead of \"teaspoon\") - - `:full` - The full name as a suffix (e.g. \"teaspoon\")" - :suffix) - - -(def ^:const short - "A short suffix. - (e.g. \"tsp\" instead of \"teaspoon\") - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :short) - - -(def ^:const full - "The full name as a suffix. - (e.g. \"teaspoon\") - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :full) - - -;; Color Systems - -(def ^:const srm - "The [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) color system. - - Commonly used with `brewtility.color` and in argument maps for enricher functions." - :srm) - - -(def ^:const ebc - "The [European Brewery Convention](https://en.wikipedia.org/wiki/European_Brewery_Convention) color system. - - Commonly used with `brewtility.color` and in argument maps for enricher functions." - :ebc) - - -(def ^:const lovibond - "The [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) color system. - - Commonly used with `brewtility.color` and in argument maps for enricher functions." - :lovibond) - - -(def ^:const rgba - "The [RGBA](https://en.wikipedia.org/wiki/RGBA_color_space) color system. - - Commonly used with `brewtility.color` and in argument maps for enricher functions." - :rgba) - - -;; Volume Units - -(def ^:const american-fluid-ounce - "The [American fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#American_fluid_ounce) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :american-fluid-ounce) - - -(def ^:const american-gallon - "The [American gallon](https://en.wikipedia.org/wiki/Gallon#Us_liquid_gallon) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :american-gallon) - - -(def ^:const american-pint - "The [American pint](https://en.wikipedia.org/wiki/Pint#US_liquid_pint) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :american-pint) - - -(def ^:const american-quart - "The [American quart](https://en.wikipedia.org/wiki/Quart#US_liquid_quart) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :american-quart) - - -(def ^:const cup - "The [cup](https://en.wikipedia.org/wiki/Cup_(unit)) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :cup) - - -(def ^:const imperial-fluid-ounce - "The [Imperial fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#Imperial_fluid_ounce) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :imperial-fluid-ounce) - - -(def ^:const imperial-gallon - "The [Imperial gallon](https://en.wikipedia.org/wiki/Gallon#Imperial_gallon) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :imperial-gallon) - - -(def ^:const imperial-pint - "The [Imperial pint](https://en.wikipedia.org/wiki/Pint#Imperial_pint) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :imperial-pint) - - -(def ^:const imperial-quart - "The [Imperial quart](https://en.wikipedia.org/wiki/Quart#Imperial_quart) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :imperial-quart) - - -(def ^:const liter - "The [liter](https://en.wikipedia.org/wiki/Liter) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." - :liter) - - -(def ^:const litre - "The [liter](https://en.wikipedia.org/wiki/Litre) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." - :litre) - - -(def ^:const milliliter - "The [milliliter](https://en.wikipedia.org/wiki/Milliliter) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." - :milliliter) - - -(def ^:const millilitre - "The [milliliter](https://en.wikipedia.org/wiki/Millilitre) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." - :millilitre) - - -(def ^:const teaspoon - "The [teaspoon](https://en.wikipedia.org/wiki/Teaspoon) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :teaspoon) - - -(def ^:const tablespoon - "The [tablespoon](https://en.wikipedia.org/wiki/Tablespoon) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :tablespoon) - - -;; Weight/Mass Units - -(def ^:const gram - "The [gram](https://en.wikipedia.org/wiki/Gram) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :gram) - - -(def ^:const kilogram - "The [kilogram](https://en.wikipedia.org/wiki/Kilogram) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :kilogram) - - -(def ^:const milligram - "The [milligram](https://en.wikipedia.org/wiki/Milligram) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :milligram) - - -(def ^:const ounce - "The [ounce](https://en.wikipedia.org/wiki/Ounce#International_avoirdupois_ounce) unit of measure; specifically, the International avoirdupois ounce. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :ounce) - - -(def ^:const pound - "The [pound](https://en.wikipedia.org/wiki/Pound_(mass)) unit of measure - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :pound) - - -;; Temperature Units - -(def ^:const celsius - "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." - :celsius) - - -(def ^:const c - "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." - :c) - - -(def ^:const centigrade - "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." - :centigrade) - - -(def ^:const fahrenheit - "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." - :fahrenheit) - - -(def ^:const f - "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." - :f) - - -(def ^:const kelvin - "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." - :kelvin) - - -(def ^:const k - "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions. - Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." - :k) - - -;; Time Units - -(def ^:const day - "The [day](https://en.wikipedia.org/wiki/Day) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :day) - - -(def ^:const hour - "The [hour](https://en.wikipedia.org/wiki/Hour) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :hour) - - -(def ^:const microsecond - "The [microsecond](https://en.wikipedia.org/wiki/Microsecond) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :microsecond) - - -(def ^:const millisecond - "The [millisecond](https://en.wikipedia.org/wiki/Millisecond) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :millisecond) - - -(def ^:const minute - "The [minute](https://en.wikipedia.org/wiki/Minute) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :minute) - - -(def ^:const nanosecond - "The [nanosecond](https://en.wikipedia.org/wiki/Nanosecond) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :nanosecond) - - -(def ^:const second - "The [second](https://en.wikipedia.org/wiki/Second) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :second) - - -(def ^:const week - "The [week](https://en.wikipedia.org/wiki/Week) unit of measure. - - Commonly used with `brewtility.units` and in argument maps for enricher functions." - :week) diff --git a/src/brewtility/string.cljc b/src/brewtility/string.cljc deleted file mode 100644 index 643d3bc..0000000 --- a/src/brewtility/string.cljc +++ /dev/null @@ -1,84 +0,0 @@ -(ns brewtility.string - "String comparison utilities" - {:added "1.3"} - (:require [clojure.string :as str])) - - -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} - - -(def ^:const cast-to-uppercase? - "An option map key to cast strings to UPPER CASE in `prepare-for-compare`. - Commonly, this is set for the `options` argument of `same?` and `includes?`. - This option will be enabled if this key's value is truthy, and is disabled by default." - :uppercase?) - - -#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} - - -(def ^:const coerce-to-compare? - "An option map key to coerce values to strings in `prepare-for-compare`. - Commonly, this is set for the `options` argument of `same?` and `includes?`. - This option will be enabled if this key's value is truthy, and is disabled by default." - :coerce?) - - -(defn prepare-for-compare - "Takes a string `s`, trims it, and coerces it to lower case. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s` will be cast to a string via `str`. Defaults to false." - {:added "1.3" - :see-also ["same?" - "includes?" - "cast-to-uppercase?" - "coerce-to-compare?"]} - ([s] (prepare-for-compare s {})) - - ([s {:keys [uppercase? coerce?]}] - (let [casing-fn (if uppercase? str/upper-case str/lower-case) - s' (if coerce? (str s) s)] - (-> s' str/trim casing-fn)))) - - -(defn same? - "Checks to see if `s1` and `s2` are equal after each string has been modified by `prepare-for-compare`. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." - {:added "1.3" - :see-also ["includes?" - "prepare-for-compare" - "cast-to-uppercase?" - "coerce-to-compare?"]} - ([s1 s2] (same? s1 s2 {})) - - ([s1 s2 opts] - (= (prepare-for-compare s1 opts) - (prepare-for-compare s2 opts)))) - - -(defn includes? - "Checks to see if `s1` includes `s2` after each string has been modified by `prepare-for-compare`. - - An option map may be passed as an optional second argument. - The following keys are supported: - - - `:uppercase?` - If true, `s1` and `s2` will be coerced to upper case. Defaults to false. - - `:coerce?` - If true, `s1` and `s2` will be cast to a string via `str`. Defaults to false." - {:added "1.3" - :see-also ["includes?" - "prepare-for-compare" - "cast-to-uppercase?" - "coerce-to-compare?"]} - ([s1 s2] (includes? s1 s2 {})) - - ([s1 s2 opts] - (str/includes? (prepare-for-compare s1 opts) (prepare-for-compare s2 opts)))) diff --git a/test/brewtility/color_test.cljc b/test/brewtility/color_test.cljc deleted file mode 100644 index dd34ee8..0000000 --- a/test/brewtility/color_test.cljc +++ /dev/null @@ -1,81 +0,0 @@ -(ns brewtility.color-test - (:require [brewtility.color :as sut] - [brewtility.precision :as bp] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) - - -(deftest srm->rgba-test - (testing "SRM color lookup behaves as expected" - (is (= sut/srm-1 (sut/srm->rgba 1))) - (is (= sut/srm-2 (sut/srm->rgba 2))) - (is (= sut/srm-3 (sut/srm->rgba 3))) - (is (= sut/srm-4 (sut/srm->rgba 4))) - (is (= sut/srm-5 (sut/srm->rgba 5))) - (is (= sut/srm-6 (sut/srm->rgba 6))) - (is (= sut/srm-7 (sut/srm->rgba 7))) - (is (= sut/srm-8 (sut/srm->rgba 8))) - (is (= sut/srm-9 (sut/srm->rgba 9))) - (is (= sut/srm-10 (sut/srm->rgba 10))) - (is (= sut/srm-11 (sut/srm->rgba 11))) - (is (= sut/srm-12 (sut/srm->rgba 12))) - (is (= sut/srm-13 (sut/srm->rgba 13))) - (is (= sut/srm-14 (sut/srm->rgba 14))) - (is (= sut/srm-15 (sut/srm->rgba 15))) - (is (= sut/srm-16 (sut/srm->rgba 16))) - (is (= sut/srm-17 (sut/srm->rgba 17))) - (is (= sut/srm-18 (sut/srm->rgba 18))) - (is (= sut/srm-19 (sut/srm->rgba 19))) - (is (= sut/srm-20 (sut/srm->rgba 20))) - (is (= sut/srm-21 (sut/srm->rgba 21))) - (is (= sut/srm-22 (sut/srm->rgba 22))) - (is (= sut/srm-23 (sut/srm->rgba 23))) - (is (= sut/srm-24 (sut/srm->rgba 24))) - (is (= sut/srm-25 (sut/srm->rgba 25))) - (is (= sut/srm-26 (sut/srm->rgba 26))) - (is (= sut/srm-27 (sut/srm->rgba 27))) - (is (= sut/srm-28 (sut/srm->rgba 28))) - (is (= sut/srm-29 (sut/srm->rgba 29))) - (is (= sut/srm-30 (sut/srm->rgba 30))) - (is (= sut/srm-31 (sut/srm->rgba 31))) - (is (= sut/srm-32 (sut/srm->rgba 32))) - (is (= sut/srm-33 (sut/srm->rgba 33))) - (is (= sut/srm-34 (sut/srm->rgba 34))) - (is (= sut/srm-35 (sut/srm->rgba 35))) - (is (= sut/srm-36 (sut/srm->rgba 36))) - (is (= sut/srm-37 (sut/srm->rgba 37))) - (is (= sut/srm-38 (sut/srm->rgba 38))) - (is (= sut/srm-39 (sut/srm->rgba 39))) - (is (= sut/srm-40 (sut/srm->rgba 40))) - (is (= sut/srm-1 (sut/srm->rgba 0))) - (is (= sut/srm-1 (sut/srm->rgba -1))) - (is (= sut/srm-6 (sut/srm->rgba 6.2))) - (is (= sut/srm-6 (sut/srm->rgba 6.8))) - (is (= sut/srm-40 (sut/srm->rgba 41))))) - - -(deftest lovibond->rgba-test - (testing "lovibond -> SRM -> rgba lookup behaves as expected" - (is (= sut/srm-13 (sut/lovibond->rgba 10.16))) - (is (= sut/srm-1 (sut/lovibond->rgba 0.56))) - (is (= sut/srm-1 (sut/lovibond->rgba -0.18))) - (is (= sut/srm-6 (sut/lovibond->rgba 5.14))) - (is (= sut/srm-6 (sut/lovibond->rgba 5.58))) - (is (= sut/srm-40 (sut/lovibond->rgba 30.83))))) - - -(deftest ebc->rgba-test - (testing "EBC -> SRM -> rgba lookup behaves as expected" - (is (= sut/srm-13 (sut/ebc->rgba 25.61))) - (is (= sut/srm-1 (sut/ebc->rgba 0))) - (is (= sut/srm-1 (sut/ebc->rgba -1.97))) - (is (= sut/srm-6 (sut/ebc->rgba 12.21))) - (is (= sut/srm-6 (sut/ebc->rgba 13.40))) - (is (= sut/srm-40 (sut/ebc->rgba 80.77))))) - - -(deftest conversion-test - (testing "Ensure various color unit conversions behave as expected" - (is (= 10.0 (bp/->2dp (sut/lovibond->srm 7.94)) (bp/->2dp (sut/ebc->srm 19.69)))) - (is (= 23.2 (bp/->2dp (sut/srm->lovibond 30.66)) (bp/->2dp (sut/ebc->lovibond 60.38)))) - (is (= -45.53 (bp/->2dp (sut/srm->ebc -23.11)) (bp/->2dp (sut/lovibond->ebc -16.5)))))) diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index 76b7864..b90468c 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -4,8 +4,8 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.equipment :as equipment.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-equipment diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index 544030e..219525e 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -4,8 +4,8 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.fermentables :as fermentables.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-fermentable diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index 0ed0a19..cf90ad2 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -5,8 +5,8 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.hops :as hops.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (defn random-hop-type diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index cb4f108..854d142 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -4,8 +4,8 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.mash :as mash.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-mash-step @@ -72,7 +72,7 @@ (defn generate-mash-steps-wrapper "Generate a random mash-steps object" - {:added "1.3" + {:added "2.0" :no-doc true} [] {:mash-steps (gen/generate (spec/gen ::mash.format/mash-steps))}) diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index b40f46f..0aa7545 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -4,8 +4,8 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.miscs :as miscs.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-misc @@ -13,7 +13,7 @@ {:amount 0.010 :name "Irish Moss" :notes "Used as a clarifying agent during the last few minutes of the boil" - :time 15.0 + :time 15.1 :type "Fining" :use "Boil" :version 1}) diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index 4844b90..ac13723 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -13,13 +13,13 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.recipes :as recipes.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (defn random-ibu-method "Return a random valid hop type." - {:added "1.3" + {:added "2.0" :no-doc true} [] (-> recipes.format/ibu-method-types diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index 58613f3..aa3268f 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -4,8 +4,8 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.styles :as style.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-style diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 19b7144..9e18bcb 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -4,13 +4,13 @@ [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.waters :as waters.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (defn random-ph "Generate a random `:ph` value." - {:added "1.4" + {:added "2.0" :no-doc true} [] (rand 14)) @@ -53,7 +53,7 @@ (defn generate-water "Generate a random water object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::waters.format/water))) @@ -61,7 +61,7 @@ (defn generate-water-wrapper "Generate a random water-wrapper object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::waters.format/water-wrapper))) @@ -69,7 +69,7 @@ (defn generate-waters "Generate a random waters object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::waters.format/waters))) @@ -77,7 +77,7 @@ (defn generate-waters-wrapper "Generate a random waters-wrapper object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::waters.format/waters-wrapper))) diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 1095176..9ed0169 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -5,13 +5,13 @@ [com.wallbrew.spoon.spec :as spoon.spec] [com.wallbrew.spoon.string :as spoon.str] [common-beer-format.yeasts :as yeasts.format] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (defn random-flocculation "Return a random valid flocculation." - {:added "1.4" + {:added "2.0" :no-doc true} [] (-> yeasts.format/yeast-flocculation-types @@ -59,7 +59,7 @@ (defn generate-yeast "Generate a random yeast object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeast))) @@ -67,7 +67,7 @@ (defn generate-yeast-wrapper "Generate a random yeast-wrapper object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeast-wrapper))) @@ -75,7 +75,7 @@ (defn generate-yeasts "Generate a random yeasts object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeasts))) @@ -83,7 +83,7 @@ (defn generate-yeasts-wrapper "Generate a random yeasts-wrapper object" - {:added "1.4" + {:added "2.0" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeasts-wrapper))) diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index d17fd9f..b811eeb 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -1,9 +1,9 @@ (ns brewtility.enrich.impl-test (:require [brewtility.enrich.impl :as sut] - [brewtility.static :as static] + [brewtility.units.options :as options] [clojure.string :as str] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest ->displayable-volume-test @@ -23,17 +23,17 @@ "Conversion may override the default suffix")) (testing "Ensure ->displayable-volume supports its full suite of options with static keys" (is (= "5.678 l" - (sut/->displayable-volume 1.5 static/american-gallon static/liter) - (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision static/default-precision - static/suffix static/short})) + (sut/->displayable-volume 1.5 options/american-gallon options/liter) + (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision options/default-precision + options/suffix options/short})) "Conversion defaults to 3 digits of precisions and shorthand unit names with static keys") (is (= "5.7 l" - (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision 1 - static/suffix static/short})) + (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision with static keys") (is (= "5.678 liter" - (sut/->displayable-volume 1.5 static/american-gallon static/liter {static/precision 3 - static/suffix static/full})) + (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix with static keys"))) @@ -199,10 +199,10 @@ (is (= valid-opts (sut/verify-enrich-displayable-volume-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units static/teaspoon - static/system-of-measure static/metric - static/precision 2 - static/suffix static/full}] + (let [valid-opts-w-keys {:target-units options/teaspoon + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] (is (= valid-opts-w-keys (sut/verify-enrich-displayable-volume-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" @@ -235,10 +235,10 @@ (is (= valid-opts (sut/verify-enrich-displayable-weight-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units static/pound - static/system-of-measure static/metric - static/precision 2 - static/suffix static/full}] + (let [valid-opts-w-keys {:target-units options/pound + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] (is (= valid-opts-w-keys (sut/verify-enrich-displayable-weight-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" @@ -271,10 +271,10 @@ (is (= valid-opts (sut/verify-enrich-displayable-time-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units static/minute - static/system-of-measure static/metric - static/precision 2 - static/suffix static/full}] + (let [valid-opts-w-keys {:target-units options/minute + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] (is (= valid-opts-w-keys (sut/verify-enrich-displayable-time-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" @@ -307,10 +307,10 @@ (is (= valid-opts (sut/verify-enrich-displayable-temperature-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units static/c - static/system-of-measure static/metric - static/precision 2 - static/suffix static/full}] + (let [valid-opts-w-keys {:target-units options/c + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] (is (= valid-opts-w-keys (sut/verify-enrich-displayable-temperature-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc index c475685..c690c4c 100644 --- a/test/brewtility/enrich/miscs_test.cljc +++ b/test/brewtility/enrich/miscs_test.cljc @@ -44,10 +44,6 @@ (deftest enrich-display-time-test (testing "Ensure enricher correctly defaults to setting display time" - (is (= "15.0 m" (-> miscs.data/sample-misc - miscs.enrich/enrich-display-time - :display-time)) - "miscs.data/sample-misc sets the time to 15.0, which is the default unit") (is (= "15.555 m" (-> miscs.data/sample-misc (assoc :time 15.555) miscs.enrich/enrich-display-time @@ -58,13 +54,13 @@ (miscs.enrich/enrich-display-time {:misc-time-precision 2}) :display-time)) "enrich-display-time can be configured to use a different precision") - (is (= "900.0 s" (-> miscs.data/sample-misc - (assoc :time 15.0) + (is (= "13.2 s" (-> miscs.data/sample-misc + (assoc :time 0.22) (miscs.enrich/enrich-display-time {:misc-time-target-units :second}) :display-time)) "enrich-display-time unites can be configured to use seconds") - (is (= "15.0 minute" (-> miscs.data/sample-misc - (assoc :time 15.0) + (is (= "15.1 minute" (-> miscs.data/sample-misc + (assoc :time 15.1) (miscs.enrich/enrich-display-time {:misc-time-suffix :full}) :display-time)) "enrich-display-time can be configured to use full suffixes") @@ -73,13 +69,13 @@ (miscs.enrich/enrich-display-time {:precision 2}) :display-time)) "enrich-display-time can be configured to use a different precision with default settings keys") - (is (= "15.0 m" (-> miscs.data/sample-misc - (assoc :time 15.0) + (is (= "15.1 m" (-> miscs.data/sample-misc + (assoc :time 15.1) (miscs.enrich/enrich-display-time {:system-of-measure :metric}) :display-time)) "enrich-display-time unites can be configured with default settings keys") - (is (= "15.0 minute" (-> miscs.data/sample-misc - (assoc :time 15.0) + (is (= "15.1 minute" (-> miscs.data/sample-misc + (assoc :time 15.1) (miscs.enrich/enrich-display-time {:suffix :full}) :display-time)) "enrich-display-time can be configured to use full suffixes with default settings keys")) @@ -105,8 +101,8 @@ (miscs.enrich/enrich-display-amount {:misc-amount-precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision") - (is (= "15000.0 g" (-> weighted-misc - (assoc :amount 15.0) + (is (= "15444.4 g" (-> weighted-misc + (assoc :amount 15.4444) (miscs.enrich/enrich-display-amount {:misc-amount-target-units :gram}) :display-amount)) "enrich-display-amount unites can be configured to use seconds") @@ -120,8 +116,8 @@ (miscs.enrich/enrich-display-amount {:precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision with default settings keys") - (is (= "15.0 kg" (-> weighted-misc - (assoc :amount 15.0) + (is (= "15.4 kg" (-> weighted-misc + (assoc :amount 15.4) (miscs.enrich/enrich-display-amount {:system-of-measure :metric}) :display-amount)) "enrich-display-amount unites can be configured with default settings keys") @@ -161,8 +157,8 @@ (miscs.enrich/enrich-display-amount {:precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision with default settings keys") - (is (= "15.0 l" (-> volume-misc - (assoc :amount 15.0) + (is (= "15.1 l" (-> volume-misc + (assoc :amount 15.1) (miscs.enrich/enrich-display-amount {:system-of-measure :metric}) :display-amount)) "enrich-display-amount unites can be configured with default settings keys") @@ -210,11 +206,11 @@ "Enrichment pattern should produce a valid misc object") (testing "Static data comparison for enrichment pattern functions" (is (= {:amount 0.01 - :display-time "15.0 m" + :display-time "15.1 m" :amount-is-weight false :use "Boil" :name "Irish Moss" - :time 15.0 + :time 15.1 :type "Fining" :notes "Used as a clarifying agent during the last few minutes of the boil" :display-amount "0.003 gal" diff --git a/test/brewtility/enrich/waters_test.cljc b/test/brewtility/enrich/waters_test.cljc index 7eddd11..1945442 100644 --- a/test/brewtility/enrich/waters_test.cljc +++ b/test/brewtility/enrich/waters_test.cljc @@ -38,8 +38,8 @@ (waters.enrich/enrich-display-amount {:precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision with default settings keys") - (is (= "15.0 l" (-> waters.data/sample-water - (assoc :amount 15.0) + (is (= "15.1 l" (-> waters.data/sample-water + (assoc :amount 15.1) (waters.enrich/enrich-display-amount {:system-of-measure :metric}) :display-amount)) "enrich-display-amount unites can be configured with default settings keys") diff --git a/test/brewtility/enrich/yeasts_test.cljc b/test/brewtility/enrich/yeasts_test.cljc index dbf3691..837bdc5 100644 --- a/test/brewtility/enrich/yeasts_test.cljc +++ b/test/brewtility/enrich/yeasts_test.cljc @@ -59,8 +59,8 @@ (yeasts.enrich/enrich-display-amount {:yeast-amount-precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision") - (is (= "15000.0 g" (-> weighted-yeast - (assoc :amount 15.0) + (is (= "15444.4 g" (-> weighted-yeast + (assoc :amount 15.4444) (yeasts.enrich/enrich-display-amount {:yeast-amount-target-units :gram}) :display-amount)) "enrich-display-amount unites can be configured to use seconds") @@ -74,8 +74,8 @@ (yeasts.enrich/enrich-display-amount {:precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision with default settings keys") - (is (= "15.0 kg" (-> weighted-yeast - (assoc :amount 15.0) + (is (= "15.4 kg" (-> weighted-yeast + (assoc :amount 15.4) (yeasts.enrich/enrich-display-amount {:system-of-measure :metric}) :display-amount)) "enrich-display-amount unites can be configured with default settings keys") @@ -115,8 +115,8 @@ (yeasts.enrich/enrich-display-amount {:precision 2}) :display-amount)) "enrich-display-amount can be configured to use a different precision with default settings keys") - (is (= "15.0 l" (-> volume-yeast - (assoc :amount 15.0) + (is (= "15.1 l" (-> volume-yeast + (assoc :amount 15.1) (yeasts.enrich/enrich-display-amount {:system-of-measure :metric}) :display-amount)) "enrich-display-amount unites can be configured with default settings keys") diff --git a/test/brewtility/runner.cljs b/test/brewtility/runner.cljs index 8b932bc..2dbe1f7 100644 --- a/test/brewtility/runner.cljs +++ b/test/brewtility/runner.cljs @@ -13,6 +13,13 @@ [brewtility.data.styles] [brewtility.data.waters] [brewtility.data.yeasts] + [brewtility.enrich.equipment-test] + [brewtility.enrich.fermentables-test] + [brewtility.enrich.hops-test] + [brewtility.enrich.mash-test] + [brewtility.enrich.miscs-test] + [brewtility.enrich.waters-test] + [brewtility.enrich.yeasts-test] [brewtility.precision-test] [brewtility.predicates.equipment-test] [brewtility.predicates.fermentables-test] @@ -47,6 +54,13 @@ 'brewtility.data.styles 'brewtility.data.waters 'brewtility.data.yeasts + 'brewtility.enrich.equipment-test + 'brewtility.enrich.fermentables-test + 'brewtility.enrich.hops-test + 'brewtility.enrich.mash-test + 'brewtility.enrich.miscs-test + 'brewtility.enrich.waters-test + 'brewtility.enrich.yeasts-test 'brewtility.precision-test 'brewtility.predicates.equipment-test 'brewtility.predicates.fermentables-test diff --git a/test/brewtility/string_test.cljc b/test/brewtility/string_test.cljc deleted file mode 100644 index 2e5cff3..0000000 --- a/test/brewtility/string_test.cljc +++ /dev/null @@ -1,51 +0,0 @@ -(ns brewtility.string-test - (:require [brewtility.string :as sut] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) - - -(deftest prepare-for-compare-test - (testing "Strings are appropriately re-cased and trimmed of whitespace" - (is (= "" (sut/prepare-for-compare " "))) - (is (= "clojure" (sut/prepare-for-compare "ClOjUrE "))) - (is (= "clojure" (sut/prepare-for-compare "ClOjUrE " {:uppercase? false}))) - (is (= "clojure" (sut/prepare-for-compare "ClOjUrE " {sut/cast-to-uppercase? false}))) - (is (= "clojure" (sut/prepare-for-compare "clojure"))) - (is (= "100 lines of code" (sut/prepare-for-compare " 100 lines of CODE"))) - (is (= "a b" (sut/prepare-for-compare " a b "))) - (is (= "CLOJURE" (sut/prepare-for-compare "ClOjUrE " {:uppercase? true}))) - (is (= "CLOJURE" (sut/prepare-for-compare "ClOjUrE " {sut/cast-to-uppercase? true}))) - (is (= "CLOJURE" (sut/prepare-for-compare "clojure" {:uppercase? true}))) - (is (= "100 LINES OF CODE" (sut/prepare-for-compare " 100 lines of CODE" {:uppercase? true}))) - (is (= "A B" (sut/prepare-for-compare " a b " {:uppercase? true}))) - (is (= ":CLOJURE" (sut/prepare-for-compare :ClOjUrE {:uppercase? true :coerce? true}))) - (is (= "CLOJURE" (sut/prepare-for-compare "clojure" {:uppercase? true :coerce? true}))) - (is (= "100" (sut/prepare-for-compare 100 {:uppercase? true :coerce? true}))) - (is (= "true" (sut/prepare-for-compare true {:coerce? true}))) - (is (= "" (sut/prepare-for-compare nil {:coerce? true}))))) - - -(deftest same?-test - (testing "Strings containing matching characters after perparation match" - (is (true? (sut/same? " clojure" "CLOJURE "))) - (is (true? (sut/same? "clojure " " CLOJURE " {:uppercase? true}))) - (is (true? (sut/same? " 100 LINES OF CODE" "100 LINES OF CODE "))) - (is (false? (sut/same? "clo jure" "CLOJURE"))) - (is (false? (sut/same? "100" "!))" {:uppercase? true}))) - (is (true? (sut/same? true "true" {:coerce? true}))) - (is (true? (sut/same? nil "" {:coerce? true}))) - (is (true? (sut/same? :carrot ":CARROT" {:coerce? true}))))) - - -(deftest includes?-test - (testing "Strings containing matching characters after perparation match" - (is (true? (sut/includes? " clojure" "CLOJURE "))) - (is (true? (sut/includes? "CLOJURE " "c"))) - (is (true? (sut/includes? "clojure " " CLOJURE " {:uppercase? true}))) - (is (true? (sut/includes? "100 LINES OF CODE " " 100 "))) - (is (false? (sut/includes? "clo" "CLOJURE"))) - (is (false? (sut/includes? "100" "!))" {:uppercase? true}))) - (is (true? (sut/includes? "falsefaasetrue" true {:coerce? true}))) - (is (true? (sut/includes? nil "" {:coerce? true}))) - (is (true? (sut/includes? :carrot ":CARROT" {:coerce? true}))))) - From a07c4f164f0e1b5007761926e194e218f260db46 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 00:56:33 +0000 Subject: [PATCH 24/44] Fix rebasing errors --- doc/cljdoc.edn | 2 +- doc/{ => patterns}/enricher-pattern.md | 0 doc/symbolic-keywords.md | 51 ---------------------- src/brewtility/enrich/impl.cljc | 14 +++--- src/brewtility/units.cljc | 3 -- src/brewtility/units/color.cljc | 4 +- src/brewtility/units/pressure.cljc | 8 ++-- src/brewtility/units/specific_gravity.cljc | 8 ++-- src/brewtility/units/temperature.cljc | 8 ++-- src/brewtility/units/time.cljc | 6 +-- src/brewtility/units/volume.cljc | 6 +-- src/brewtility/units/weight.cljc | 6 +-- test/brewtility/data/mash.cljc | 2 +- test/brewtility/data/recipes.cljc | 2 +- test/brewtility/data/styles.cljc | 4 +- test/brewtility/data/waters.cljc | 6 +-- test/brewtility/data/yeasts.cljc | 10 ++--- 17 files changed, 43 insertions(+), 97 deletions(-) rename doc/{ => patterns}/enricher-pattern.md (100%) delete mode 100644 doc/symbolic-keywords.md diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index 2d29b52..ec89b11 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -13,5 +13,5 @@ ["Units of Measure" {:file "doc/api/units.md"}] ["Wrapping" {:file "doc/api/wrapping.md"}]] ["Adopted Patterns" {} - ["Enricher Pattern" {:file "doc/enricher-pattern.md"}] + ["Enricher Pattern" {:file "doc/patterns/enricher-pattern.md"}] ["Symbolic Keywords" {:file "doc/patterns/symbolic_keywords.md"}]]]} diff --git a/doc/enricher-pattern.md b/doc/patterns/enricher-pattern.md similarity index 100% rename from doc/enricher-pattern.md rename to doc/patterns/enricher-pattern.md diff --git a/doc/symbolic-keywords.md b/doc/symbolic-keywords.md deleted file mode 100644 index cdda860..0000000 --- a/doc/symbolic-keywords.md +++ /dev/null @@ -1,51 +0,0 @@ -# Symbolic Keywords - -In many clojure libraries, the behavior of complex functions may be controlled by a map. -For example: - -```clojure -(:require [brewtility.units :as units]) -(units/display :volume 1.5 :liter) ;; => "1.5 l" -(units/display :volume 1.5 :liter {:suffix :full}) ;; => "1.5 liter" -``` - -This allows us to easily extend the definition of a single function to fulfill multiple complex needs; however, option maps come with considerable drawbacks. -When a map is keyed with keywords, it is easy to introduce subtle, hard-to-detect errors. -Since most of these functions select default values for keys not present, typos can lead to meaningful differences in behavior. -For example: - -```clojure -(:require [brewtility.units :as units]) -(units/display :volume 1.5 :liter) ;; => "1.5 l" - -;; Not the missing "f" in the key :sufix -(units/display :volume 1.5 :liter {:sufix :full}) ;; => "1.5 l" -``` - -Because keywords aren't picked up by the auto-complete features of most editors, they're vulnerable to all classes of transpositional errors. -Further, the options themselves are unable to carry metadata and documentation with them, making them little more than magic values. - -For this reason, it is helpful for libraries to include symbols which point to the "magic" keywords used in option maps. -This has several benefits: - -- Misspelled or incorrect option keys are compile-time errors, instead of runtime bugs -- Symbols can carry metadata like documentation, deprecation notices, and point to alternative options -- Context-aware editors can auto-complete options - -Here's can example: - -```clojure -(:require [brewtility.units :as units] - [brewtility.units.options :as options]) - -(units/display options/volume 1.5 options/liter) ;; => "1.5 l" -(units/display options/volume 1.5 options/liter {options/suffix options/full}) ;; => "1.5 liter" -``` - -Most option maps in `brewtility` support symbolic keywords. -These keywords are available in the namespaces ending in `.options`. -These files live as close to the code relying on them as possible; -for example, the options for all unit conversion operations (e.g. `brewtility.units`, `brewtility.units.time`, `brewtility.units.color`, etc.) are available in `brewtility.units.options`. - -Further, the option keywords are preferred for library development. -A single source of truth for the name of a common option, such as `precision`, limits the possibility of incorrectly retrieving the values used by that option. diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 53d1a05..80e38a5 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -16,27 +16,27 @@ options/suffix options/short}) -(def ^:const value-key +(def value-key "The key to source data from in `->displayable` functions" :value-key) -(def ^:const display-key +(def display-key "The key to store displayable data in in `->displayable` functions" :display-key) -(def ^:const fine-grain-target-units +(def fine-grain-target-units "The target units to use for fine-grain toggling of displayable units in `->displayable` functions" :fine-grain-target-units) -(def ^:const fine-grain-precision +(def fine-grain-precision "The suffix to use for fine-grain setting of precision in `->displayable` functions" :fine-grain-precision) -(def ^:const fine-grain-suffix +(def fine-grain-suffix "The suffix to use for fine-grain setting of precision in `->displayable` functions" :fine-grain-suffix) @@ -139,14 +139,14 @@ options/international-system options/kilogram}) -(def ^:private ^:const default-time-by-system +(def ^:private default-time-by-system {options/imperial options/minute options/metric options/minute options/us-customary options/minute options/international-system options/minute}) -(def ^:private ^:const default-temperature-by-system +(def ^:private default-temperature-by-system {options/imperial options/fahrenheit options/metric options/celsius options/us-customary options/fahrenheit diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 6f851b1..311a565 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -29,9 +29,6 @@ [brewtility.units.weight :as weight])) -;; -;; Weight -;; (defn convert "Given a `measurement` in `source-units`, convert it to the `target-units` in a given `measurement-type`. diff --git a/src/brewtility/units/color.cljc b/src/brewtility/units/color.cljc index 0c50262..71218f9 100644 --- a/src/brewtility/units/color.cljc +++ b/src/brewtility/units/color.cljc @@ -14,7 +14,7 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The color systems available across brewtility." #{options/srm options/ebc @@ -22,7 +22,7 @@ options/rgba}) -(def ^:const measurements->display-name +(def measurements->display-name "A map from color system names to their full and short unit names" {options/srm {options/full "standard reference method" options/short "srm"} diff --git a/src/brewtility/units/pressure.cljc b/src/brewtility/units/pressure.cljc index 26efaba..0967cc6 100644 --- a/src/brewtility/units/pressure.cljc +++ b/src/brewtility/units/pressure.cljc @@ -16,7 +16,7 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The pressure measurements supported by brewtility." #{options/pascal options/kilopascal @@ -26,7 +26,7 @@ options/psi}) -(def ^:const measurements->display-name +(def measurements->display-name "A map of pressure measurements to their display names." {options/pascal {options/full "pascal" options/short "pa"} @@ -122,7 +122,7 @@ (/ pressure 6.894757)) -(def ^:const measurement->kilopascal +(def measurement->kilopascal "A map of pressure measurements to functions that convert to kilopascals." {options/pascal pascal->kilopascal options/kilopascal identity @@ -132,7 +132,7 @@ options/psi psi->kilopascal}) -(def ^:const kilopascal->measurement +(def kilopascal->measurement "A map of pressure measurements to functions that convert from kilopascals." {options/pascal kilopascal->pascal options/kilopascal identity diff --git a/src/brewtility/units/specific_gravity.cljc b/src/brewtility/units/specific_gravity.cljc index 808c4af..759d673 100644 --- a/src/brewtility/units/specific_gravity.cljc +++ b/src/brewtility/units/specific_gravity.cljc @@ -11,23 +11,23 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The specific gravity systems available across brewtility." #{options/specific-gravity}) -(def ^:const measurements->display-name +(def measurements->display-name "A map from specific gravity system names to their full and short unit names." {options/specific-gravity {options/full "specific gravity" options/short "sg"}}) -(def ^:const measurement->specific-gravity +(def measurement->specific-gravity "A map from specific gravity system names to the conversion function to specific gravity." {options/specific-gravity identity}) -(def ^:const specific-gravity->measurement +(def specific-gravity->measurement "A map from specific gravity system names to the conversion function from specific gravity." {options/specific-gravity identity}) diff --git a/src/brewtility/units/temperature.cljc b/src/brewtility/units/temperature.cljc index b7d3a9a..8d2b337 100644 --- a/src/brewtility/units/temperature.cljc +++ b/src/brewtility/units/temperature.cljc @@ -13,7 +13,7 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The temperature measurements supported by brewtility." #{options/c options/celsius @@ -24,7 +24,7 @@ options/kelvin}) -(def ^:const measurements->display-name +(def measurements->display-name "The temperature measurements supported by brewtility." {options/c {options/full "celsius" options/short "c"} @@ -74,7 +74,7 @@ (- temp 273.15)) -(def ^:const measurement->celsius +(def measurement->celsius "A map from measurement names to the implementation function which converts them to degrees celsius" {options/c identity options/celsius identity @@ -85,7 +85,7 @@ options/kelvin kelvin->celsius}) -(def ^:const celsius->measurement +(def celsius->measurement "A map from measurement names to the implementation function which converts them from degrees celsius" {options/celsius identity options/c identity diff --git a/src/brewtility/units/time.cljc b/src/brewtility/units/time.cljc index 3b4bcee..df744ed 100644 --- a/src/brewtility/units/time.cljc +++ b/src/brewtility/units/time.cljc @@ -19,7 +19,7 @@ (:refer-clojure :exclude [time])) -(def ^:const measurements +(def measurements "The time measurements available across brewtility" #{options/day options/hour @@ -31,7 +31,7 @@ options/week}) -(def ^:const measurement->minute +(def measurement->minute "A map from measurement names to doubles representing their fractional value to one minute" {options/day 1440.0 options/hour 60.0 @@ -43,7 +43,7 @@ options/week 10080.0}) -(def ^:const measurements->display-name +(def measurements->display-name "A map from measurement names to their full name and abbreviation" {options/day {options/full "days" options/short "d"} diff --git a/src/brewtility/units/volume.cljc b/src/brewtility/units/volume.cljc index 0c009a6..dd24f91 100644 --- a/src/brewtility/units/volume.cljc +++ b/src/brewtility/units/volume.cljc @@ -25,7 +25,7 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The volume measurements available across brewtility" #{options/american-gallon options/american-pint @@ -44,7 +44,7 @@ options/imperial-fluid-ounce}) -(def ^:const measurement->litre +(def measurement->litre "A map from measurement names to doubles representing their fractional value to one liter" {options/american-fluid-ounce 0.0295735 options/american-gallon 3.78541 @@ -63,7 +63,7 @@ options/teaspoon 0.00492892}) -(def ^:const measurements->display-name +(def measurements->display-name "A map from measurement names to their full name and abbreviation" {options/american-fluid-ounce {options/full "fluid ounce" options/short "fl oz"} diff --git a/src/brewtility/units/weight.cljc b/src/brewtility/units/weight.cljc index eb09fe8..e7a68d5 100644 --- a/src/brewtility/units/weight.cljc +++ b/src/brewtility/units/weight.cljc @@ -15,7 +15,7 @@ [brewtility.units.options :as options])) -(def ^:const measurements +(def measurements "The weight measurements available across brewtility" #{options/gram options/kilogram @@ -24,7 +24,7 @@ options/pound}) -(def ^:const measurement->kilogram +(def measurement->kilogram "A map from measurement names to doubles representing their fractional value to one kilogram" {options/gram 0.001 options/kilogram 1.0 @@ -33,7 +33,7 @@ options/pound 0.45359237}) -(def ^:const measurements->display-name +(def measurements->display-name "A map from measurement names to their full name and abbreviation" {options/gram {options/full "gram" options/short "g"} diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index 854d142..4ff7911 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -28,7 +28,7 @@ [sample-mash-step-wrapper]) -(def ^:const sample-mash-steps-wrapper +(def sample-mash-steps-wrapper "A hard-coded sample mash-steps-wrapper for static unit tests" {:mash-steps sample-mash-steps}) diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index ac13723..ca23f72 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -19,7 +19,7 @@ (defn random-ibu-method "Return a random valid hop type." - {:added "2.0" + {:added "1.4" :no-doc true} [] (-> recipes.format/ibu-method-types diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index aa3268f..b457109 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -37,12 +37,12 @@ {:style sample-style}) -(def ^:const sample-styles +(def sample-styles "A hard-coded sample styles for static unit tests" [sample-style-wrapper]) -(def ^:const sample-styles-wrapper +(def sample-styles-wrapper "A hard-coded sample styles-wrapper for static unit tests" {:styles sample-styles}) diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 9e18bcb..1c07eb5 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -61,7 +61,7 @@ (defn generate-water-wrapper "Generate a random water-wrapper object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::waters.format/water-wrapper))) @@ -69,7 +69,7 @@ (defn generate-waters "Generate a random waters object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::waters.format/waters))) @@ -77,7 +77,7 @@ (defn generate-waters-wrapper "Generate a random waters-wrapper object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::waters.format/waters-wrapper))) diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 9ed0169..04c2495 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -11,7 +11,7 @@ (defn random-flocculation "Return a random valid flocculation." - {:added "2.0" + {:added "1.4" :no-doc true} [] (-> yeasts.format/yeast-flocculation-types @@ -59,7 +59,7 @@ (defn generate-yeast "Generate a random yeast object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeast))) @@ -67,7 +67,7 @@ (defn generate-yeast-wrapper "Generate a random yeast-wrapper object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeast-wrapper))) @@ -75,7 +75,7 @@ (defn generate-yeasts "Generate a random yeasts object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeasts))) @@ -83,7 +83,7 @@ (defn generate-yeasts-wrapper "Generate a random yeasts-wrapper object" - {:added "2.0" + {:added "1.4" :no-doc true} [] (gen/generate (spec/gen ::yeasts.format/yeasts-wrapper))) From a6d3850a3e4652779565e361b75f2d7feb11e2c7 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 00:57:25 +0000 Subject: [PATCH 25/44] Fix rebasing errors --- .github/workflows/clojure.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clojure.yml b/.github/workflows/clojure.yml index 450a44a..90a8408 100644 --- a/.github/workflows/clojure.yml +++ b/.github/workflows/clojure.yml @@ -14,7 +14,7 @@ jobs: - name: Cache maven dependencies uses: actions/cache@v4 env: - cache-name: cache-maven + cache-name: cache-maven with: path: ~/.m2 save-always: true From d4b23ee29da8932b9935bd26db4e3902c919cdf6 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 00:58:15 +0000 Subject: [PATCH 26/44] Fix rebasing errors --- .github/workflows/format.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index ca1901e..b36b14b 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,18 +13,6 @@ jobs: ref: ${{ github.head_ref }} token: ${{ secrets.WALL_BREW_BOT_PAT }} - - name: Cache maven dependencies - uses: actions/cache@v3 - env: - cache-name: cache-maven - with: - path: | - ~/.m2/repository - ~/.gitlibs - key: ${{ runner.os }}-clj-${{ hashFiles('**/project.clj') }} - restore-keys: | - ${{ runner.os }}-clj - - name: Install cljstyle uses: just-sultanov/setup-cljstyle@v1 with: @@ -34,9 +22,6 @@ jobs: run: | cljstyle fix --report --report-timing --verbose - - name: Rebuild pom.xml - run: lein pom - - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5.0.0 with: From d9664b0a2d03b963ed8269d65cee89908904e011 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 00:59:10 +0000 Subject: [PATCH 27/44] Fix rebasing errors --- src/brewtility/enrich/impl.cljc | 1 + src/brewtility/units.cljc | 1 - test/brewtility/enrich/impl_test.cljc | 6 +++--- test/brewtility/enrich/miscs_test.cljc | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 80e38a5..c9bf96b 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -108,6 +108,7 @@ (temperature/convert source-units target-units) (temperature/display target-units opts)))) + ;; TODO: Pluralize strings (defn ->displayable-color "Convert a color then render it to a displayable value." diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 311a565..76b1735 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -29,7 +29,6 @@ [brewtility.units.weight :as weight])) - (defn convert "Given a `measurement` in `source-units`, convert it to the `target-units` in a given `measurement-type`. diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index b811eeb..c5cfabf 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -25,15 +25,15 @@ (is (= "5.678 l" (sut/->displayable-volume 1.5 options/american-gallon options/liter) (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision options/default-precision - options/suffix options/short})) + options/suffix options/short})) "Conversion defaults to 3 digits of precisions and shorthand unit names with static keys") (is (= "5.7 l" (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 1 - options/suffix options/short})) + options/suffix options/short})) "Conversion may override the default precision with static keys") (is (= "5.678 liter" (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 3 - options/suffix options/full})) + options/suffix options/full})) "Conversion may override the default suffix with static keys"))) diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc index c690c4c..5deaa7e 100644 --- a/test/brewtility/enrich/miscs_test.cljc +++ b/test/brewtility/enrich/miscs_test.cljc @@ -55,9 +55,9 @@ :display-time)) "enrich-display-time can be configured to use a different precision") (is (= "13.2 s" (-> miscs.data/sample-misc - (assoc :time 0.22) - (miscs.enrich/enrich-display-time {:misc-time-target-units :second}) - :display-time)) + (assoc :time 0.22) + (miscs.enrich/enrich-display-time {:misc-time-target-units :second}) + :display-time)) "enrich-display-time unites can be configured to use seconds") (is (= "15.1 minute" (-> miscs.data/sample-misc (assoc :time 15.1) From 6bdf54a0080c7f9bcd47d3c0f018583bbbf6949c Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 12 Jun 2023 02:44:40 +0000 Subject: [PATCH 28/44] Fix :added keys --- src/brewtility/enrich/equipment.cljc | 24 ++++++++++----------- src/brewtility/enrich/fermentables.cljc | 28 ++++++++++++------------- src/brewtility/enrich/hops.cljc | 14 ++++++------- src/brewtility/enrich/mash.cljc | 26 +++++++++++------------ src/brewtility/enrich/miscs.cljc | 16 +++++++------- src/brewtility/enrich/styles.cljc | 2 +- src/brewtility/enrich/waters.cljc | 12 +++++------ src/brewtility/enrich/yeasts.cljc | 18 ++++++++-------- 8 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc index 19b0349..f095b46 100644 --- a/src/brewtility/enrich/equipment.cljc +++ b/src/brewtility/enrich/equipment.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.equipment "Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.fermentables" "brewtility.enrich.hops" "brewtility.enrich.mash" @@ -33,7 +33,7 @@ Defaults to `false`. - `:precision` - The number of decimal places to round the calculated value to. Defaults to `3`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.calculations/calculate-equipment-boil-volume" "enrich-equipment" "enrich-equipment-wrapper"]} @@ -77,7 +77,7 @@ - `:boil-size-target-units`: The unit to convert the boil size into. Supersedes `:system-of-measure`. - `:boil-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:boil-size-suffix`: The suffix type to append to the boil size. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-boil-size equipment {})) ([equipment @@ -112,7 +112,7 @@ - `:batch-size-target-units`: The unit to convert the batch size into. Supersedes `:system-of-measure`. - `:batch-size-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:batch-size-suffix`: The suffix type to append to the batch size. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-batch-size equipment {})) ([equipment @@ -147,7 +147,7 @@ - `:tun-volume-target-units`: The unit to convert the tun volume into. Supersedes `:system-of-measure`. - `:tun-volume-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:tun-volume-suffix`: The suffix type to append to the tun volume. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-tun-volume equipment {})) ([equipment @@ -182,7 +182,7 @@ - `:tun-weight-target-units`: The unit to convert the tun weight into. Supersedes `:system-of-measure`. - `:tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:tun-weight-suffix`: The suffix type to append to the tun weight. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-tun-weight equipment {})) ([equipment @@ -217,7 +217,7 @@ - `:top-up-water-target-units`: The unit to convert the top up water into. Supersedes `:system-of-measure`. - `:top-up-water-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-water-suffix`: The suffix type to append to the top up water. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-top-up-water equipment {})) ([equipment @@ -252,7 +252,7 @@ - `:trub-chiller-loss-target-units`: The unit to convert the trub chiller loss into. Supersedes `:system-of-measure`. - `:trub-chiller-loss-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:trub-chiller-loss-suffix`: The suffix type to append to the trub chiller loss. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-trub-chiller-loss equipment {})) ([equipment @@ -287,7 +287,7 @@ - `:lauter-deadspace-target-units`: The unit to convert the lauter deadspace into. Supersedes `:system-of-measure`. - `:lauter-deadspace-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:lauter-deadspace-suffix`: The suffix type to append to the lauter deadspace. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-lauter-deadspace equipment {})) ([equipment @@ -322,7 +322,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-equipment" "enrich-equipment-wrapper"]} ([equipment] (enrich-display-top-up-kettle equipment {})) ([equipment @@ -390,7 +390,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-calculated-boil-size" "enrich-calculated-boil-size" "enrich-diplay-tun-volume" @@ -469,7 +469,7 @@ - `:top-up-kettle-target-units`: The unit to convert the top up kettle into. Supersedes `:system-of-measure`. - `:top-up-kettle-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:top-up-kettle-suffix`: The suffix type to append to the top up kettle. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-calculated-boil-size" "enrich-calculated-boil-size" "enrich-diplay-tun-volume" diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 7d0dcb5..47433b2 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.fermentables "Enricher-pattern functions for [fermentables](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.hops" "brewtility.enrich.mash" @@ -19,7 +19,7 @@ "An enricher pattern function to determine if a [fermentable](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/fermentables.cljc) was added after the boil. In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the :add-after-boil field is not present, this function will explicitly set it to false." - {:added "2.0" + {:added "2.1" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -41,7 +41,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -66,7 +66,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -91,7 +91,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -116,7 +116,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -141,7 +141,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" "enrich-fermentable" @@ -166,7 +166,7 @@ - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.predicates.fermentables/extract?" "enrich-fermentable" "enrich-fermentable-wrapper" @@ -200,7 +200,7 @@ - `:fermentable-color-target-units`: The unit to convert the color into. Supersedes `:color-system`. - `:fermentable-color-precision`: The number of significant decimal places to display. Supersedes `:color`. - `:fermentable-color-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -254,7 +254,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-fermentable" "enrich-fermentable-wrapper" "enrich-fermentables" @@ -304,7 +304,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -363,7 +363,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -413,7 +413,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" @@ -463,7 +463,7 @@ - `:fermentable-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:fermentable-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:fermentable-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-add-after-boil" "enrich-coarse-fine-diff" "enrich-moisture" diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc index d239d33..1f41898 100644 --- a/src/brewtility/enrich/hops.cljc +++ b/src/brewtility/enrich/hops.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.hops "Enricher-pattern functions for [hops](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.mash" @@ -32,7 +32,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.string/same?" "enrich-hop" "enrich-hop-wrapper" @@ -71,7 +71,7 @@ - `:hop-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - `:hop-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-hop" "enrich-hop-wrapper" "enrich-hops" @@ -114,7 +114,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" @@ -152,7 +152,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop" @@ -188,7 +188,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" @@ -224,7 +224,7 @@ - `:hop-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:hop-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:hop-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-hop-wrapper" diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc index 4031179..20d24f2 100644 --- a/src/brewtility/enrich/mash.cljc +++ b/src/brewtility/enrich/mash.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.mash "Enricher-pattern functions for [mashes and mash steps](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/mash.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.mash-steps" "brewtility.enrich.fermentables" @@ -32,7 +32,7 @@ - `:display-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash-step" "enrich-mash-step-wrapper" @@ -73,7 +73,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.string/same?" "enrich-mash-step" "enrich-mash-step-wrapper" @@ -119,7 +119,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step-wrapper" @@ -159,7 +159,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -197,7 +197,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -235,7 +235,7 @@ - `:display-infuse-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-infuse-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-infuse-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-mash-step" @@ -268,7 +268,7 @@ - `:display-grain-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-grain-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-grain-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -305,7 +305,7 @@ - `:display-tun-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -342,7 +342,7 @@ - `:display-sparge-temperature-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-sparge-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-sparge-temperature-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.impl/->displayable-temperature" "enrich-mash" "enrich-mash-wrapper"]} @@ -379,7 +379,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.impl/->displayable-weight" "enrich-mash" "enrich-mash-wrapper"]} @@ -437,7 +437,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-display-grain-temperature" @@ -499,7 +499,7 @@ - `:display-tun-weight-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:display-tun-weight-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:display-tun-weight-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-step-temperature" "enrich-display-infuse-amount" "enrich-display-grain-temperature" diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index d757530..3dce83a 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.miscs "Enricher-pattern functions for [miscs](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -15,7 +15,7 @@ (defn enrich-amount-is-weight "An enricher pattern function to determine if a [misc](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/miscs.cljc) should be measured by weight/volume. When this feild is not present, it is assumed to be false." - {:added "2.0" + {:added "2.1" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -47,7 +47,7 @@ - `:misc-time-target-units`: The unit to convert the time into. Supersedes `:system-of-measure`. - `:misc-time-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-time-suffix`: The suffix type to append to the time. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -87,7 +87,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-misc" "enrich-misc-wrapper" "enrich-miscs" @@ -132,7 +132,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -172,7 +172,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -209,7 +209,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" @@ -246,7 +246,7 @@ - `:misc-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:misc-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:misc-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-display-time" "enrich-amount-is-weight" diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index 5163ddf..719604d 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.styles "Enricher-pattern functions for [styles](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/styles.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc index 4cee76f..2c565ac 100644 --- a/src/brewtility/enrich/waters.cljc +++ b/src/brewtility/enrich/waters.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.waters "Enricher-pattern functions for [waters](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -32,7 +32,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-water" "enrich-water-wrapper" "enrich-waters" @@ -71,7 +71,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-water-wrapper" "enrich-waters" @@ -103,7 +103,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-water" "enrich-waters" @@ -134,7 +134,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-water" "enrich-water-wrapper" @@ -165,7 +165,7 @@ - `:water-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:water-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:water-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-display-amount" "enrich-water" "enrich-water-wrapper" diff --git a/src/brewtility/enrich/yeasts.cljc b/src/brewtility/enrich/yeasts.cljc index e3b2690..b0f9dd4 100644 --- a/src/brewtility/enrich/yeasts.cljc +++ b/src/brewtility/enrich/yeasts.cljc @@ -1,6 +1,6 @@ (ns brewtility.enrich.yeasts "Enricher-pattern functions for [yeasts](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) maps" - {:added "2.0" + {:added "2.1" :see-also ["brewtility.enrich.equipment" "brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -15,7 +15,7 @@ (defn enrich-amount-is-weight "An enricher pattern function to determine if a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) should be measured by weight/volume. When this feild is not present, it is assumed to be false." - {:added "2.0" + {:added "2.1" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -49,7 +49,7 @@ - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `:yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-amount-suffix`: The suffix type to append to the amount. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -90,7 +90,7 @@ - `:yeast-min-temperature-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. - `:yeast-min-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-min-temperature-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -131,7 +131,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-yeast" "enrich-yeast-wrapper" "enrich-yeasts" @@ -181,7 +181,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -228,7 +228,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -271,7 +271,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" @@ -314,7 +314,7 @@ - `:yeast-max-temperature-target-units`: The unit to convert the max-temperature into. Supersedes `:system-of-measure`. - `:yeast-max-temperature-precision`: The number of significant decimal places to display. Supersedes `:precision`. - `:yeast-max-temperature-suffix`: The suffix type to append to the max-temperature. Supersedes `:suffix`." - {:added "2.0" + {:added "2.1" :see-also ["enrich-amount-is-weight" "enrich-display-amount" "enrich-display-min-temperature" From da713ce59092baa58ca5133596f486c5cd00413c Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 17 Jun 2023 17:42:01 +0000 Subject: [PATCH 29/44] Finish all base enrichers --- .sealog/changes/2-0-0.edn | 2 +- src/brewtility/enrich/impl.cljc | 785 +++++++++++++++++--------- src/brewtility/enrich/recipes.cljc | 13 + test/brewtility/enrich/impl_test.cljc | 168 +++--- 4 files changed, 609 insertions(+), 359 deletions(-) create mode 100644 src/brewtility/enrich/recipes.cljc diff --git a/.sealog/changes/2-0-0.edn b/.sealog/changes/2-0-0.edn index e3b6039..d1f55b5 100644 --- a/.sealog/changes/2-0-0.edn +++ b/.sealog/changes/2-0-0.edn @@ -13,7 +13,7 @@ "Display functions for all unit types."] :changed ["Internal functions that convert between unit systems now use `brewtility.units`"] :deprecated [] - :removed ["`brewility.color` has been removed in favor of `brewtility.units.color`" + :removed ["`brewtility.color` has been removed in favor of `brewtility.units.color`" "`brewtility.units/convert-weight` has been removed in favor of `brewtility.units/convert` and `brewtility.units.weight/convert`" "`brewtility.units/convert-volume` has been removed in favor of `brewtility.units/convert` and `brewtility.units.volume/convert`" "`brewtility.units/convert-temperature` has been removed in favor of `brewtility.units/convert` and `brewtility.units.temperature/convert`"] diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index c9bf96b..fd8d921 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -1,9 +1,14 @@ (ns brewtility.enrich.impl + "Function to help minimize repeated code in enricher functions. + + Not intended for public consumption." {:no-doc true :added "2.1" :implementation-only true} (:require [brewtility.units.color :as color] [brewtility.units.options :as options] + [brewtility.units.pressure :as pressure] + [brewtility.units.specific-gravity :as specific-gravity] [brewtility.units.temperature :as temperature] [brewtility.units.time :as time] [brewtility.units.volume :as volume] @@ -41,66 +46,127 @@ :fine-grain-suffix) +(def default-color-by-system + "The default color to use for each system in `->displayable` functions." + {options/imperial options/srm + options/metric options/srm + options/us-customary options/srm + options/international-system options/srm}) + + +(def default-pressure-by-system + "The default pressure to use for each system in `->displayable` functions." + {options/imperial options/psi + options/metric options/kilopascal + options/us-customary options/psi + options/international-system options/kilopascal}) + + +(def default-specific-gravity-by-system + "The default specific gravity to use for each system in `->displayable` functions." + {options/imperial options/specific-gravity + options/metric options/specific-gravity + options/us-customary options/specific-gravity + options/international-system options/specific-gravity}) + + +(def default-temperature-by-system + "The default temperature to use for each system in `->displayable` functions." + {options/imperial options/fahrenheit + options/metric options/celsius + options/us-customary options/fahrenheit + options/international-system options/celsius}) + + +(def default-time-by-system + "The default time to use for each system in `->displayable` functions." + {options/imperial options/minute + options/metric options/minute + options/us-customary options/minute + options/international-system options/minute}) + + +(def default-volume-by-system + "The default volume to use for each system in `->displayable` functions." + {options/imperial options/imperial-gallon + options/metric options/litre + options/us-customary options/american-gallon + options/international-system options/litre}) + + +(def default-weight-by-system + "The default weight to use for each system in `->displayable` functions." + {options/imperial options/pound + options/metric options/kilogram + options/us-customary options/pound + options/international-system options/kilogram}) + + ;; TODO: Pluralize strings -(defn ->displayable-volume - "Convert a volume then render it to a displayable value." - {:added "1.3.0" +(defn ->displayable-color + "Convert a color then render it to a displayable value." + {:added "2.1" :no-doc true - :see-also ["->displayable-weight" - "->displayable-time" + :see-also ["->displayable-pressure" + "->displayable-specific-gravity" "->displayable-temperature" - "->displayable-color"]} + "->displayable-time" + "->displayable-volume" + "->displayable-weight"]} ([source-value source-units target-units] - (->displayable-volume source-value source-units target-units default-display-options)) + (->displayable-color source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] (-> source-value - (volume/convert source-units target-units) - (volume/display target-units opts)))) + (color/convert source-units target-units) + (color/display target-units opts)))) -;; TODO: Pluralize strings -(defn ->displayable-weight - "Convert a weight then render it to a displayable value." - {:added "1.3.0" +(defn ->displayable-pressure + "Convert a pressure then render it to a displayable value." + {:added "2.1" :no-doc true - :see-also ["->displayable-volume" - "->displayable-time" + :see-also ["->displayable-color" + "->displayable-specific-gravity" "->displayable-temperature" - "->displayable-color"]} + "->displayable-time" + "->displayable-volume" + "->displayable-weight"]} ([source-value source-units target-units] - (->displayable-weight source-value source-units target-units default-display-options)) + (->displayable-pressure source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] (-> source-value - (weight/convert source-units target-units) - (weight/display target-units opts)))) + (pressure/convert source-units target-units) + (pressure/display target-units opts)))) -;; TODO: Pluralize strings -(defn ->displayable-time - "Convert a time then render it to a displayable value." - {:added "1.3.0" +(defn ->displayable-specific-gravity + "Convert a specific gravity then render it to a displayable value." + {:added "2.1" :no-doc true - :see-also ["->displayable-volume" - "->displayable-weight" + :see-also ["->displayable-color" + "->displayable-pressure" "->displayable-temperature" - "->displayable-color"]} + "->displayable-time" + "->displayable-volume" + "->displayable-weight"]} ([source-value source-units target-units] - (->displayable-time source-value source-units target-units default-display-options)) + (->displayable-specific-gravity source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] (-> source-value - (time/convert source-units target-units) - (time/display target-units opts)))) + (specific-gravity/convert source-units target-units) + (specific-gravity/display target-units opts)))) -;; TODO: Pluralize strings (defn ->displayable-temperature "Convert a temperature then render it to a displayable value." - {:added "1.3.0" + {:added "2.1" :no-doc true - :see-also ["->displayable-volume" - "->displayable-weight" + :see-also ["->displayable-color" + "->displayable-pressure" + "->displayable-specific-gravity" "->displayable-time" - "->displayable-color"]} + "->displayable-volume" + "->displayable-weight"]} ([source-value source-units target-units] (->displayable-temperature source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] @@ -109,63 +175,76 @@ (temperature/display target-units opts)))) -;; TODO: Pluralize strings -(defn ->displayable-color - "Convert a color then render it to a displayable value." - {:added "1.3.0" +(defn ->displayable-time + "Convert a time then render it to a displayable value." + {:added "2.1" :no-doc true - :see-also ["->displayable-volume" - "->displayable-weight" - "->displayable-time" - "->displayable-temperature"]} + :see-also ["->displayable-color" + "->displayable-pressure" + "->displayable-specific-gravity" + "->displayable-temperature" + "->displayable-volume" + "->displayable-weight"]} ([source-value source-units target-units] - (->displayable-color source-value source-units target-units default-display-options)) + (->displayable-time source-value source-units target-units default-display-options)) ([source-value source-units target-units opts] (-> source-value - (color/convert source-units target-units) - (color/display target-units opts)))) - - -(def ^:private default-volume-by-system - {options/imperial options/imperial-gallon - options/metric options/litre - options/us-customary options/american-gallon - options/international-system options/litre}) - - -(def ^:private default-weight-by-system - {options/imperial options/pound - options/metric options/kilogram - options/us-customary options/pound - options/international-system options/kilogram}) + (time/convert source-units target-units) + (time/display target-units opts)))) -(def ^:private default-time-by-system - {options/imperial options/minute - options/metric options/minute - options/us-customary options/minute - options/international-system options/minute}) +(defn ->displayable-volume + "Convert a volume then render it to a displayable value." + {:added "2.1" + :no-doc true + :see-also ["->displayable-color" + "->displayable-pressure" + "->displayable-specific-gravity" + "->displayable-temperature" + "->displayable-time" + "->displayable-weight"]} + ([source-value source-units target-units] + (->displayable-volume source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] + (-> source-value + (volume/convert source-units target-units) + (volume/display target-units opts)))) -(def ^:private default-temperature-by-system - {options/imperial options/fahrenheit - options/metric options/celsius - options/us-customary options/fahrenheit - options/international-system options/celsius}) +(defn ->displayable-weight + "Convert a weight then render it to a displayable value." + {:added "2.1" + :no-doc true + :see-also ["->displayable-color" + "->displayable-pressure" + "->displayable-specific-gravity" + "->displayable-temperature" + "->displayable-time" + "->displayable-volume"]} + ([source-value source-units target-units] + (->displayable-weight source-value source-units target-units default-display-options)) + ([source-value source-units target-units opts] + (-> source-value + (weight/convert source-units target-units) + (weight/display target-units opts)))) (defn target-unit-error "A function to accumulate error messages in `error-map` if `target-units` is not a valid unit for `conversion-type`" - {:added "1.3.0" + {:added "2.1" :no-doc true - :see-also ["systems-of-meaure-error" "precision-error" "suffix-error"]} + :see-also ["systems-of-meaure-error" + "precision-error" + "suffix-error"]} [error-map conversion-type target-units] (let [allowed-values (case conversion-type - :color color/measurements - :volume volume/measurements - :weight weight/measurements - :time time/measurements - :temperature temperature/measurements) + :color color/measurements + :pressure pressure/measurements + :specific-gravity specific-gravity/measurements + :temperature temperature/measurements + :time time/measurements + :volume volume/measurements + :weight weight/measurements) error-msg (str "Invalid unit for " (name conversion-type) " conversion : `" @@ -177,10 +256,10 @@ (defn source-unit-error "A function to accumulate error messages in `error-map` if `source-units` is not a valid unit for `conversion-type`. - + Note: This is only used for color conversion at this time. BeerXML prescribes the system of measure for all other units." - {:added "1.3.0" + {:added "2.1" :no-doc true :see-also ["systems-of-meaure-error" "precision-error" @@ -188,11 +267,13 @@ "target-unit-error"]} [error-map conversion-type source-units] (let [allowed-values (case conversion-type - :color color/measurements - :temperature temperature/measurements - :time time/measurements - :volume volume/measurements - :weight weight/measurements) + :color color/measurements + :pressure pressure/measurements + :specific-gravity specific-gravity/measurements + :temperature temperature/measurements + :time time/measurements + :volume volume/measurements + :weight weight/measurements) error-msg (str "Invalid unit for " (name conversion-type) " conversion : `" @@ -203,23 +284,29 @@ (defn systems-of-meaure-error - "A function to accumulate error messages in `error-map` if `system-of-measure` is not valid for `conversion-type`" - {:added "1.3.0" + "A function to accumulate error messages in `error-map` if `system-of-measure` is not valid for `conversion-type`." + {:added "2.1" :no-doc true - :see-also ["target-unit-error" "precision-error" "suffix-error"]} + :see-also ["target-unit-error" + "precision-error" + "suffix-error"]} [error-map conversion-type system-of-measure] - (let [error-msg (format "Invalid system of measure for %s conversion : %s. Allowed values are: %s" - (name conversion-type) - system-of-measure - options/systems-of-measure)] + (let [error-msg (str "Invalid system of measure for " + (name conversion-type) + " conversion : " + system-of-measure + ". Allowed values are:" + options/systems-of-measure)] (assoc error-map :system-of-measure error-msg))) (defn precision-error - "A function to accumulate error messages in `error-map` if `precision` is not an integer" - {:added "1.3.0" + "A function to accumulate error messages in `error-map` if `precision` is not an integer." + {:added "2.1" :no-doc true - :see-also ["target-unit-error" "systems-of-meaure-error" "suffix-error"]} + :see-also ["target-unit-error" + "systems-of-meaure-error" + "suffix-error"]} [error-map conversion-type precision] (let [error-msg (str "Invalid precision for " (name conversion-type) @@ -230,23 +317,144 @@ (defn suffix-error - "A function to accumulate error messages in `error-map` if `suffix` is not a valid choice" - {:added "1.3.0" + "A function to accumulate error messages in `error-map` if `suffix` is not a valid choice." + {:added "2.1" :no-doc true - :see-also ["target-unit-error" "systems-of-meaure-error" "precision-error"]} + :see-also ["target-unit-error" + "systems-of-meaure-error" + "precision-error"]} [error-map conversion-type suffix] - (let [error-msg (format "Invalid suffix type for %s conversion : %s. Allowed values are: %s" - (name conversion-type) - suffix - options/supported-suffixes)] + (let [error-msg (str "Invalid suffix type for " + (name conversion-type) + " conversion : " + suffix + ". Allowed values are: " + options/supported-suffixes)] (assoc error-map :suffix error-msg))) -(defn verify-enrich-displayable-volume-opts - "A function to verify the options map passed to `->displayable-volume` +;; Enricher argument validation functions + +(defn parse-enrich-displayable-color-opts + "A function to parse the options map passed to `->displayable-color` + This requires the user to supply valid values for: `target-units`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-color"]} + [{:keys [target-units source-units precision suffix] + :as opts}] + (let [valid-target? (contains? color/srm->measurement target-units) + valid-source? (contains? color/measurement->srm source-units) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :color target-units) + (not valid-source?) (source-unit-error :color source-units) + (not valid-precision?) (precision-error :color precision) + (not valid-suffix?) (suffix-error :color suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable color enrichment options: " errors))))) + + +(defn parse-enrich-displayable-pressure-opts + "A function to parse the options map passed to `->displayable-pressure` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-pressure"]} + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? pressure/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :pressure target-units) + (not valid-system?) (systems-of-meaure-error :pressure system-of-measure) + (not valid-precision?) (precision-error :pressure precision) + (not valid-suffix?) (suffix-error :pressure suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid options for `->displayable-pressure`: " errors))))) + + +(defn parse-enrich-displayable-specific-gravity-opts + "A function to parse the options map passed to `->displayable-specific-gravity` This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, an Exception is thrown with information on the invalid options." - {:added "1.3.0" + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-specific-gravity"]} + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? specific-gravity/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :specific-gravity target-units) + (not valid-system?) (systems-of-meaure-error :specific-gravity system-of-measure) + (not valid-precision?) (precision-error :specific-gravity precision) + (not valid-suffix?) (suffix-error :specific-gravity suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid options for `->displayable-specific-gravity`: " errors))))) + + +(defn parse-enrich-displayable-temperature-opts + "A function to parse the options map passed to `->displayable-temperature` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-temperature"]} + [{:keys [precision suffix system-of-measure target-units] + :as opts}] + (let [valid-target? (contains? temperature/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :temperature target-units) + (not valid-system?) (systems-of-meaure-error :temperature system-of-measure) + (not valid-precision?) (precision-error :temperature precision) + (not valid-suffix?) (suffix-error :temperature suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable temperature enrichment options: " errors))))) + + +(defn parse-enrich-displayable-time-opts + "A function to parse the options map passed to `->displayable-time` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-time"]} + [{:keys [precision suffix system-of-measure target-units] + :as opts}] + (let [valid-target? (contains? time/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :time target-units) + (not valid-system?) (systems-of-meaure-error :time system-of-measure) + (not valid-precision?) (precision-error :time precision) + (not valid-suffix?) (suffix-error :time suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable time enrichment options: " errors))))) + + +(defn parse-enrich-displayable-volume-opts + "A function to parse the options map passed to `->displayable-volume` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" :no-doc true :see-also ["enrich-displayable-volume"]} [{:keys [target-units system-of-measure precision suffix] @@ -265,12 +473,35 @@ (throw (ex-info "Invalid displayable volume enrichment options: " errors))))) +(defn parse-enrich-displayable-weight-opts + "A function to parse the options map passed to `->displayable-weight` + This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. + If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." + {:added "2.1" + :no-doc true + :see-also ["enrich-displayable-weight"]} + [{:keys [target-units system-of-measure precision suffix] + :as opts}] + (let [valid-target? (contains? weight/measurements target-units) + valid-system? (contains? options/systems-of-measure system-of-measure) + valid-precision? (int? precision) + valid-suffix? (contains? options/supported-suffixes suffix) + errors (cond-> {} + (not valid-target?) (target-unit-error :weight target-units) + (not valid-system?) (systems-of-meaure-error :weight system-of-measure) + (not valid-precision?) (precision-error :weight precision) + (not valid-suffix?) (suffix-error :weight suffix))] + (if (empty? errors) + opts + (throw (ex-info "Invalid displayable weight enrichment options: " errors))))) + + #_{:clj-kondo/ignore [:shadowed-var]} -(defn enrich-displayable-volume - "A function to enrich a map with a human-readable version of a volume at `value-key`. - If invalid options are passed, the function throws an Exception with information on the invalid options. +(defn enrich-displayable-color + "A function to enrich a map with a human-readable version of a color at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: @@ -279,62 +510,83 @@ `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` - If these options are valid, the function will convert the volume to the target units and return the original value with the new value added at `display-key`" - {:added "1.3.0" + If these options are valid, the function will convert the color to the target system and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true :see-also ["enrich-displayable-color" - "enrich-displayable-weight" + "enrich-displayable-specific-gravity" "enrich-displayable-temperature" - "enrich-displayable-time"]} + "enrich-displayable-time" + "enrich-displayable-volume" + "enrich-displayable-weight"]} [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key source-units] :or {system-of-measure options/us-customary suffix options/short precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-volume (get default-volume-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-volume) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (verify-enrich-displayable-volume-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-volume source-value :liter target-units opts))) + (let [system-of-measure-color (get default-color-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-color) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-color-opts + {:target-units target-units + :source-units source-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-color source-value source-units target-units opts))) source-data)) -(defn verify-enrich-displayable-weight-opts - "A function to verify the options map passed to `->displayable-weight` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, an Exception is thrown with information on the invalid options." - {:added "1.3.0" +#_{:clj-kondo/ignore [:shadowed-var]} + + +(defn enrich-displayable-pressure + "A function to enrich a map with a human-readable version of a pressure at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the pressure to the target system and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-weight"]} - [{:keys [target-units system-of-measure precision suffix] - :as opts}] - (let [valid-target? (contains? weight/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :weight target-units) - (not valid-system?) (systems-of-meaure-error :weight system-of-measure) - (not valid-precision?) (precision-error :weight precision) - (not valid-suffix?) (suffix-error :weight suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable weight enrichment options: " errors))))) + :see-also ["enrich-displayable-color" + "enrich-displayable-specific-gravity" + "enrich-displayable-temperature" + "enrich-displayable-time" + "enrich-displayable-volume" + "enrich-displayable-weight"]} + [source-data + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix value-key system-of-measure] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-pressure (get default-pressure-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-pressure) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-pressure-opts + {:target-units target-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-pressure source-value options/kilopascal target-units opts))) + source-data)) #_{:clj-kondo/ignore [:shadowed-var]} -(defn enrich-displayable-weight - "A function to enrich a map with a human-readable version of a weight at `value-key`. - If invalid options are passed, the function throws an Exception with information on the invalid options. +(defn enrich-displayable-specific-gravity + "A function to enrich a map with a human-readable version of a specific gravity at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: @@ -343,53 +595,74 @@ `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` - If these options are valid, the function will convert the weight to the target units and return the original value with the new value added at `display-key`" - {:added "1.3.0" + If these options are valid, the function will convert the specific gravity to the target system and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-volume" - "enrich-displayable-color" + :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" "enrich-displayable-temperature" - "enrich-displayable-time"]} + "enrich-displayable-time" + "enrich-displayable-volume" + "enrich-displayable-weight"]} [source-data - {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary suffix options/short - precision 3}}] + precision options/default-precision}}] (if-let [source-value (get source-data value-key)] - (let [system-of-measure-weight (get default-weight-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-weight) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (verify-enrich-displayable-weight-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-weight source-value :kilogram target-units opts))) + (let [system-of-measure-sg (get default-specific-gravity-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-sg) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-specific-gravity-opts + {:target-units target-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-specific-gravity source-value options/specific-gravity target-units opts))) source-data)) -(defn verify-enrich-displayable-time-opts - "A function to verify the options map passed to `->displayable-time` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, an Exception is thrown with information on the invalid options." - {:added "1.3.0" +#_{:clj-kondo/ignore [:shadowed-var]} + + +(defn enrich-displayable-temperature + "A function to enrich a map with a human-readable version of a temperature at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. + + Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. + However, it will defer to more selective values passed in with the following precedence: + + `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-precision` > `precision` + `:fine-grain-suffix` > `suffix` + + If these options are valid, the function will convert the temperature to the target units and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-time"]} - [{:keys [precision suffix system-of-measure target-units] - :as opts}] - (let [valid-target? (contains? time/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :time target-units) - (not valid-system?) (systems-of-meaure-error :time system-of-measure) - (not valid-precision?) (precision-error :time precision) - (not valid-suffix?) (suffix-error :time suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable time enrichment options: " errors))))) + :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" + "enrich-displayable-specific-gravity" + "enrich-displayable-time" + "enrich-displayable-volume" + "enrich-displayable-weight"]} + [source-data + {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] + (if-let [source-value (get source-data value-key)] + (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-temperature) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-temperature-opts + {:target-units target-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-temperature source-value options/celsius target-units opts))) + source-data)) #_{:clj-kondo/ignore [:shadowed-var]} @@ -397,7 +670,7 @@ (defn enrich-displayable-time "A function to enrich a map with a human-readable version of a time at `value-key`. - If invalid options are passed, the function throws an Exception with information on the invalid options. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: @@ -407,12 +680,14 @@ `:fine-grain-suffix` > `suffix` If these options are valid, the function will convert the time to the target units and return the original value with the new value added at `display-key`" - {:added "1.3.0" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-volume" - "enrich-displayable-weight" + :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" + "enrich-displayable-specific-gravity" "enrich-displayable-temperature" - "enrich-displayable-color"]} + "enrich-displayable-volume" + "enrich-displayable-weight"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary @@ -423,7 +698,7 @@ target-units (or fine-grain-target-units system-of-measure-time) precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) - opts (verify-enrich-displayable-time-opts + opts (parse-enrich-displayable-time-opts {:target-units target-units options/system-of-measure system-of-measure options/precision precision @@ -432,35 +707,12 @@ source-data)) -(defn verify-enrich-displayable-temperature-opts - "A function to verify the options map passed to `->displayable-temperature` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, an Exception is thrown with information on the invalid options." - {:added "1.3.0" - :no-doc true - :see-also ["enrich-displayable-temperature"]} - [{:keys [precision suffix system-of-measure target-units] - :as opts}] - (let [valid-target? (contains? temperature/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :temperature target-units) - (not valid-system?) (systems-of-meaure-error :temperature system-of-measure) - (not valid-precision?) (precision-error :temperature precision) - (not valid-suffix?) (suffix-error :temperature suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable temperature enrichment options: " errors))))) - - #_{:clj-kondo/ignore [:shadowed-var]} -(defn enrich-displayable-temperature - "A function to enrich a map with a human-readable version of a temperature at `value-key`. - If invalid options are passed, the function throws an Exception with information on the invalid options. +(defn enrich-displayable-volume + "A function to enrich a map with a human-readable version of a volume at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: @@ -469,87 +721,72 @@ `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` - If these options are valid, the function will convert the temperature to the target units and return the original value with the new value added at `display-key`" - {:added "1.3.0" + If these options are valid, the function will convert the volume to the target units and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-volume" - "enrich-displayable-weight" - "enrich-displayable-color" - "enrich-displayable-time"]} + :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" + "enrich-displayable-specific-gravity" + "enrich-displayable-temperature" + "enrich-displayable-time" + "enrich-displayable-weight"]} [source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] :or {system-of-measure options/us-customary suffix options/short precision options/default-precision}}] + (if-let [source-value (get source-data value-key)] - (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-temperature) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (verify-enrich-displayable-temperature-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-temperature source-value :celsius target-units opts))) + (let [system-of-measure-volume (get default-volume-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-volume) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-volume-opts + {:target-units target-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-volume source-value options/liter target-units opts))) source-data)) -(defn verify-enrich-displayable-color-opts - "A function to verify the options map passed to `->displayable-color` - This requires the user to supply valid values for: `target-units`, `precision`, and `suffix`. - If any of these are invalid, an Exception is thrown with information on the invalid options." - {:added "1.3.0" - :no-doc true - :see-also ["enrich-displayable-color"]} - [{:keys [target-units source-units precision suffix] - :as opts}] - (let [valid-target? (contains? color/srm->measurement target-units) - valid-source? (contains? color/measurement->srm source-units) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :color target-units) - (not valid-source?) (source-unit-error :color source-units) - (not valid-precision?) (precision-error :color precision) - (not valid-suffix?) (suffix-error :color suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable color enrichment options: " errors))))) - - #_{:clj-kondo/ignore [:shadowed-var]} -(defn enrich-displayable-color - "A function to enrich a map with a human-readable version of a color at `value-key`. - If invalid options are passed, the function throws an Exception with information on the invalid options. +(defn enrich-displayable-weight + "A function to enrich a map with a human-readable version of a weight at `value-key`. + If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: + `impl/fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` - If these options are valid, the function will convert the color to the target system and return the original value with the new value added at `display-key`" - {:added "1.3.0" + If these options are valid, the function will convert the weight to the target units and return the original value with the new value added at `display-key`" + {:added "2.1" :no-doc true - :see-also ["enrich-displayable-volume" - "enrich-displayable-weight" + :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" + "enrich-displayable-specific-gravity" "enrich-displayable-temperature" - "enrich-displayable-time"]} + "enrich-displayable-time" + "enrich-displayable-volume"]} [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix value-key source-units] - :or {suffix options/short - precision options/default-precision}}] + {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] + :or {system-of-measure options/us-customary + suffix options/short + precision options/default-precision}}] (if-let [source-value (get source-data value-key)] - (let [target-units fine-grain-target-units - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (verify-enrich-displayable-color-opts - {:target-units target-units - :source-units source-units - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-color source-value source-units target-units opts))) + (let [system-of-measure-weight (get default-weight-by-system system-of-measure) + target-units (or fine-grain-target-units system-of-measure-weight) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-weight-opts + {:target-units target-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix})] + (assoc source-data display-key (->displayable-weight source-value options/kilogram target-units opts))) source-data)) diff --git a/src/brewtility/enrich/recipes.cljc b/src/brewtility/enrich/recipes.cljc new file mode 100644 index 0000000..cfd921c --- /dev/null +++ b/src/brewtility/enrich/recipes.cljc @@ -0,0 +1,13 @@ +(ns brewtility.enrich.recipes + "Enricher-pattern functions for [recipes](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/recipes.cljc) maps" + {:added "2.1" + :see-also ["brewtility.enrich.equipment" + "brewtility.enrich.fermentables" + "brewtility.enrich.hops" + "brewtility.enrich.mash" + "brewtility.enrich.miscs" + "brewtility.enrich.styles" + "brewtility.enrich.waters" + "brewtility.enrich.yeast"]} + (:require [brewtility.enrich.impl :as impl])) + diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index c5cfabf..ccda945 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -189,145 +189,145 @@ "The valid values are included in the error message")))) -(deftest verify-enrich-displayable-volume-opts-test +(deftest parse-enrich-displayable-volume-opts-test (let [valid-opts {:target-units :teaspoon :system-of-measure :metric :precision 2 :suffix :full} error-regex #"Invalid displayable volume enrichment options"] - (testing "Ensure verify-enrich-displayable-volume-opts returns valid opts" - (is (= valid-opts (sut/verify-enrich-displayable-volume-opts valid-opts)) + (testing "Ensure parse-enrich-displayable-volume-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-volume-opts valid-opts)) "Valid opts are returned unchanged")) - (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/teaspoon options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/verify-enrich-displayable-volume-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-volume-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake)))))))) -(deftest verify-enrich-displayable-weight-opts-test +(deftest parse-enrich-displayable-weight-opts-test (let [valid-opts {:target-units :pound :system-of-measure :metric :precision 2 :suffix :full} error-regex #"Invalid displayable weight enrichment options"] - (testing "Ensure verify-enrich-displayable-weight-opts returns valid opts" - (is (= valid-opts (sut/verify-enrich-displayable-weight-opts valid-opts)) + (testing "Ensure parse-enrich-displayable-weight-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-weight-opts valid-opts)) "Valid opts are returned unchanged")) - (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/pound options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/verify-enrich-displayable-weight-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-weight-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake)))))))) -(deftest verify-enrich-displayable-time-opts-test +(deftest parse-enrich-displayable-time-opts-test (let [valid-opts {:target-units :minute :system-of-measure :metric :precision 2 :suffix :full} error-regex #"Invalid displayable time enrichment options"] - (testing "Ensure verify-enrich-displayable-time-opts returns valid opts" - (is (= valid-opts (sut/verify-enrich-displayable-time-opts valid-opts)) + (testing "Ensure parse-enrich-displayable-time-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-time-opts valid-opts)) "Valid opts are returned unchanged")) - (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/minute options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/verify-enrich-displayable-time-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-time-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-time-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :suffix :fake)))))))) -(deftest verify-enrich-displayable-temperature-opts-test +(deftest parse-enrich-displayable-temperature-opts-test (let [valid-opts {:target-units :c :system-of-measure :metric :precision 2 :suffix :full} error-regex #"Invalid displayable temperature enrichment options"] - (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts" - (is (= valid-opts (sut/verify-enrich-displayable-temperature-opts valid-opts)) + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-temperature-opts valid-opts)) "Valid opts are returned unchanged")) - (testing "Ensure verify-enrich-displayable-temperature-opts returns valid opts with static keys" + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/c options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/verify-enrich-displayable-temperature-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-temperature-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/verify-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake)))))))) From 70564f4a2f9f54e0b74e8c9a1684d1a6838acecd Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 26 Jun 2023 18:45:01 +0000 Subject: [PATCH 30/44] Test all enricher implementation functions --- .clj-kondo/rewrite-clj/rewrite-clj/config.edn | 5 + .github/workflows/format.yml | 21 + CHANGELOG.md | 2 +- Makefile | 3 + doc/patterns/enricher-pattern.md | 2 +- package-lock.json | 14 - pom.xml | 12 + project.clj | 8 +- src/brewtility/calculations.cljc | 92 +- src/brewtility/enrich/impl.cljc | 22 +- src/brewtility/enrich/styles.cljc | 231 +++++ src/brewtility/precision.cljc | 23 +- src/brewtility/wrapping.cljc | 136 ++- test/brewtility/calculations_test.cljc | 31 +- test/brewtility/enrich/equipment_test.cljc | 18 +- test/brewtility/enrich/fermentables_test.cljc | 2 +- test/brewtility/enrich/hops_test.cljc | 2 +- test/brewtility/enrich/impl_test.cljc | 854 ++++++++++++++---- test/brewtility/enrich/mash_test.cljc | 2 +- test/brewtility/enrich/miscs_test.cljc | 2 +- test/brewtility/enrich/waters_test.cljc | 2 +- test/brewtility/enrich/yeasts_test.cljc | 2 +- test/brewtility/precision_test.cljc | 9 +- .../brewtility/predicates/equipment_test.cljc | 2 +- .../predicates/fermentables_test.cljc | 2 +- test/brewtility/predicates/hops_test.cljc | 2 +- test/brewtility/predicates/impl_test.cljc | 2 +- test/brewtility/predicates/mash_test.cljc | 2 +- test/brewtility/predicates/miscs_test.cljc | 2 +- test/brewtility/predicates/recipes_test.cljc | 2 +- test/brewtility/predicates/styles_test.cljc | 2 +- test/brewtility/predicates/waters_test.cljc | 2 +- test/brewtility/predicates/yeasts_test.cljc | 2 +- 33 files changed, 1209 insertions(+), 306 deletions(-) create mode 100644 .clj-kondo/rewrite-clj/rewrite-clj/config.edn diff --git a/.clj-kondo/rewrite-clj/rewrite-clj/config.edn b/.clj-kondo/rewrite-clj/rewrite-clj/config.edn new file mode 100644 index 0000000..19ecae9 --- /dev/null +++ b/.clj-kondo/rewrite-clj/rewrite-clj/config.edn @@ -0,0 +1,5 @@ +{:lint-as + {rewrite-clj.zip/subedit-> clojure.core/-> + rewrite-clj.zip/subedit->> clojure.core/->> + rewrite-clj.zip/edit-> clojure.core/-> + rewrite-clj.zip/edit->> clojure.core/->>}} diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index b36b14b..9d165ee 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,6 +13,19 @@ jobs: ref: ${{ github.head_ref }} token: ${{ secrets.WALL_BREW_BOT_PAT }} + - name: Cache maven dependencies + uses: actions/cache@v3 + env: + cache-name: cache-maven + with: + path: ~/.m2 + key: ${{ runner.os }}-clj-${{ hashFiles('**/project.clj') }} + restore-keys: | + ${{ runner.os }}-clj + + - name: Install Clojure dependencies + run: lein deps + - name: Install cljstyle uses: just-sultanov/setup-cljstyle@v1 with: @@ -22,6 +35,14 @@ jobs: run: | cljstyle fix --report --report-timing --verbose + - name: Sort Namespaces + run: | + lein ns-sort + + - name: Render Changelog + run: | + lein sealog render + - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5.0.0 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ac9e7..f1ba80a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * Changed * Internal functions that convert between unit systems now use `brewtility.units` * Removed - * `brewility.color` has been removed in favor of `brewtility.units.color` + * `brewtility.color` has been removed in favor of `brewtility.units.color` * `brewtility.units/convert-weight` has been removed in favor of `brewtility.units/convert` and `brewtility.units.weight/convert` * `brewtility.units/convert-volume` has been removed in favor of `brewtility.units/convert` and `brewtility.units.volume/convert` * `brewtility.units/convert-temperature` has been removed in favor of `brewtility.units/convert` and `brewtility.units.temperature/convert` diff --git a/Makefile b/Makefile index 4b1a5d7..a91d4fd 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ version/major: @ lein change version leiningen.release/bump-version release @ lein sealog bump major @ lein pom + @ npm version major --no-git-tag-version version/minor: $(info Updating minor version and adding CHANGELOG entry...) @@ -22,6 +23,7 @@ version/minor: @ lein change version leiningen.release/bump-version release @ lein sealog bump minor @ lein pom + @ npm version minor --no-git-tag-version version/patch: $(info Updating patch version and adding CHANGELOG entry...) @@ -30,6 +32,7 @@ version/patch: @ lein change version leiningen.release/bump-version release @ lein sealog bump patch @ lein pom + @ npm version patch --no-git-tag-version changelog/render: $(info Rendering CHANGELOG...) diff --git a/doc/patterns/enricher-pattern.md b/doc/patterns/enricher-pattern.md index fa7478f..463b526 100644 --- a/doc/patterns/enricher-pattern.md +++ b/doc/patterns/enricher-pattern.md @@ -35,7 +35,7 @@ While the unit conversion is simple, it can often lead to front-end code like th ``` Helper functions may be extracted, but the above code would certainly benefit from the `:display-boil-size` and `:display-tun-weight` fields which may optionally exist on the `equipment` record. -As a utility library for beer data, brewtility comes with the functionality needed to compute these display fields; however, keeping them as loose datums isn't fully desireable either. +As a utility library for beer data, brewtility comes with the functionality needed to compute these display fields; however, keeping them as loose datums isn't fully desirable either. In the contexts we want display data available for an equipment record, it's much easier to provide that data with the equipment record. To that end, this library implements an enrichment pattern. diff --git a/package-lock.json b/package-lock.json index 28aa715..85e61dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -605,20 +605,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", diff --git a/pom.xml b/pom.xml index e64abb7..1e9929a 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,12 @@ 1.11.132 provided + + cider + cider-nrepl + 0.31.0 + test + com.wallbrew common-beer-data @@ -99,6 +105,12 @@ 0.1.11 test + + nrepl + nrepl + 1.0.0 + test + diff --git a/project.clj b/project.clj index 952594d..0023b39 100644 --- a/project.clj +++ b/project.clj @@ -25,10 +25,12 @@ :deploy-branches ["master"] :profiles {:uberjar {:aot :all} - :dev {:dependencies [[com.wallbrew/common-beer-data "1.3.0"] + :dev {:dependencies [[cider/cider-nrepl "0.31.0"] + [com.wallbrew/common-beer-data "1.3.0"] [com.wallbrew/common-beer-format "2.2.1"] - [doo "0.1.11"]] - :plugins [[lein-doo "0.1.11"]]}} + [doo/doo "0.1.11"] + [nrepl/nrepl "1.0.0"]] + :plugins [[lein-doo/lein-doo "0.1.11"]]}} :aliases {"test-build" ["do" "clean" ["cljsbuild" "once" "test"] ["doo" "once"] ["test"]]} diff --git a/src/brewtility/calculations.cljc b/src/brewtility/calculations.cljc index 7b63cf8..1241ffa 100644 --- a/src/brewtility/calculations.cljc +++ b/src/brewtility/calculations.cljc @@ -7,18 +7,26 @@ [brewtility.units.options :as options] [brewtility.units.time :as time] [brewtility.units.volume :as volume] - [brewtility.units.weight :as weight])) + [brewtility.units.weight :as weight]) + (:refer-clojure :exclude [time])) (defn normalize-fermentable - "Given a `common-beer-format` conforming `fermentable`, normalize it for color computation." + "Given a `common-beer-format` conforming `fermentable`, normalize it for color computation. + If insufficient data is provided, this function will throw an exception." {:added "1.0"} - [fermentable] - (let [is-not-grain? (not (fermentables/grain? fermentable)) - kg->lbs (fn [w] (weight/convert w options/kilogram options/pound))] ; MCU is calculated against pounds - (cond-> fermentable - true (update :amount kg->lbs) - is-not-grain? (update :color #(color/convert % options/srm options/lovibond))))) ; Grain color is in Lovibond, all other fermentables use SRM + [{:keys [amount color] :as fermentable}] + (if (and (number? amount) + (number? color)) + (let [is-not-grain? (not (fermentables/grain? fermentable)) + ; MCU is calculated against pounds + kg->lbs (fn [w] (weight/convert w options/kilogram options/pound))] + (cond-> fermentable + true (update :amount kg->lbs) + ; Grain color is in Lovibond, all other fermentables use SRM + is-not-grain? (update :color #(color/convert % options/srm options/lovibond)))) + (throw (ex-info "Cannot calculate color with non-numeric values" {:amount amount + :color color})))) (defn calculate-malt-color-units "Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the overall Malt Color Units for a recipe." @@ -85,11 +93,15 @@ {:added "1.0" :see-also ["gravity-points->potential-gravity"]} [potential-gravity weight] - (let [weight-in-pounds (weight/convert weight options/kilogram options/pound)] - (-> potential-gravity - (* 1000) - (- 1000) - (* weight-in-pounds)))) + (if (and (number? potential-gravity) + (number? weight)) + (let [weight-in-pounds (weight/convert weight options/kilogram options/pound)] + (-> potential-gravity + (* 1000) + (- 1000) + (* weight-in-pounds))) + (throw (ex-info "Cannot calculate gravity points with non-numeric values" {:potential-gravity potential-gravity + :weight weight})))) (defn gravity-points->potential-gravity @@ -97,11 +109,15 @@ {:added "1.0" :see-also ["potential-gravity->gravity-points"]} [gravity-points volume] - (let [volume-in-gallons (volume/convert volume options/litre options/american-gallon)] - (-> gravity-points - (/ volume-in-gallons) - (+ 1000) - (/ 1000.0)))) + (if (and (number? gravity-points) + (number? volume)) + (let [volume-in-gallons (volume/convert volume options/litre options/american-gallon)] + (-> gravity-points + (/ volume-in-gallons) + (+ 1000) + (/ 1000.0))) + (throw (ex-info "Cannot calculate potential gravity with non-numeric values" {:gravity-points gravity-points + :volume volume})))) (defn calculate-potential-gravity @@ -117,7 +133,7 @@ (def gravity->abv-multiplier - "The multiplier used to convert gravity to ABV. + "The multiplier used to convert gravity to ABV. This is a constant, and is not configurable." 0.00135) @@ -138,10 +154,10 @@ (calculate-potential-final-gravity fermentables batch-size default-attenuation)) ([fermentables batch-size attenuation] - (let [gravity (calculate-potential-gravity fermentables batch-size) - gravity-points (-> gravity - (* 1000) - (- 1000)) + (let [gravity (calculate-potential-gravity fermentables batch-size) + gravity-points (-> gravity + (* 1000) + (- 1000)) attenuated-points (* gravity-points attenuation)] (-> gravity-points @@ -152,7 +168,8 @@ (defn calculate-potential-abv "Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, estimate the ABV. - The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed." + The primary fermentation yeast's `attenuation` may also be passed, otherwise 75% is assumed. + If insufficient data is provided, this function will throw an exception." {:added "1.0"} ([fermentables batch-size] (calculate-potential-abv fermentables batch-size default-attenuation)) @@ -180,7 +197,7 @@ "Calculate the maximum amount of alpha acid released by `weight` ounce of a hop at `percent` alpha acid." {:added "1.0"} [weight alpha] - (let [weight-in-ounces (weight/convert weight options/kilogram options/ounce) + (let [weight-in-ounces (weight/convert weight options/kilogram options/ounce) aau-normalization-factor 100] (* aau-normalization-factor weight-in-ounces alpha))) @@ -188,16 +205,27 @@ (defn calculate-ibu-per-hop "Given a `common-beer-format` conforming `hop`, `batch-size`, and `potential-gravity`, calculate the amount of IBUs generated." {:added "1.0"} - [hop batch-size potential-gravity] - (let [utilization (calculate-hop-utilization potential-gravity (:time hop)) - alpha-acid-units (calculate-alpha-acid-units (:amount hop) (:alpha hop)) - imperial-volume (volume/convert batch-size options/litre options/american-gallon) - conversion-factor 74.89] - (/ (* alpha-acid-units utilization conversion-factor) imperial-volume))) + [{:keys [time amount alpha] :as _hop} batch-size potential-gravity] + (if (and (number? time) + (number? amount) + (number? alpha) + (number? batch-size) + (number? potential-gravity)) + (let [utilization (calculate-hop-utilization potential-gravity time) + alpha-acid-units (calculate-alpha-acid-units amount alpha) + imperial-volume (volume/convert batch-size options/litre options/american-gallon) + conversion-factor 74.89] + (/ (* alpha-acid-units utilization conversion-factor) imperial-volume)) + (throw (ex-info "Cannot calculate IBUs with non-numeric values" {:amount amount + :time time + :alpha alpha + :batch-size batch-size + :potential-gravity potential-gravity})))) (defn calculate-recipe-ibus - "Given a collection of `common-beer-format` conforming `hops`, `batch-size`, and `potential-gravity` calculate the amount of IBUs generated." + "Given a collection of `common-beer-format` conforming `hops`, `batch-size`, and `potential-gravity` calculate the amount of IBUs generated. + If insufficient data is provided, this function will throw an exception." {:added "1.0"} [hops batch-size potential-gravity] (let [reducing-fn (fn [acc h] (+ acc (calculate-ibu-per-hop h batch-size potential-gravity)))] diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index fd8d921..f75484c 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -245,7 +245,7 @@ :time time/measurements :volume volume/measurements :weight weight/measurements) - error-msg (str "Invalid unit for " + error-msg (str "Invalid target unit for " (name conversion-type) " conversion : `" target-units @@ -274,7 +274,7 @@ :time time/measurements :volume volume/measurements :weight weight/measurements) - error-msg (str "Invalid unit for " + error-msg (str "Invalid source unit for " (name conversion-type) " conversion : `" source-units @@ -378,7 +378,7 @@ (not valid-suffix?) (suffix-error :pressure suffix))] (if (empty? errors) opts - (throw (ex-info "Invalid options for `->displayable-pressure`: " errors))))) + (throw (ex-info "Invalid displayable pressure enrichment options: " errors))))) (defn parse-enrich-displayable-specific-gravity-opts @@ -401,7 +401,7 @@ (not valid-suffix?) (suffix-error :specific-gravity suffix))] (if (empty? errors) opts - (throw (ex-info "Invalid options for `->displayable-specific-gravity`: " errors))))) + (throw (ex-info "Invalid displayable specific gravity enrichment options: " errors))))) (defn parse-enrich-displayable-temperature-opts @@ -506,7 +506,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -549,7 +549,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -591,7 +591,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -633,7 +633,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -675,7 +675,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -717,7 +717,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` @@ -760,7 +760,7 @@ Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. However, it will defer to more selective values passed in with the following precedence: - `impl/fine-grain-target-units` > `system-of-measure` + `:fine-grain-target-units` > `system-of-measure` `:fine-grain-precision` > `precision` `:fine-grain-suffix` > `suffix` diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index 719604d..eb0e3ec 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -11,3 +11,234 @@ "brewtility.enrich.yeast"]} (:require [brewtility.enrich.impl :as impl])) + +(defn enrich-display-og-min + "An enricher pattern function to render a human-readable display minimum original gravity of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-og-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-og-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-og-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-og-min style {})) + ([style {:keys [style-display-og-min-target-units + style-display-og-min-precision + style-display-og-min-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :og-min + impl/display-key :display-og-min + impl/fine-grain-target-units style-display-og-min-target-units + impl/fine-grain-precision style-display-og-min-precision + impl/fine-grain-suffix style-display-og-min-suffix})] + (impl/enrich-displayable-specific-gravity style options)))) + + +(defn enrich-display-og-max + "An enricher pattern function to render a human-readable display maximum original gravity of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-og-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-og-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-og-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-og-max style {})) + ([style {:keys [style-display-og-max-target-units + style-display-og-max-precision + style-display-og-max-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :og-max + impl/display-key :display-og-max + impl/fine-grain-target-units style-display-og-max-target-units + impl/fine-grain-precision style-display-og-max-precision + impl/fine-grain-suffix style-display-og-max-suffix})] + (impl/enrich-displayable-specific-gravity style options)))) + + +(defn enrich-display-fg-min + "An enricher pattern function to render a human-readable display minimum final gravity of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + +- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-fg-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-fg-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-fg-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-fg-min style {})) + ([style {:keys [style-display-fg-min-target-units + style-display-fg-min-precision + style-display-fg-min-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :fg-min + impl/display-key :display-fg-min + impl/fine-grain-target-units style-display-fg-min-target-units + impl/fine-grain-precision style-display-fg-min-precision + impl/fine-grain-suffix style-display-fg-min-suffix})] + (impl/enrich-displayable-specific-gravity style options)))) + + +(defn enrich-display-fg-max + "An enricher pattern function to render a human-readable display maximum final gravity of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + +- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-fg-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-fg-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-fg-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-fg-max style {})) + ([style {:keys [style-display-fg-max-target-units + style-display-fg-max-precision + style-display-fg-max-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :fg-max + impl/display-key :display-fg-max + impl/fine-grain-target-units style-display-fg-max-target-units + impl/fine-grain-precision style-display-fg-max-precision + impl/fine-grain-suffix style-display-fg-max-suffix})] + (impl/enrich-displayable-specific-gravity style options)))) + + +(defn enrich-display-color-min + "An enricher pattern function to render a human-readable display minimum color of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + +- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-color-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-color-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-color-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-color-min style {})) + ([style {:keys [style-display-color-min-target-units + style-display-color-min-precision + style-display-color-min-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :color-min + impl/display-key :display-color-min + impl/fine-grain-target-units style-display-color-min-target-units + impl/fine-grain-precision style-display-color-min-precision + impl/fine-grain-suffix style-display-color-min-suffix})] + (impl/enrich-displayable-color style options)))) + + +(defn enrich-display-color-max + "An enricher pattern function to render a human-readable display maximum color of a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + +- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-color-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-color-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-color-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-display-color-max style {})) + ([style {:keys [style-display-color-max-target-units + style-display-color-max-precision + style-display-color-max-suffix] + :as opts}] + (let [options (merge opts {impl/value-key :color-max + impl/display-key :display-color-max + impl/fine-grain-target-units style-display-color-max-target-units + impl/fine-grain-precision style-display-color-max-precision + impl/fine-grain-suffix style-display-color-max-suffix})] + (impl/enrich-displayable-color style options)))) diff --git a/src/brewtility/precision.cljc b/src/brewtility/precision.cljc index 703a48f..e8dd214 100644 --- a/src/brewtility/precision.cljc +++ b/src/brewtility/precision.cljc @@ -8,20 +8,27 @@ "Determine if `n2` approximates `n1` within `variance` percent." {:added "1.0"} [n1 n2 variance] - (let [upper-bound (* n1 (+ 1.0 variance)) - lower-bound (* n1 (- 1.0 variance))] - (<= lower-bound n2 upper-bound))) + (if (and (number? n1) + (number? n2) + (number? variance)) + (let [upper-bound (* n1 (+ 1.0 variance)) + lower-bound (* n1 (- 1.0 variance))] + (<= lower-bound n2 upper-bound)) + (throw (ex-info "Cannot approximate using non-numeric values" {:n1 n1 + :n2 n2 + :variance variance})))) (defn ->precision "Given a decimal `x` and the number of decimal places, returns that number rounded to `num-decimals` precision." - {:added "1.0"} + {:added "1.0" + :see-also ["->1dp" "->2dp" "->3dp"]} [^double x ^long num-decimals] (double - #?(:clj (.setScale (bigdec x) num-decimals RoundingMode/HALF_UP) - :cljs (let [denominator (Math/pow 10.0 (double num-decimals)) - numerator (Math/round (* x denominator))] - (/ numerator denominator))))) + #?(:clj (.setScale (bigdec x) num-decimals RoundingMode/HALF_UP) + :cljs (let [denominator (Math/pow 10.0 (double num-decimals)) + numerator (Math/round (* x denominator))] + (/ numerator denominator))))) (defn ->1dp diff --git a/src/brewtility/wrapping.cljc b/src/brewtility/wrapping.cljc index 6828586..53391ce 100644 --- a/src/brewtility/wrapping.cljc +++ b/src/brewtility/wrapping.cljc @@ -12,7 +12,9 @@ (defn wrap-equipment "Wrap an `equipment` map into an `equipment-wrapper` map." {:added "1.4" - :see-also ["unwrap-equipment"]} + :see-also ["unwrap-equipment" + "::common-beer-format.equipment/equipment" + "::common-beer-format.equipment/equipment-wrapper"]} [equipment] {:equipment equipment}) @@ -20,7 +22,9 @@ (defn unwrap-equipment "Unwrap an `equipment-wrapper` map into an `equipment` map." {:added "1.4" - :see-also ["wrap-equipment"]} + :see-also ["wrap-equipment" + "::common-beer-format.equipment/equipment" + "::common-beer-format.equipment/equipment-wrapper"]} [equipment-wrapper] (:equipment equipment-wrapper)) @@ -30,7 +34,9 @@ (defn wrap-fermentables "Wrap a `fermentables` collection into a `fermentables-wrapper` map." {:added "1.4" - :see-also ["unwrap-fermentables"]} + :see-also ["unwrap-fermentables" + "::common-beer-format.fermentables/fermentables" + "::common-beer-format.fermentables/fermentables-wrapper"]} [fermentables] {:fermentables fermentables}) @@ -38,7 +44,9 @@ (defn unwrap-fermentables "Unwrap a `fermentables-wrapper` map into a `fermentables` collection." {:added "1.4" - :see-also ["wrap-fermentables"]} + :see-also ["wrap-fermentables" + "::common-beer-format.fermentables/fermentables" + "::common-beer-format.fermentables/fermentables-wrapper"]} [fermentables-wrapper] (:fermentables fermentables-wrapper)) @@ -46,7 +54,9 @@ (defn wrap-fermentable "Wrap a `fermentable` map into a `fermentable-wrapper` map." {:added "1.4" - :see-also ["unwrap-fermentable"]} + :see-also ["unwrap-fermentable" + "::common-beer-format.fermentables/fermentable" + "::common-beer-format.fermentables/fermentable-wrapper"]} [fermentable] {:fermentable fermentable}) @@ -54,7 +64,9 @@ (defn unwrap-fermentable "Unwrap a `fermentable-wrapper` map into a `fermentable` map." {:added "1.4" - :see-also ["wrap-fermentable"]} + :see-also ["wrap-fermentable" + "::common-beer-format.fermentables/fermentable" + "::common-beer-format.fermentables/fermentable-wrapper"]} [fermentable-wrapper] (:fermentable fermentable-wrapper)) @@ -64,7 +76,9 @@ (defn wrap-hops "Wrap a `hops` collection into a `hops-wrapper` map." {:added "1.4" - :see-also ["unwrap-hops"]} + :see-also ["unwrap-hops" + "::common-beer-format.hops/hops" + "::common-beer-format.hops/hops-wrapper"]} [hops] {:hops hops}) @@ -72,7 +86,9 @@ (defn unwrap-hops "Unwrap a `hops-wrapper` map into a `hops` collection." {:added "1.4" - :see-also ["wrap-hops"]} + :see-also ["wrap-hops" + "::common-beer-format.hops/hops" + "::common-beer-format.hops/hops-wrapper"]} [hops-wrapper] (:hops hops-wrapper)) @@ -80,7 +96,9 @@ (defn wrap-hop "Wrap a `hop` map into a `hop-wrapper` map." {:added "1.4" - :see-also ["unwrap-hop"]} + :see-also ["unwrap-hop" + "::common-beer-format.hops/hop" + "::common-beer-format.hops/hop-wrapper"]} [hop] {:hop hop}) @@ -88,7 +106,9 @@ (defn unwrap-hop "Unwrap a `hop-wrapper` map into a `hop` map." {:added "1.4" - :see-also ["wrap-hop"]} + :see-also ["wrap-hop" + "::common-beer-format.hops/hop" + "::common-beer-format.hops/hop-wrapper"]} [hop-wrapper] (:hop hop-wrapper)) @@ -98,7 +118,9 @@ (defn wrap-mash-step "Wrap a `mash-step` map into a `mash-step-wrapper` map." {:added "1.4" - :see-also ["unwrap-mash-step"]} + :see-also ["unwrap-mash-step" + "::common-beer-format.mash/mash-step" + "::common-beer-format.mash/mash-step-wrapper"]} [mash-step] {:mash-step mash-step}) @@ -106,7 +128,9 @@ (defn unwrap-mash-step "Unwrap a `mash-step-wrapper` map into a `mash-step` map." {:added "1.4" - :see-also ["wrap-mash-step"]} + :see-also ["wrap-mash-step" + "::common-beer-format.mash/mash-step" + "::common-beer-format.mash/mash-step-wrapper"]} [mash-step-wrapper] (:mash-step mash-step-wrapper)) @@ -114,7 +138,9 @@ (defn wrap-mash "Wrap a `mash` map into a `mash-wrapper` map." {:added "1.4" - :see-also ["unwrap-mash"]} + :see-also ["unwrap-mash" + "::common-beer-format.mash/mash" + "::common-beer-format.mash/mash-wrapper"]} [mash] {:mash mash}) @@ -122,7 +148,9 @@ (defn unwrap-mash "Unwrap a `mash-wrapper` map into a `mash` map." {:added "1.4" - :see-also ["wrap-mash"]} + :see-also ["wrap-mash" + "::common-beer-format.mash/mash" + "::common-beer-format.mash/mash-wrapper"]} [mash-wrapper] (:mash mash-wrapper)) @@ -132,7 +160,9 @@ (defn wrap-misc "Wrap a `misc` map into a `misc-wrapper` map." {:added "1.4" - :see-also ["unwrap-misc"]} + :see-also ["unwrap-misc" + "::common-beer-format.miscs/misc" + "::common-beer-format.miscs/misc-wrapper"]} [misc] {:misc misc}) @@ -140,7 +170,9 @@ (defn unwrap-misc "Unwrap a `misc-wrapper` map into a `misc` map." {:added "1.4" - :see-also ["wrap-misc"]} + :see-also ["wrap-misc" + "::common-beer-format.miscs/misc" + "::common-beer-format.miscs/misc-wrapper"]} [misc-wrapper] (:misc misc-wrapper)) @@ -148,7 +180,9 @@ (defn wrap-miscs "Wrap a `miscs` collection into a `miscs-wrapper` map." {:added "1.4" - :see-also ["unwrap-miscs"]} + :see-also ["unwrap-miscs" + "::common-beer-format.miscs/miscs" + "::common-beer-format.miscs/miscs-wrapper"]} [miscs] {:miscs miscs}) @@ -156,7 +190,9 @@ (defn unwrap-miscs "Unwrap a `miscs-wrapper` map into a `miscs` collection." {:added "1.4" - :see-also ["wrap-miscs"]} + :see-also ["wrap-miscs" + "::common-beer-format.miscs/miscs" + "::common-beer-format.miscs/miscs-wrapper"]} [miscs-wrapper] (:miscs miscs-wrapper)) @@ -166,7 +202,9 @@ (defn wrap-recipe "Wrap a `recipe` map into a `recipe-wrapper` map." {:added "1.4" - :see-also ["unwrap-recipe"]} + :see-also ["unwrap-recipe" + "::common-beer-format.recipes/recipe" + "::common-beer-format.recipes/recipe-wrapper"]} [recipe] {:recipe recipe}) @@ -174,7 +212,9 @@ (defn unwrap-recipe "Unwrap a `recipe-wrapper` map into a `recipe` map." {:added "1.4" - :see-also ["wrap-recipe"]} + :see-also ["wrap-recipe" + "::common-beer-format.recipes/recipe" + "::common-beer-format.recipes/recipe-wrapper"]} [recipe-wrapper] (:recipe recipe-wrapper)) @@ -182,7 +222,9 @@ (defn wrap-recipes "Wrap a `recipes` collection into a `recipes-wrapper` map." {:added "1.4" - :see-also ["unwrap-recipes"]} + :see-also ["unwrap-recipes" + "::common-beer-format.recipes/recipes" + "::common-beer-format.recipes/recipes-wrapper"]} [recipes] {:recipes recipes}) @@ -190,7 +232,9 @@ (defn unwrap-recipes "Unwrap a `recipes-wrapper` map into a `recipes` collection." {:added "1.4" - :see-also ["wrap-recipes"]} + :see-also ["wrap-recipes" + "::common-beer-format.recipes/recipes" + "::common-beer-format.recipes/recipes-wrapper"]} [recipes-wrapper] (:recipes recipes-wrapper)) @@ -200,7 +244,9 @@ (defn wrap-style "Wrap a `style` map into a `style-wrapper` map." {:added "1.4" - :see-also ["unwrap-style"]} + :see-also ["unwrap-style" + "::common-beer-format.styles/style" + "::common-beer-format.styles/style-wrapper"]} [style] {:style style}) @@ -208,7 +254,9 @@ (defn unwrap-style "Unwrap a `style-wrapper` map into a `style` map." {:added "1.4" - :see-also ["wrap-style"]} + :see-also ["wrap-style" + "::common-beer-format.styles/style" + "::common-beer-format.styles/style-wrapper"]} [style-wrapper] (:style style-wrapper)) @@ -216,7 +264,9 @@ (defn wrap-styles "Wrap a `styles` collection into a `styles-wrapper` map." {:added "1.4" - :see-also ["unwrap-styles"]} + :see-also ["unwrap-styles" + "::common-beer-format.styles/styles" + "::common-beer-format.styles/styles-wrapper"]} [styles] {:styles styles}) @@ -224,7 +274,9 @@ (defn unwrap-styles "Unwrap a `styles-wrapper` map into a `styles` collection." {:added "1.4" - :see-also ["wrap-styles"]} + :see-also ["wrap-styles" + "::common-beer-format.styles/styles" + "::common-beer-format.styles/styles-wrapper"]} [styles-wrapper] (:styles styles-wrapper)) @@ -234,7 +286,9 @@ (defn wrap-water "Wrap a `water` map into a `water-wrapper` map." {:added "1.4" - :see-also ["unwrap-water"]} + :see-also ["unwrap-water" + "::common-beer-format.waters/water" + "::common-beer-format.waters/water-wrapper"]} [water] {:water water}) @@ -242,7 +296,9 @@ (defn unwrap-water "Unwrap a `water-wrapper` map into a `water` map." {:added "1.4" - :see-also ["wrap-water"]} + :see-also ["wrap-water" + "::common-beer-format.waters/water" + "::common-beer-format.waters/water-wrapper"]} [water-wrapper] (:water water-wrapper)) @@ -250,7 +306,9 @@ (defn wrap-waters "Wrap a `waters` collection into a `waters-wrapper` map." {:added "1.4" - :see-also ["unwrap-waters"]} + :see-also ["unwrap-waters" + "::common-beer-format.waters/waters" + "::common-beer-format.waters/waters-wrapper"]} [waters] {:waters waters}) @@ -258,7 +316,9 @@ (defn unwrap-waters "Unwrap a `waters-wrapper` map into a `waters` collection." {:added "1.4" - :see-also ["wrap-waters"]} + :see-also ["wrap-waters" + "::common-beer-format.waters/waters" + "::common-beer-format.waters/waters-wrapper"]} [waters-wrapper] (:waters waters-wrapper)) @@ -268,7 +328,9 @@ (defn wrap-yeast "Wrap a `yeast` map into a `yeast-wrapper` map." {:added "1.4" - :see-also ["unwrap-yeast"]} + :see-also ["unwrap-yeast" + "::common-beer-format.yeasts/yeast" + "::common-beer-format.yeasts/yeast-wrapper"]} [yeast] {:yeast yeast}) @@ -276,7 +338,9 @@ (defn unwrap-yeast "Unwrap a `yeast-wrapper` map into a `yeast` map." {:added "1.4" - :see-also ["wrap-yeast"]} + :see-also ["wrap-yeast" + "::common-beer-format.yeasts/yeast" + "::common-beer-format.yeasts/yeast-wrapper"]} [yeast-wrapper] (:yeast yeast-wrapper)) @@ -284,7 +348,9 @@ (defn wrap-yeasts "Wrap a `yeasts` collection into a `yeasts-wrapper` map." {:added "1.4" - :see-also ["unwrap-yeasts"]} + :see-also ["unwrap-yeasts" + "::common-beer-format.yeasts/yeasts" + "::common-beer-format.yeasts/yeasts-wrapper"]} [yeasts] {:yeasts yeasts}) @@ -292,6 +358,8 @@ (defn unwrap-yeasts "Unwrap a `yeasts-wrapper` map into a `yeasts` collection." {:added "1.4" - :see-also ["wrap-yeasts"]} + :see-also ["wrap-yeasts" + "::common-beer-format.yeasts/yeasts" + "::common-beer-format.yeasts/yeasts-wrapper"]} [yeasts-wrapper] (:yeasts yeasts-wrapper)) diff --git a/test/brewtility/calculations_test.cljc b/test/brewtility/calculations_test.cljc index 7b3a7a6..afd5b4a 100644 --- a/test/brewtility/calculations_test.cljc +++ b/test/brewtility/calculations_test.cljc @@ -19,11 +19,15 @@ (is (= 22.046 (bp/->3dp (:amount normalized-grain)))) (is (= (dissoc normalized-adjunct :amount :color) (dissoc (:grits adjuncts/adjuncts) :amount :color))) (is (= 11.023 (bp/->3dp (:amount normalized-adjunct)))) - (is (= 1.299 (bp/->3dp (:color normalized-adjunct))))))) + (is (= 1.299 (bp/->3dp (:color normalized-adjunct)))))) + (testing "An exception is thrown when data is missing" + (let [grain (dissoc (:rye-malt grains/grains) :amount)] + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate color with non-numeric values" (sut/normalize-fermentable grain)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate color with non-numeric values" (sut/normalize-fermentable grain))))))) (deftest calculate-malt-color-units-test - (testing "Colors can be correctly computer for recipes" + (testing "Colors can be correctly calculated for recipes" (let [grain-1 (assoc (:rye-malt grains/grains) :amount 7) grain-2 (assoc (:pale-malt-2-row-us grains/grains) :amount 3) adjunct-1 (assoc (:rice-hulls adjuncts/adjuncts) :amount 2) @@ -38,15 +42,20 @@ (deftest gravity-conversion-test - (testing "Potential gravity and gravity points can be computed correctly" + (testing "Potential gravity and gravity points can be calculated correctly" (is (= 264.555 (bp/->3dp (sut/potential-gravity->gravity-points 1.04 3)))) (is (= 0.0 (bp/->3dp (sut/potential-gravity->gravity-points 1.0 5143)))) (is (= 1.043 (bp/->3dp (sut/gravity-points->potential-gravity 40 3.5)))) - (is (= 1.0 (bp/->3dp (sut/gravity-points->potential-gravity 0 3.5)))))) + (is (= 1.0 (bp/->3dp (sut/gravity-points->potential-gravity 0 3.5))))) + (testing "An exception is thrown when data is missing" + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate gravity points with non-numeric values" (sut/potential-gravity->gravity-points nil 3)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate gravity points with non-numeric values" (sut/potential-gravity->gravity-points nil 3)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate potential gravity with non-numeric values" (sut/gravity-points->potential-gravity 40 nil)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate potential gravity with non-numeric values" (sut/gravity-points->potential-gravity 40 nil)))))) (deftest calculate-potential-gravity-test - (testing "Gravity/ABV can be correctly computer for recipes" + (testing "Gravity/ABV can be correctly calculated for recipes" (let [grain-1 (assoc (:rye-malt grains/grains) :amount 7) grain-2 (assoc (:pale-malt-2-row-us grains/grains) :amount 3) adjunct-1 (assoc (:rice-hulls adjuncts/adjuncts) :amount 2) @@ -79,7 +88,7 @@ (deftest calculate-alpha-acid-units-test - (testing "The amount of alpha acids release by a known quantity of hops can be computed" + (testing "The amount of alpha acids release by a known quantity of hops can be calculated" (is (= 0.0 (bp/->3dp (sut/calculate-alpha-acid-units 0.0 0.5)))) (is (= 0.0 (bp/->3dp (sut/calculate-alpha-acid-units 0.05 0.0)))) (is (= 79.014 (bp/->3dp (sut/calculate-alpha-acid-units 0.14 (:alpha (:el-dorado hops/both)))))) @@ -94,7 +103,15 @@ (is (= 29.448 (bp/->3dp (sut/calculate-ibu-per-hop (assoc hop :amount 0.01 :time 60) 15 1.03)))) (is (= 32.12 (bp/->3dp (sut/calculate-ibu-per-hop (assoc hop :amount 0.01 :time 120) 15 1.03)))) (is (= 16.06 (bp/->3dp (sut/calculate-ibu-per-hop (assoc hop :amount 0.01 :time 120) 30 1.03)))) - (is (= 24.529 (bp/->3dp (sut/calculate-ibu-per-hop (assoc hop :amount 0.01 :time 120) 15 1.06))))))) + (is (= 24.529 (bp/->3dp (sut/calculate-ibu-per-hop (assoc hop :amount 0.01 :time 120) 15 1.06)))))) + (testing "An exception is thrown when data required for the calculation is missing" + (let [hop (:el-dorado hops/both)] + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop {} 15 1.03)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop hop nil 1.03)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop hop 15 nil)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop {} 15 1.03)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop hop nil 1.03)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot calculate IBUs with non-numeric values" (sut/calculate-ibu-per-hop hop 15 nil))))))) (deftest calculate-recipe-ibus-test diff --git a/test/brewtility/enrich/equipment_test.cljc b/test/brewtility/enrich/equipment_test.cljc index 86bad64..2579f3f 100644 --- a/test/brewtility/enrich/equipment_test.cljc +++ b/test/brewtility/enrich/equipment_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.equipment :as equipment.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest enrich-calculated-boil-size-tests @@ -66,7 +66,7 @@ :boil-size-precision 1 :boil-size-suffix :full}) :display-boil-size)) - "Broad settings can be overriden with boil-size specific settings") + "Broad settings can be overridden with boil-size specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-boil-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -99,7 +99,7 @@ :batch-size-precision 1 :batch-size-suffix :full}) :display-batch-size)) - "Broad settings can be overriden with batch-size specific settings") + "Broad settings can be overridden with batch-size specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-batch-size equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -132,7 +132,7 @@ :tun-volume-precision 1 :tun-volume-suffix :full}) :display-tun-volume)) - "Broad settings can be overriden with tun-volume specific settings") + "Broad settings can be overridden with tun-volume specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-volume equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -165,7 +165,7 @@ :tun-weight-precision 1 :tun-weight-suffix :full}) :display-tun-weight)) - "Broad settings can be overriden with tun-weight specific settings") + "Broad settings can be overridden with tun-weight specific settings") (is (spoon.spec/test-valid? ::equipment.format/equipment (equipment.enrich/enrich-display-tun-weight equipment.data/sample-equipment)) "Enrichment pattern should produce a valid equipment object"))) @@ -198,7 +198,7 @@ :top-up-water-precision 1 :top-up-water-suffix :full}) :display-top-up-water)) - "Broad settings can be overriden with top-up-water specific settings") + "Broad settings can be overridden with top-up-water specific settings") (is (nil? (-> equipment.data/sample-equipment (dissoc :top-up-water) equipment.enrich/enrich-display-top-up-water @@ -236,7 +236,7 @@ :trub-chiller-loss-precision 1 :trub-chiller-loss-suffix :full}) :display-trub-chiller-loss)) - "Broad settings can be overriden with trub-chiller-loss specific settings") + "Broad settings can be overridden with trub-chiller-loss specific settings") (is (nil? (-> equipment.data/sample-equipment (dissoc :trub-chiller-loss) equipment.enrich/enrich-display-lauter-deadspace @@ -274,7 +274,7 @@ :lauter-deadspace-precision 1 :lauter-deadspace-suffix :full}) :display-lauter-deadspace)) - "Broad settings can be overriden with lauter-deadspace specific settings") + "Broad settings can be overridden with lauter-deadspace specific settings") (is (nil? (-> equipment.data/sample-equipment (dissoc :lauter-deadspace) (equipment.enrich/enrich-display-lauter-deadspace {:lauter-deadspace-target-units :cup @@ -314,7 +314,7 @@ :top-up-kettle-precision 1 :top-up-kettle-suffix :full}) :display-top-up-kettle)) - "Broad settings can be overriden with top-up-kettle specific settings") + "Broad settings can be overridden with top-up-kettle specific settings") (is (nil? (-> equipment.data/sample-equipment (dissoc :top-up-kettle) equipment.enrich/enrich-display-top-up-kettle diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index 7fd183d..a3992dd 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.fermentables :as fermentable.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest enrich-add-after-boil-test diff --git a/test/brewtility/enrich/hops_test.cljc b/test/brewtility/enrich/hops_test.cljc index ef95b0f..ffaaa8d 100644 --- a/test/brewtility/enrich/hops_test.cljc +++ b/test/brewtility/enrich/hops_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.hops :as hop.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) ;; diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index ccda945..f522210 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -1,25 +1,151 @@ (ns brewtility.enrich.impl-test - (:require [brewtility.enrich.impl :as sut] + (:require #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + [brewtility.enrich.impl :as sut] + [brewtility.units.color :as color] [brewtility.units.options :as options] - [clojure.string :as str] - #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + [brewtility.units.pressure :as pressure] + [brewtility.units.specific-gravity :as specific-gravity] + [brewtility.units.temperature :as temperature] + [brewtility.units.time :as time] + [brewtility.units.volume :as volume] + [brewtility.units.weight :as weight] + [clojure.set :as set] + [clojure.string :as str])) + + +(deftest code-type-tests + (testing "Ensure maps used for options are structurally correct" + (testing "Defaults by System - These must be maps from Systems of Measure to their corresponding measurements." + (is (= (sort (keys sut/default-color-by-system)) + (sort (keys sut/default-pressure-by-system)) + (sort (keys sut/default-specific-gravity-by-system)) + (sort (keys sut/default-temperature-by-system)) + (sort (keys sut/default-time-by-system)) + (sort (keys sut/default-volume-by-system)) + (sort (keys sut/default-weight-by-system)) + (sort (vec options/systems-of-measure)))) + (is (set/subset? (set (vals sut/default-color-by-system)) color/measurements)) + (is (set/subset? (set (vals sut/default-pressure-by-system)) pressure/measurements)) + (is (set/subset? (set (vals sut/default-specific-gravity-by-system)) specific-gravity/measurements)) + (is (set/subset? (set (vals sut/default-temperature-by-system)) temperature/measurements)) + (is (set/subset? (set (vals sut/default-time-by-system)) time/measurements)) + (is (set/subset? (set (vals sut/default-volume-by-system)) volume/measurements)) + (is (set/subset? (set (vals sut/default-weight-by-system)) weight/measurements)))) + (testing "Option keys" + (is (keyword? sut/value-key)) + (is (keyword? sut/display-key)) + (is (keyword? sut/fine-grain-target-units)) + (is (keyword? sut/fine-grain-precision)) + (is (keyword? sut/fine-grain-suffix)))) + + +(deftest ->displayable-color-test + (testing "Ensure ->displayable-color supports its full suite of options." + (is (= "2.955 ebc" + (sut/->displayable-color 1.5 options/srm options/ebc) + (sut/->displayable-color 1.5 options/srm options/ebc sut/default-display-options)) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "3.0 ebc" + (sut/->displayable-color 1.5 options/srm options/ebc {options/precision 1}) + (sut/->displayable-color 1.5 options/srm options/ebc {options/precision 1 + options/suffix options/short})) + "Conversion may override the default precision") + (is (= "1.668 degrees lovibond" + (sut/->displayable-color 1.5 options/srm options/lovibond {options/suffix options/full}) + (sut/->displayable-color 1.5 options/srm options/lovibond {options/precision 3 + options/suffix options/full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-pressure-test + (testing "Ensure ->displayable-pressure supports its full suite of options" + (is (= "0.103 bar" + (sut/->displayable-pressure 1.5 options/psi options/bar) + (sut/->displayable-pressure 1.5 options/psi options/bar sut/default-display-options)) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "0.1 bar" + (sut/->displayable-pressure 1.5 options/psi options/bar {options/precision 1}) + (sut/->displayable-pressure 1.5 options/psi options/bar {options/precision 1 + options/suffix options/short})) + "Conversion may override the default precision") + (is (= "10.342 kilopascals" + (sut/->displayable-pressure 1.5 options/psi options/kilopascal {options/suffix options/full}) + (sut/->displayable-pressure 1.5 options/psi options/kilopascal {options/precision 3 + options/suffix options/full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-specific-gravity-test + (testing "Ensure ->displayable-specific-gravity supports its full suite of options" + (is (= "1.5 sg" + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity) + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity sut/default-display-options)) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "1.5 sg" + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1}) + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1 + options/suffix options/short})) + "Conversion may override the default precision") + (is (= "1.5 specific gravity" + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/suffix options/full}) + (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 3 + options/suffix options/full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-temperature-test + (testing "Ensure ->displayable-temperature supports its full suite of options" + (is (= "318.75 k" + (sut/->displayable-temperature 45.6 options/c options/k) + (sut/->displayable-temperature 45.6 options/c options/k {options/precision 3 + options/suffix options/short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "318.8 k" + (sut/->displayable-temperature 45.6 options/c options/k {options/precision 1}) + (sut/->displayable-temperature 45.6 options/c options/k {options/precision 1 + options/suffix options/short})) + "Conversion may override the default precision") + (is (= "318.75 kelvin" + (sut/->displayable-temperature 45.6 options/c options/k {options/precision 3 + options/suffix options/full}) + (sut/->displayable-temperature 45.6 options/c options/k {options/suffix options/full})) + "Conversion may override the default suffix"))) + + +(deftest ->displayable-time-test + (testing "Ensure ->displayable-time supports its full suite of options" + (is (= "0.76 m" + (sut/->displayable-time 45.6 options/second options/minute) + (sut/->displayable-time 45.6 options/second options/minute {options/precision 3 + options/suffix options/short})) + "Conversion defaults to 3 digits of precisions and shorthand unit names") + (is (= "0.8 m" + (sut/->displayable-time 45.6 options/second options/minute {options/precision 1}) + (sut/->displayable-time 45.6 options/second options/minute {options/precision 1 + options/suffix options/short})) + "Conversion may override the default precision") + (is (= "0.76 minute" + (sut/->displayable-time 45.6 options/second options/minute {options/suffix options/full}) + (sut/->displayable-time 45.6 options/second options/minute {options/precision 3 + options/suffix options/full})) + "Conversion may override the default suffix"))) (deftest ->displayable-volume-test (testing "Ensure ->displayable-volume supports its full suite of options" (is (= "5.678 l" (sut/->displayable-volume 1.5 :american-gallon :liter) - (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 3 - :suffix :short})) + (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 3 + options/suffix :short})) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "5.7 l" - (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 1 - :suffix :short})) + (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 1 + options/suffix :short})) "Conversion may override the default precision") (is (= "5.678 liter" - (sut/->displayable-volume 1.5 :american-gallon :liter {:precision 3 - :suffix :full})) + (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 3 + options/suffix :full})) "Conversion may override the default suffix")) (testing "Ensure ->displayable-volume supports its full suite of options with static keys" (is (= "5.678 l" @@ -40,58 +166,90 @@ (deftest ->displayable-weight-test (testing "Ensure ->displayable-weight supports its full suite of options" (is (= "0.053 oz" - (sut/->displayable-weight 1.5 :gram :ounce) - (sut/->displayable-weight 1.5 :gram :ounce {:precision 3 - :suffix :short})) + (sut/->displayable-weight 1.5 options/gram options/ounce) + (sut/->displayable-weight 1.5 options/gram options/ounce sut/default-display-options)) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "0.1 oz" - (sut/->displayable-weight 1.5 :gram :ounce {:precision 1 - :suffix :short})) + (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 1}) + (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "0.053 ounce" - (sut/->displayable-weight 1.5 :gram :ounce {:precision 3 - :suffix :full})) - "Conversion may override the default suffix"))) - - -(deftest ->displayable-time-test - (testing "Ensure ->displayable-time supports its full suite of options" - (is (= "0.76 m" - (sut/->displayable-time 45.6 :second :minute) - (sut/->displayable-time 45.6 :second :minute {:precision 3 - :suffix :short})) - "Conversion defaults to 3 digits of precisions and shorthand unit names") - (is (= "0.8 m" - (sut/->displayable-time 45.6 :second :minute {:precision 1 - :suffix :short})) - "Conversion may override the default precision") - (is (= "0.76 minute" - (sut/->displayable-time 45.6 :second :minute {:precision 3 - :suffix :full})) - "Conversion may override the default suffix"))) - - -(deftest ->displayable-temperature-test - (testing "Ensure ->displayable-temperature supports its full suite of options" - (is (= "318.75 k" - (sut/->displayable-temperature 45.6 :c :k) - (sut/->displayable-temperature 45.6 :c :k {:precision 3 - :suffix :short})) - "Conversion defaults to 3 digits of precisions and shorthand unit names") - (is (= "318.8 k" - (sut/->displayable-temperature 45.6 :c :k {:precision 1 - :suffix :short})) - "Conversion may override the default precision") - (is (= "318.75 kelvin" - (sut/->displayable-temperature 45.6 :c :k {:precision 3 - :suffix :full})) + (sut/->displayable-weight 1.5 options/gram options/ounce {options/suffix options/full}) + (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) (deftest target-unit-error-test + (testing "Ensure target-unit-error sets an appropriate error for color" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map options/color :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "color") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "lovibond") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for pressure" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map options/pressure :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "pressure") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "psi") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for specific-gravity" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map options/specific-gravity :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "specific-gravity") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "specific-gravity") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for temperature" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map options/temperature :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "temperature") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "celsius") + "The valid units are included in the error message"))) + (testing "Ensure target-unit-error sets an appropriate error for time" + (let [error-map {:some "error"} + new-error-map (sut/target-unit-error error-map options/time :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "time") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "minute") + "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for volume" (let [error-map {:some "error"} - new-error-map (sut/target-unit-error error-map :volume :fake)] + new-error-map (sut/target-unit-error error-map options/volume :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") (is (contains? new-error-map :units) @@ -104,7 +262,7 @@ "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for weight" (let [error-map {:some "error"} - new-error-map (sut/target-unit-error error-map :weight :fake)] + new-error-map (sut/target-unit-error error-map options/weight :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") (is (contains? new-error-map :units) @@ -114,23 +272,52 @@ (is (str/includes? (:units new-error-map) "fake") "The invalid unit is included in the error message") (is (str/includes? (:units new-error-map) "pound") + "The valid units are included in the error message")))) + + +(deftest source-unit-error-test + (testing "Ensure source-unit-error sets an appropriate error for color" + (let [error-map {:some "error"} + new-error-map (sut/source-unit-error error-map options/color :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "color") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "lovibond") "The valid units are included in the error message"))) - (testing "Ensure target-unit-error sets an appropriate error for time" + (testing "Ensure source-unit-error sets an appropriate error for pressure" (let [error-map {:some "error"} - new-error-map (sut/target-unit-error error-map :time :fake)] + new-error-map (sut/source-unit-error error-map options/pressure :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") (is (contains? new-error-map :units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "time") + (is (str/includes? (:units new-error-map) "pressure") "The type of attempted conversion is included in the error message") (is (str/includes? (:units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "minute") + (is (str/includes? (:units new-error-map) "psi") "The valid units are included in the error message"))) - (testing "Ensure target-unit-error sets an appropriate error for temperature" + (testing "Ensure source-unit-error sets an appropriate error for specific-gravity" (let [error-map {:some "error"} - new-error-map (sut/target-unit-error error-map :temperature :fake)] + new-error-map (sut/source-unit-error error-map options/specific-gravity :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "specific-gravity") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "specific-gravity") + "The valid units are included in the error message"))) + (testing "Ensure source-unit-error sets an appropriate error for temperature" + (let [error-map {:some "error"} + new-error-map (sut/source-unit-error error-map options/temperature :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") (is (contains? new-error-map :units) @@ -140,138 +327,325 @@ (is (str/includes? (:units new-error-map) "fake") "The invalid unit is included in the error message") (is (str/includes? (:units new-error-map) "celsius") + "The valid units are included in the error message"))) + (testing "Ensure source-unit-error sets an appropriate error for time" + (let [error-map {:some "error"} + new-error-map (sut/source-unit-error error-map options/time :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "time") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "minute") + "The valid units are included in the error message"))) + (testing "Ensure source-unit-error sets an appropriate error for volume" + (let [error-map {:some "error"} + new-error-map (sut/source-unit-error error-map options/volume :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "volume") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "teaspoon") + "The valid units are included in the error message"))) + (testing "Ensure source-unit-error sets an appropriate error for weight" + (let [error-map {:some "error"} + new-error-map (sut/source-unit-error error-map options/weight :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map :units) + "The new error is recorded") + (is (str/includes? (:units new-error-map) "weight") + "The type of attempted conversion is included in the error message") + (is (str/includes? (:units new-error-map) "fake") + "The invalid unit is included in the error message") + (is (str/includes? (:units new-error-map) "pound") "The valid units are included in the error message")))) (deftest systems-of-meaure-error-test - (testing "Ensure systems-of-meaure-error sets an appropriate error" + (testing "Ensure systems-of-meaure-error sets an appropriate error for color." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/color :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "color") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for pressure." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/pressure :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "pressure") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for specific-gravity." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/specific-gravity :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "specific-gravity") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for temperature." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/temperature :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "temperature") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for time." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/time :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "time") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for volume." (let [error-map {:some "error"} - new-error-map (sut/systems-of-meaure-error error-map :volume :fake)] + new-error-map (sut/systems-of-meaure-error error-map options/volume :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :system-of-measure) + (is (contains? new-error-map options/system-of-measure) "The new error is recorded") - (is (str/includes? (:system-of-measure new-error-map) "volume") + (is (str/includes? (options/system-of-measure new-error-map) "volume") "The type of attempted conversion is included in the error message") - (is (str/includes? (:system-of-measure new-error-map) "fake") + (is (str/includes? (options/system-of-measure new-error-map) "fake") "The invalid system of measure is included in the error message") - (is (str/includes? (:system-of-measure new-error-map) "metric") + (is (str/includes? (options/system-of-measure new-error-map) "metric") + "The valid values are included in the error message"))) + (testing "Ensure systems-of-meaure-error sets an appropriate error for weight." + (let [error-map {:some "error"} + new-error-map (sut/systems-of-meaure-error error-map options/weight :fake)] + (is (contains? new-error-map :some) + "Previously recorded errors are preserved") + (is (contains? new-error-map options/system-of-measure) + "The new error is recorded") + (is (str/includes? (options/system-of-measure new-error-map) "weight") + "The type of attempted conversion is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "fake") + "The invalid system of measure is included in the error message") + (is (str/includes? (options/system-of-measure new-error-map) "metric") "The valid values are included in the error message")))) (deftest precision-error-test (testing "Ensure precision-error sets an appropriate error" (let [error-map {:some "error"} - new-error-map (sut/precision-error error-map :volume 10)] + new-error-map (sut/precision-error error-map options/volume 10)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :precision) + (is (contains? new-error-map options/precision) "The new error is recorded") - (is (str/includes? (:precision new-error-map) "volume") + (is (str/includes? (options/precision new-error-map) "volume") "The type of attempted conversion is included in the error message") - (is (str/includes? (:precision new-error-map) "10") + (is (str/includes? (options/precision new-error-map) "10") "The invalid system of measure is included in the error message")))) (deftest suffix-error-test (testing "Ensure suffix-error sets an appropriate error" (let [error-map {:some "error"} - new-error-map (sut/suffix-error error-map :volume :fake)] + new-error-map (sut/suffix-error error-map options/volume :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :suffix) + (is (contains? new-error-map options/suffix) "The new error is recorded") - (is (str/includes? (:suffix new-error-map) "volume") + (is (str/includes? (options/suffix new-error-map) "volume") "The type of attempted conversion is included in the error message") - (is (str/includes? (:suffix new-error-map) "fake") + (is (str/includes? (options/suffix new-error-map) "fake") "The invalid suffix type is included in the error message") - (is (str/includes? (:suffix new-error-map) "full") + (is (str/includes? (options/suffix new-error-map) "full") "The valid values are included in the error message")))) -(deftest parse-enrich-displayable-volume-opts-test - (let [valid-opts {:target-units :teaspoon - :system-of-measure :metric - :precision 2 - :suffix :full} - error-regex #"Invalid displayable volume enrichment options"] - (testing "Ensure parse-enrich-displayable-volume-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-volume-opts valid-opts)) +(deftest parse-enrich-displayable-color-opts-test + (let [valid-opts {:target-units options/lovibond + :source-units options/srm + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable color enrichment options"] + (testing "Ensure parse-enrich-displayable-color-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-color-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units options/teaspoon + (let [valid-opts-w-keys {:target-units options/lovibond + :source-units options/srm options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-volume-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-color-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/suffix :fake)))))))) -(deftest parse-enrich-displayable-weight-opts-test - (let [valid-opts {:target-units :pound - :system-of-measure :metric - :precision 2 - :suffix :full} - error-regex #"Invalid displayable weight enrichment options"] - (testing "Ensure parse-enrich-displayable-weight-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-weight-opts valid-opts)) +(deftest parse-enrich-displayable-pressure-opts-test + (let [valid-opts {:target-units options/psi + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable pressure enrichment options"] + (testing "Ensure parse-enrich-displayable-pressure-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-pressure-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Ensure parse-enrich-displayable-pressure-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units options/psi + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-pressure-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/suffix :fake)))))))) + + +(deftest parse-enrich-displayable-specific-gravity-opts-test + (let [valid-opts {:target-units options/specific-gravity + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable specific gravity enrichment options"] + (testing "Ensure parse-enrich-displayable-specific-gravity-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-specific-gravity-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Ensure parse-enrich-displayable-specific-gravity-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units options/specific-gravity + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-specific-gravity-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/suffix :fake)))))))) + + +(deftest parse-enrich-displayable-temperature-opts-test + (let [valid-opts {:target-units options/c + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable temperature enrichment options"] + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-temperature-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units options/pound + (let [valid-opts-w-keys {:target-units options/c options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-weight-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-temperature-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-time-opts-test - (let [valid-opts {:target-units :minute - :system-of-measure :metric - :precision 2 - :suffix :full} + (let [valid-opts {:target-units options/minute + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} error-regex #"Invalid displayable time enrichment options"] (testing "Ensure parse-enrich-displayable-time-opts returns valid opts" (is (= valid-opts (sut/parse-enrich-displayable-time-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units options/minute + (let [valid-opts-w-keys {:target-units options/minute options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -280,54 +654,196 @@ (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/suffix :fake)))))))) -(deftest parse-enrich-displayable-temperature-opts-test - (let [valid-opts {:target-units :c - :system-of-measure :metric - :precision 2 - :suffix :full} - error-regex #"Invalid displayable temperature enrichment options"] - (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-temperature-opts valid-opts)) +(deftest parse-enrich-displayable-volume-opts-test + (let [valid-opts {:target-units options/teaspoon + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable volume enrichment options"] + (testing "Ensure parse-enrich-displayable-volume-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-volume-opts valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" - (let [valid-opts-w-keys {:target-units options/c + (let [valid-opts-w-keys {:target-units options/teaspoon options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-temperature-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-volume-opts valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/suffix :fake)))))))) + + +(deftest parse-enrich-displayable-weight-opts-test + (let [valid-opts {:target-units options/pound + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full} + error-regex #"Invalid displayable weight enrichment options"] + (testing "Ensure parse-enrich-displayable-weight-opts returns valid opts" + (is (= valid-opts (sut/parse-enrich-displayable-weight-opts valid-opts)) + "Valid opts are returned unchanged")) + (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" + (let [valid-opts-w-keys {:target-units options/pound + options/system-of-measure options/metric + options/precision 2 + options/suffix options/full}] + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-weight-opts valid-opts-w-keys)) + "Valid opts are returned unchanged with static keys"))) + (testing "Missing any option throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/suffix)))))) + (testing "An invalid selection for any require value throws an error" + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/suffix :fake)))))))) + + +(deftest enrich-displayable-color-test + (testing "Validate displayable color enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-color base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "0.595 srm")] + (is (= result-map (sut/enrich-displayable-color base-map {:display-key :display + :value-key :value + :source-units options/lovibond + :target-units options/srm}))))))) + + +(deftest enrich-displayable-pressure-test + (testing "Validate displayable pressure enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-pressure base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "1000.0 pa")] + (is (= result-map (sut/enrich-displayable-pressure base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/pascal}))))))) + + +(deftest enrich-displayable-specific-gravity-test + (testing "Validate displayable specific-gravity enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-specific-gravity base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "1.0 sg")] + (is (= result-map (sut/enrich-displayable-specific-gravity base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/specific-gravity}))))))) + + +(deftest enrich-displayable-temperature-test + (testing "Validate displayable temperature enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-temperature base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "274.15 k")] + (is (= result-map (sut/enrich-displayable-temperature base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/k}))))))) + + +(deftest enrich-displayable-time-test + (testing "Validate displayable time enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-time base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "1.0 m")] + (is (= result-map (sut/enrich-displayable-time base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/minute}))))))) + + +(deftest enrich-displayable-volume-test + (testing "Validate displayable volume enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-volume base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "202.884 tsp")] + (is (= result-map (sut/enrich-displayable-volume base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/teaspoon}))))))) + + +(deftest enrich-displayable-weight-test + (testing "Validate displayable weight enrichment." + (testing "If no value is provided, return the original map." + (let [base-map {:hello "there"}] + (is (= base-map (sut/enrich-displayable-weight base-map {:display-key :hello + :value-key :missing}))))) + (testing "When a value is provided, add the data at `:display-key`" + (let [base-map {:hello "there" + :value 1} + result-map (assoc base-map :display "2.205 lb")] + (is (= result-map (sut/enrich-displayable-weight base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/pound}))))))) diff --git a/test/brewtility/enrich/mash_test.cljc b/test/brewtility/enrich/mash_test.cljc index bc307df..e8b6356 100644 --- a/test/brewtility/enrich/mash_test.cljc +++ b/test/brewtility/enrich/mash_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.mash :as mash.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest static-enrichment-tests diff --git a/test/brewtility/enrich/miscs_test.cljc b/test/brewtility/enrich/miscs_test.cljc index 5deaa7e..d62c3f3 100644 --- a/test/brewtility/enrich/miscs_test.cljc +++ b/test/brewtility/enrich/miscs_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.miscs :as miscs.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest enrich-amount-is-weight-test diff --git a/test/brewtility/enrich/waters_test.cljc b/test/brewtility/enrich/waters_test.cljc index 1945442..1d6b0c8 100644 --- a/test/brewtility/enrich/waters_test.cljc +++ b/test/brewtility/enrich/waters_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.waters :as waters.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest enrich-display-amount-test diff --git a/test/brewtility/enrich/yeasts_test.cljc b/test/brewtility/enrich/yeasts_test.cljc index 837bdc5..363aed7 100644 --- a/test/brewtility/enrich/yeasts_test.cljc +++ b/test/brewtility/enrich/yeasts_test.cljc @@ -4,7 +4,7 @@ [com.wallbrew.spoon.spec :as spoon.spec] [common-beer-format.yeasts :as yeasts.format] #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (deftest enrich-amount-is-weight-test diff --git a/test/brewtility/precision_test.cljc b/test/brewtility/precision_test.cljc index 9ab803a..c4d24c5 100644 --- a/test/brewtility/precision_test.cljc +++ b/test/brewtility/precision_test.cljc @@ -14,7 +14,14 @@ (is (true? (sut/approximates? 100 90 0.1)) "90 is within 10% of 100") (is (false? (sut/approximates? 100 90 0.01)) - "90 is not within 1% of 100"))) + "90 is not within 1% of 100")) + (testing "Ensure that non-numeric values throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? nil 100 0.00001)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? 100 nil 0.00001)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? 100 100 nil)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? nil 100 0.00001)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? 100 nil 0.00001)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? 100 100 nil)))))) (deftest ->1dp-test diff --git a/test/brewtility/predicates/equipment_test.cljc b/test/brewtility/predicates/equipment_test.cljc index 9b4fdfd..e5bd147 100644 --- a/test/brewtility/predicates/equipment_test.cljc +++ b/test/brewtility/predicates/equipment_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.equipment-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.equipment :as equipment] [brewtility.predicates.equipment :as sut] [common-beer-format.equipment :as cbf-equipment])) diff --git a/test/brewtility/predicates/fermentables_test.cljc b/test/brewtility/predicates/fermentables_test.cljc index e5a14c2..5115337 100644 --- a/test/brewtility/predicates/fermentables_test.cljc +++ b/test/brewtility/predicates/fermentables_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.fermentables-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.fermentables :as fermentables] [brewtility.predicates.fermentables :as sut] [common-beer-format.fermentables :as cbf-fermentables])) diff --git a/test/brewtility/predicates/hops_test.cljc b/test/brewtility/predicates/hops_test.cljc index 3f8b589..da2c727 100644 --- a/test/brewtility/predicates/hops_test.cljc +++ b/test/brewtility/predicates/hops_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.hops-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.hops :as hops] [brewtility.predicates.hops :as sut] [common-beer-format.hops :as cbf-hops])) diff --git a/test/brewtility/predicates/impl_test.cljc b/test/brewtility/predicates/impl_test.cljc index f0564c8..0425b58 100644 --- a/test/brewtility/predicates/impl_test.cljc +++ b/test/brewtility/predicates/impl_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.impl-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.predicates.impl :as sut])) diff --git a/test/brewtility/predicates/mash_test.cljc b/test/brewtility/predicates/mash_test.cljc index cbe16b3..7c98fe9 100644 --- a/test/brewtility/predicates/mash_test.cljc +++ b/test/brewtility/predicates/mash_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.mash-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.mash :as mash] [brewtility.predicates.mash :as sut] [common-beer-format.mash :as cbf-mash])) diff --git a/test/brewtility/predicates/miscs_test.cljc b/test/brewtility/predicates/miscs_test.cljc index bb1bd63..6c52e8a 100644 --- a/test/brewtility/predicates/miscs_test.cljc +++ b/test/brewtility/predicates/miscs_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.miscs-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.miscs :as miscs] [brewtility.predicates.miscs :as sut] [common-beer-format.miscs :as cbf-miscs])) diff --git a/test/brewtility/predicates/recipes_test.cljc b/test/brewtility/predicates/recipes_test.cljc index 62edf9e..c101c70 100644 --- a/test/brewtility/predicates/recipes_test.cljc +++ b/test/brewtility/predicates/recipes_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.recipes-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.recipes :as recipes] [brewtility.predicates.recipes :as sut] [common-beer-format.recipes :as cbf-recipes])) diff --git a/test/brewtility/predicates/styles_test.cljc b/test/brewtility/predicates/styles_test.cljc index 38baf37..3b69e68 100644 --- a/test/brewtility/predicates/styles_test.cljc +++ b/test/brewtility/predicates/styles_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.styles-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.styles :as styles] [brewtility.predicates.styles :as sut] [common-beer-format.styles :as cbf-styles])) diff --git a/test/brewtility/predicates/waters_test.cljc b/test/brewtility/predicates/waters_test.cljc index 9913f5a..b736af5 100644 --- a/test/brewtility/predicates/waters_test.cljc +++ b/test/brewtility/predicates/waters_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.waters-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.waters :as waters] [brewtility.predicates.waters :as sut] [common-beer-format.waters :as cbf-waters])) diff --git a/test/brewtility/predicates/yeasts_test.cljc b/test/brewtility/predicates/yeasts_test.cljc index c7b4a83..f1dc8ce 100644 --- a/test/brewtility/predicates/yeasts_test.cljc +++ b/test/brewtility/predicates/yeasts_test.cljc @@ -1,6 +1,6 @@ (ns brewtility.predicates.yeasts-test (:require #? (:clj [clojure.test :refer [deftest is testing]]) - #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.yeasts :as yeasts] [brewtility.predicates.yeasts :as sut] [common-beer-format.yeasts :as cbf-yeasts])) From f3edf105b5834e9bc33c7dbdafb63479aa15ea77 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 19 Feb 2024 23:37:39 +0000 Subject: [PATCH 31/44] Fix typo in test string --- src/brewtility/calculations.cljc | 1 + src/brewtility/precision.cljc | 8 ++++---- test/brewtility/precision_test.cljc | 12 ++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/brewtility/calculations.cljc b/src/brewtility/calculations.cljc index 1241ffa..0d2f372 100644 --- a/src/brewtility/calculations.cljc +++ b/src/brewtility/calculations.cljc @@ -28,6 +28,7 @@ (throw (ex-info "Cannot calculate color with non-numeric values" {:amount amount :color color})))) + (defn calculate-malt-color-units "Given a collection of `common-beer-format` conforming `fermentables`, and a conformed `batch-size` in liters, return the overall Malt Color Units for a recipe." {:added "1.0" diff --git a/src/brewtility/precision.cljc b/src/brewtility/precision.cljc index e8dd214..55aff62 100644 --- a/src/brewtility/precision.cljc +++ b/src/brewtility/precision.cljc @@ -25,10 +25,10 @@ :see-also ["->1dp" "->2dp" "->3dp"]} [^double x ^long num-decimals] (double - #?(:clj (.setScale (bigdec x) num-decimals RoundingMode/HALF_UP) - :cljs (let [denominator (Math/pow 10.0 (double num-decimals)) - numerator (Math/round (* x denominator))] - (/ numerator denominator))))) + #?(:clj (.setScale (bigdec x) num-decimals RoundingMode/HALF_UP) + :cljs (let [denominator (Math/pow 10.0 (double num-decimals)) + numerator (Math/round (* x denominator))] + (/ numerator denominator))))) (defn ->1dp diff --git a/test/brewtility/precision_test.cljc b/test/brewtility/precision_test.cljc index c4d24c5..0f3d5fb 100644 --- a/test/brewtility/precision_test.cljc +++ b/test/brewtility/precision_test.cljc @@ -16,12 +16,12 @@ (is (false? (sut/approximates? 100 90 0.01)) "90 is not within 1% of 100")) (testing "Ensure that non-numeric values throw an exception" - #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? nil 100 0.00001)))) - #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? 100 nil 0.00001)))) - #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate non-numeric values" (sut/approximates? 100 100 nil)))) - #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? nil 100 0.00001)))) - #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? 100 nil 0.00001)))) - #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate non-numeric values" (sut/approximates? 100 100 nil)))))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate using non-numeric values" (sut/approximates? nil 100 0.00001)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate using non-numeric values" (sut/approximates? 100 nil 0.00001)))) + #?(:clj (is (thrown-with-msg? Exception #"Cannot approximate using non-numeric values" (sut/approximates? 100 100 nil)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate using non-numeric values" (sut/approximates? nil 100 0.00001)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate using non-numeric values" (sut/approximates? 100 nil 0.00001)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Cannot approximate using non-numeric values" (sut/approximates? 100 100 nil)))))) (deftest ->1dp-test From 6f6ff418ea08d5538302e0ca41e270b19bd34f36 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 2 Mar 2024 19:00:08 +0000 Subject: [PATCH 32/44] De-dupe enricher implementation --- src/brewtility/enrich/equipment.cljc | 18 +- src/brewtility/enrich/fermentables.cljc | 35 +- src/brewtility/enrich/hops.cljc | 7 +- src/brewtility/enrich/impl.cljc | 645 +++--------------- src/brewtility/enrich/mash.cljc | 15 +- src/brewtility/enrich/miscs.cljc | 9 +- src/brewtility/enrich/styles.cljc | 15 +- src/brewtility/enrich/waters.cljc | 11 +- src/brewtility/enrich/yeasts.cljc | 47 +- src/brewtility/units/color.cljc | 34 +- test/brewtility/enrich/fermentables_test.cljc | 2 +- test/brewtility/enrich/impl_test.cljc | 458 ++++++------- test/brewtility/units/color_test.cljc | 47 ++ 13 files changed, 491 insertions(+), 852 deletions(-) diff --git a/src/brewtility/enrich/equipment.cljc b/src/brewtility/enrich/equipment.cljc index f095b46..add804d 100644 --- a/src/brewtility/enrich/equipment.cljc +++ b/src/brewtility/enrich/equipment.cljc @@ -1,5 +1,5 @@ (ns brewtility.enrich.equipment - "Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps" + "Enricher-pattern functions for [equipment](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/equipment.cljc) maps." {:added "2.1" :see-also ["brewtility.enrich.fermentables" "brewtility.enrich.hops" @@ -89,7 +89,7 @@ impl/fine-grain-target-units boil-size-target-units impl/fine-grain-precision boil-size-precision impl/fine-grain-suffix boil-size-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-batch-size @@ -124,7 +124,7 @@ impl/fine-grain-target-units batch-size-target-units impl/fine-grain-precision batch-size-precision impl/fine-grain-suffix batch-size-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-tun-volume @@ -159,7 +159,7 @@ impl/fine-grain-target-units tun-volume-target-units impl/fine-grain-precision tun-volume-precision impl/fine-grain-suffix tun-volume-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-tun-weight @@ -194,7 +194,7 @@ impl/fine-grain-target-units tun-weight-target-units impl/fine-grain-precision tun-weight-precision impl/fine-grain-suffix tun-weight-suffix})] - (impl/enrich-displayable-weight equipment options)))) + (impl/enrich-displayable-units options/weight equipment options)))) (defn enrich-display-top-up-water @@ -229,7 +229,7 @@ impl/fine-grain-target-units top-up-water-target-units impl/fine-grain-precision top-up-water-precision impl/fine-grain-suffix top-up-water-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-trub-chiller-loss @@ -264,7 +264,7 @@ impl/fine-grain-target-units trub-chiller-loss-target-units impl/fine-grain-precision trub-chiller-loss-precision impl/fine-grain-suffix trub-chiller-loss-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-lauter-deadspace @@ -299,7 +299,7 @@ impl/fine-grain-target-units lauter-deadspace-target-units impl/fine-grain-precision lauter-deadspace-precision impl/fine-grain-suffix lauter-deadspace-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-display-top-up-kettle @@ -334,7 +334,7 @@ impl/fine-grain-target-units top-up-kettle-target-units impl/fine-grain-precision top-up-kettle-precision impl/fine-grain-suffix top-up-kettle-suffix})] - (impl/enrich-displayable-volume equipment options)))) + (impl/enrich-displayable-units options/volume equipment options)))) (defn enrich-equipment diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 47433b2..692feb4 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -206,31 +206,22 @@ "enrich-fermentables" "enrich-fermentables-wrapper"]} ([fermentable] (enrich-display-color fermentable {})) - ;; TODO: Port this color conversion into the `units` namespace - ([fermentable {:keys [color-system suffix] + ([fermentable {:keys [color-system + fermentable-color-target-units + fermentable-color-precision + fermentable-color-suffix] :as opts}] (let [source-color-system (if (fermentables.predicate/grain? fermentable opts) options/lovibond options/srm) - target-color-system (or color-system source-color-system) - suffix (or suffix options/short)] - (if (and (contains? color/measurements target-color-system) - (contains? #{options/full options/short} suffix)) - (let [source-color (if (fermentables.predicate/grain? fermentable opts) - (:color fermentable) - (color/convert (:color fermentable) options/srm options/lovibond)) - target-color (case target-color-system ; TODO: Add this functionality to the `units` namespace - :lovibond source-color - :srm (color/convert source-color options/lovibond options/srm) - :ebc (color/convert source-color options/lovibond options/ebc) - :rgba (color/convert source-color options/lovibond options/rgba)) - suffix-string (get-in color/measurements->display-name [target-color-system suffix]) - display-value (str target-color suffix-string)] - (assoc fermentable :display-color display-value)) - (throw (ex-info "Invalid options for displaying fermentable color" {:color-system target-color-system - :allowed-color-systems color/measurements - :suffix suffix - :allowed-suffixes #{:full :short}})))))) + color-system (or color-system source-color-system) + opts (merge opts {:source-units source-color-system + impl/value-key :color + impl/display-key :display-color + impl/fine-grain-target-units (or fermentable-color-target-units color-system) + impl/fine-grain-precision fermentable-color-precision + impl/fine-grain-suffix fermentable-color-suffix})] + (impl/enrich-displayable-units options/color fermentable opts)))) (defn enrich-display-amount @@ -269,7 +260,7 @@ impl/fine-grain-target-units fermentable-amount-target-units impl/fine-grain-precision fermentable-amount-precision impl/fine-grain-suffix fermentable-amount-suffix})] - (impl/enrich-displayable-weight fermentable options)))) + (impl/enrich-displayable-units options/weight fermentable options)))) (defn enrich-fermentable diff --git a/src/brewtility/enrich/hops.cljc b/src/brewtility/enrich/hops.cljc index 1f41898..6370a47 100644 --- a/src/brewtility/enrich/hops.cljc +++ b/src/brewtility/enrich/hops.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.styles" "brewtility.enrich.waters" "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-display-amount @@ -48,7 +49,7 @@ impl/fine-grain-target-units hop-amount-target-units impl/fine-grain-precision hop-amount-precision impl/fine-grain-suffix hop-amount-suffix})] - (impl/enrich-displayable-weight hop options)))) + (impl/enrich-displayable-units options/weight hop options)))) (defn enrich-display-time @@ -86,7 +87,7 @@ impl/fine-grain-target-units hop-time-target-units impl/fine-grain-precision hop-time-precision impl/fine-grain-suffix hop-time-suffix})] - (impl/enrich-displayable-time hop options)))) + (impl/enrich-displayable-units options/time hop options)))) (defn enrich-hop diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index f75484c..3511505 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -5,7 +5,8 @@ {:no-doc true :added "2.1" :implementation-only true} - (:require [brewtility.units.color :as color] + (:require [brewtility.units :as units] + [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] [brewtility.units.specific-gravity :as specific-gravity] @@ -102,131 +103,27 @@ options/international-system options/kilogram}) +(def beer-xml-standard-units + "The standard units for each measurement type in BeerXML." + {options/color options/srm + options/pressure options/kilopascal + options/specific-gravity options/specific-gravity + options/temperature options/celsius + options/time options/minute + options/volume options/liter + options/weight options/kilogram}) + + ;; TODO: Pluralize strings -(defn ->displayable-color - "Convert a color then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-pressure" - "->displayable-specific-gravity" - "->displayable-temperature" - "->displayable-time" - "->displayable-volume" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-color source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (color/convert source-units target-units) - (color/display target-units opts)))) - - -(defn ->displayable-pressure - "Convert a pressure then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-specific-gravity" - "->displayable-temperature" - "->displayable-time" - "->displayable-volume" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-pressure source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (pressure/convert source-units target-units) - (pressure/display target-units opts)))) - - -(defn ->displayable-specific-gravity - "Convert a specific gravity then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-pressure" - "->displayable-temperature" - "->displayable-time" - "->displayable-volume" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-specific-gravity source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (specific-gravity/convert source-units target-units) - (specific-gravity/display target-units opts)))) - - -(defn ->displayable-temperature - "Convert a temperature then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-pressure" - "->displayable-specific-gravity" - "->displayable-time" - "->displayable-volume" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-temperature source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (temperature/convert source-units target-units) - (temperature/display target-units opts)))) - - -(defn ->displayable-time - "Convert a time then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-pressure" - "->displayable-specific-gravity" - "->displayable-temperature" - "->displayable-volume" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-time source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (time/convert source-units target-units) - (time/display target-units opts)))) - - -(defn ->displayable-volume - "Convert a volume then render it to a displayable value." - {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-pressure" - "->displayable-specific-gravity" - "->displayable-temperature" - "->displayable-time" - "->displayable-weight"]} - ([source-value source-units target-units] - (->displayable-volume source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (volume/convert source-units target-units) - (volume/display target-units opts)))) - - -(defn ->displayable-weight - "Convert a weight then render it to a displayable value." +(defn ->displayable-units + "Convert a unit then render it to a displayable value." {:added "2.1" - :no-doc true - :see-also ["->displayable-color" - "->displayable-pressure" - "->displayable-specific-gravity" - "->displayable-temperature" - "->displayable-time" - "->displayable-volume"]} - ([source-value source-units target-units] - (->displayable-weight source-value source-units target-units default-display-options)) - ([source-value source-units target-units opts] - (-> source-value - (weight/convert source-units target-units) - (weight/display target-units opts)))) + :no-doc true} + ([measurement-type source-value source-units target-units] + (->displayable-units measurement-type source-value source-units target-units default-display-options)) + ([measurement-type source-value source-units target-units opts] + (let [converted-value (units/convert measurement-type source-value source-units target-units)] + (units/display measurement-type converted-value target-units opts)))) (defn target-unit-error @@ -335,458 +232,138 @@ ;; Enricher argument validation functions -(defn parse-enrich-displayable-color-opts - "A function to parse the options map passed to `->displayable-color` - This requires the user to supply valid values for: `target-units`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." +(defn valid-unit-for-measurement-type? + "TODO: Fill me in" {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color"]} - [{:keys [target-units source-units precision suffix] - :as opts}] - (let [valid-target? (contains? color/srm->measurement target-units) - valid-source? (contains? color/measurement->srm source-units) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :color target-units) - (not valid-source?) (source-unit-error :color source-units) - (not valid-precision?) (precision-error :color precision) - (not valid-suffix?) (suffix-error :color suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable color enrichment options: " errors))))) - - -(defn parse-enrich-displayable-pressure-opts - "A function to parse the options map passed to `->displayable-pressure` + :no-doc false} + [measurement-type unit] + (case measurement-type + :color (contains? color/measurements unit) + :pressure (contains? pressure/measurements unit) + :specific-gravity (contains? specific-gravity/measurements unit) + :temperature (contains? temperature/measurements unit) + :time (contains? time/measurements unit) + :volume (contains? volume/measurements unit) + :weight (contains? weight/measurements unit) + (throw (ex-info "Unsupported unit system" + {:measurement-type measurement-type + :allowed-values options/measurement-types})))) + + +(defn parse-enrich-displayable-units-opts + "A function to parse the options map passed to `->displayable-units` This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." {:added "2.1" :no-doc true :see-also ["enrich-displayable-pressure"]} - [{:keys [target-units system-of-measure precision suffix] - :as opts}] - (let [valid-target? (contains? pressure/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :pressure target-units) - (not valid-system?) (systems-of-meaure-error :pressure system-of-measure) - (not valid-precision?) (precision-error :pressure precision) - (not valid-suffix?) (suffix-error :pressure suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable pressure enrichment options: " errors))))) - - -(defn parse-enrich-displayable-specific-gravity-opts - "A function to parse the options map passed to `->displayable-specific-gravity` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-specific-gravity"]} - [{:keys [target-units system-of-measure precision suffix] + [measurement-type + {:keys [target-units system-of-measure precision suffix] :as opts}] - (let [valid-target? (contains? specific-gravity/measurements target-units) + (let [valid-target? (valid-unit-for-measurement-type? measurement-type target-units) valid-system? (contains? options/systems-of-measure system-of-measure) valid-precision? (int? precision) valid-suffix? (contains? options/supported-suffixes suffix) errors (cond-> {} - (not valid-target?) (target-unit-error :specific-gravity target-units) - (not valid-system?) (systems-of-meaure-error :specific-gravity system-of-measure) - (not valid-precision?) (precision-error :specific-gravity precision) - (not valid-suffix?) (suffix-error :specific-gravity suffix))] + (not valid-target?) (target-unit-error measurement-type target-units) + (not valid-system?) (systems-of-meaure-error measurement-type system-of-measure) + (not valid-precision?) (precision-error measurement-type precision) + (not valid-suffix?) (suffix-error measurement-type suffix))] (if (empty? errors) opts - (throw (ex-info "Invalid displayable specific gravity enrichment options: " errors))))) + (throw (ex-info "Invalid enrichment options for ->displayable-units: " errors))))) -(defn parse-enrich-displayable-temperature-opts - "A function to parse the options map passed to `->displayable-temperature` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-temperature"]} - [{:keys [precision suffix system-of-measure target-units] - :as opts}] - (let [valid-target? (contains? temperature/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :temperature target-units) - (not valid-system?) (systems-of-meaure-error :temperature system-of-measure) - (not valid-precision?) (precision-error :temperature precision) - (not valid-suffix?) (suffix-error :temperature suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable temperature enrichment options: " errors))))) - - -(defn parse-enrich-displayable-time-opts - "A function to parse the options map passed to `->displayable-time` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-time"]} - [{:keys [precision suffix system-of-measure target-units] - :as opts}] - (let [valid-target? (contains? time/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :time target-units) - (not valid-system?) (systems-of-meaure-error :time system-of-measure) - (not valid-precision?) (precision-error :time precision) - (not valid-suffix?) (suffix-error :time suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable time enrichment options: " errors))))) - - -(defn parse-enrich-displayable-volume-opts - "A function to parse the options map passed to `->displayable-volume` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-volume"]} - [{:keys [target-units system-of-measure precision suffix] - :as opts}] - (let [valid-target? (contains? volume/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :volume target-units) - (not valid-system?) (systems-of-meaure-error :volume system-of-measure) - (not valid-precision?) (precision-error :volume precision) - (not valid-suffix?) (suffix-error :volume suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable volume enrichment options: " errors))))) - - -(defn parse-enrich-displayable-weight-opts - "A function to parse the options map passed to `->displayable-weight` - This requires the user to supply valid values for: `target-units`, `system-of-measure`, `precision`, and `suffix`. - If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-weight"]} - [{:keys [target-units system-of-measure precision suffix] - :as opts}] - (let [valid-target? (contains? weight/measurements target-units) - valid-system? (contains? options/systems-of-measure system-of-measure) - valid-precision? (int? precision) - valid-suffix? (contains? options/supported-suffixes suffix) - errors (cond-> {} - (not valid-target?) (target-unit-error :weight target-units) - (not valid-system?) (systems-of-meaure-error :weight system-of-measure) - (not valid-precision?) (precision-error :weight precision) - (not valid-suffix?) (suffix-error :weight suffix))] - (if (empty? errors) - opts - (throw (ex-info "Invalid displayable weight enrichment options: " errors))))) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-color - "A function to enrich a map with a human-readable version of a color at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the color to the target system and return the original value with the new value added at `display-key`" +(defn get-default-unit-by-measurement-type-and-system + "A function to get the default unit for a given `measurement-type` and `system-of-measure`. + If the measurement type is not supported, a Java Exception or Javascript Error is thrown with information on the invalid options." {:added "2.1" :no-doc true :see-also ["enrich-displayable-color" + "enrich-displayable-pressure" "enrich-displayable-specific-gravity" "enrich-displayable-temperature" "enrich-displayable-time" "enrich-displayable-volume" - "enrich-displayable-weight"]} - [source-data + "enrich-displayable-weight" + "enrich-displayable-range"]} + [measurement-type system-of-measure] + (case measurement-type + :color (get default-color-by-system system-of-measure) + :pressure (get default-pressure-by-system system-of-measure) + :specific-gravity (get default-specific-gravity-by-system system-of-measure) + :temperature (get default-temperature-by-system system-of-measure) + :time (get default-time-by-system system-of-measure) + :volume (get default-volume-by-system system-of-measure) + :weight (get default-weight-by-system system-of-measure) + (throw (ex-info "Unsupported unit system" + {:measurement-type measurement-type + :allowed-values options/measurement-types})))) + + +#_{:clj-kondo/ignore [:shadowed-var]} + + +(defn enrich-displayable-units + "TODO: Fill me in" + {:added "2.1" + :no-doc true} + [measurement-type + source-data {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key source-units] :or {system-of-measure options/us-customary suffix options/short precision options/default-precision}}] (if-let [source-value (get source-data value-key)] - (let [system-of-measure-color (get default-color-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-color) + (let [system-of-measure-units (get-default-unit-by-measurement-type-and-system measurement-type system-of-measure) + beer-xml-source-units (get beer-xml-standard-units measurement-type) + source-units (or source-units beer-xml-source-units) + target-units (or fine-grain-target-units system-of-measure-units) precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-color-opts + opts (parse-enrich-displayable-units-opts + measurement-type {:target-units target-units :source-units source-units options/system-of-measure system-of-measure options/precision precision options/suffix suffix})] - (assoc source-data display-key (->displayable-color source-value source-units target-units opts))) + (assoc source-data display-key (->displayable-units measurement-type source-value source-units target-units opts))) source-data)) #_{:clj-kondo/ignore [:shadowed-var]} -(defn enrich-displayable-pressure - "A function to enrich a map with a human-readable version of a pressure at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the pressure to the target system and return the original value with the new value added at `display-key`" +(defn enrich-displayable-range + "TODO: Fill me in" {:added "2.1" :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-specific-gravity" - "enrich-displayable-temperature" - "enrich-displayable-time" - "enrich-displayable-volume" - "enrich-displayable-weight"]} - [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix value-key system-of-measure] - :or {system-of-measure options/us-customary - suffix options/short - precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-pressure (get default-pressure-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-pressure) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-pressure-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-pressure source-value options/kilopascal target-units opts))) - source-data)) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-specific-gravity - "A function to enrich a map with a human-readable version of a specific gravity at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the specific gravity to the target system and return the original value with the new value added at `display-key`" - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-temperature" - "enrich-displayable-time" - "enrich-displayable-volume" - "enrich-displayable-weight"]} - [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure options/us-customary - suffix options/short - precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-sg (get default-specific-gravity-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-sg) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-specific-gravity-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-specific-gravity source-value options/specific-gravity target-units opts))) - source-data)) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-temperature - "A function to enrich a map with a human-readable version of a temperature at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the temperature to the target units and return the original value with the new value added at `display-key`" - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-specific-gravity" - "enrich-displayable-time" - "enrich-displayable-volume" - "enrich-displayable-weight"]} - [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure options/us-customary - suffix options/short - precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-temperature (get default-temperature-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-temperature) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-temperature-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-temperature source-value options/celsius target-units opts))) - source-data)) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-time - "A function to enrich a map with a human-readable version of a time at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the time to the target units and return the original value with the new value added at `display-key`" - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-specific-gravity" - "enrich-displayable-temperature" - "enrich-displayable-volume" - "enrich-displayable-weight"]} - [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] + :see-also ["enrich-displayable-units"]} + [measurement-type + source-data + {:keys [low-value-key high-value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix source-units] :or {system-of-measure options/us-customary suffix options/short precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-time (get default-time-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-time) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-time-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-time source-value options/minute target-units opts))) - source-data)) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-volume - "A function to enrich a map with a human-readable version of a volume at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the volume to the target units and return the original value with the new value added at `display-key`" - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-specific-gravity" - "enrich-displayable-temperature" - "enrich-displayable-time" - "enrich-displayable-weight"]} - [source-data - {:keys [display-key fine-grain-precision fine-grain-suffix fine-grain-target-units precision suffix system-of-measure value-key] - :or {system-of-measure options/us-customary - suffix options/short - precision options/default-precision}}] - - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-volume (get default-volume-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-volume) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-volume-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-volume source-value options/liter target-units opts))) - source-data)) - - -#_{:clj-kondo/ignore [:shadowed-var]} - - -(defn enrich-displayable-weight - "A function to enrich a map with a human-readable version of a weight at `value-key`. - If invalid options are passed, the function throws a Java Exception or Javascript Error with information on the invalid options. - - Since many enrichers can leverage the same options (for example, `:precision`) this function will check for common options. - However, it will defer to more selective values passed in with the following precedence: - - `:fine-grain-target-units` > `system-of-measure` - `:fine-grain-precision` > `precision` - `:fine-grain-suffix` > `suffix` - - If these options are valid, the function will convert the weight to the target units and return the original value with the new value added at `display-key`" - {:added "2.1" - :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-specific-gravity" - "enrich-displayable-temperature" - "enrich-displayable-time" - "enrich-displayable-volume"]} - [source-data - {:keys [value-key display-key system-of-measure suffix precision fine-grain-target-units fine-grain-precision fine-grain-suffix] - :or {system-of-measure options/us-customary - suffix options/short - precision options/default-precision}}] - (if-let [source-value (get source-data value-key)] - (let [system-of-measure-weight (get default-weight-by-system system-of-measure) - target-units (or fine-grain-target-units system-of-measure-weight) - precision (or fine-grain-precision precision) - suffix (or fine-grain-suffix suffix) - opts (parse-enrich-displayable-weight-opts - {:target-units target-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix})] - (assoc source-data display-key (->displayable-weight source-value options/kilogram target-units opts))) - source-data)) + (let [low-source-value (get source-data low-value-key) + high-source-value (get source-data high-value-key)] + (if (and low-source-value high-source-value) + (let [system-of-measure-units (get-default-unit-by-measurement-type-and-system measurement-type system-of-measure) + beer-xml-source-units (get beer-xml-standard-units measurement-type) + source-units (or source-units beer-xml-source-units) + target-units (or fine-grain-target-units system-of-measure-units) + precision (or fine-grain-precision precision) + suffix (or fine-grain-suffix suffix) + opts (parse-enrich-displayable-units-opts + measurement-type + {:target-units target-units + :source-units source-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix}) + converted-low-value (units/convert measurement-type low-source-value source-units target-units) + displayable-high-value (->displayable-units measurement-type high-source-value source-units target-units opts) + displayable-range (str converted-low-value " - " displayable-high-value)] + (assoc source-data display-key displayable-range)) + source-data))) diff --git a/src/brewtility/enrich/mash.cljc b/src/brewtility/enrich/mash.cljc index 20d24f2..7ab2b39 100644 --- a/src/brewtility/enrich/mash.cljc +++ b/src/brewtility/enrich/mash.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.styles" "brewtility.enrich.waters" "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-display-step-temperature @@ -50,7 +51,7 @@ impl/fine-grain-target-units display-temperature-target-units impl/fine-grain-precision display-temperature-precision impl/fine-grain-suffix display-temperature-suffix})] - (impl/enrich-displayable-temperature mash-step options)))) + (impl/enrich-displayable-units options/temperature mash-step options)))) (defn enrich-display-infuse-amount @@ -91,7 +92,7 @@ impl/fine-grain-target-units display-infuse-amount-target-units impl/fine-grain-precision display-infuse-amount-precision impl/fine-grain-suffix display-infuse-amount-suffix})] - (impl/enrich-displayable-volume mash-step options)))) + (impl/enrich-displayable-units options/volume mash-step options)))) (defn enrich-mash-step @@ -282,7 +283,7 @@ impl/fine-grain-target-units display-grain-temperature-target-units impl/fine-grain-precision display-grain-temperature-precision impl/fine-grain-suffix display-grain-temperature-suffix})] - (impl/enrich-displayable-temperature mash options)))) + (impl/enrich-displayable-units options/temperature mash options)))) (defn enrich-display-tun-temperature @@ -319,7 +320,7 @@ impl/fine-grain-target-units display-tun-temperature-target-units impl/fine-grain-precision display-tun-temperature-precision impl/fine-grain-suffix display-tun-temperature-suffix})] - (impl/enrich-displayable-temperature mash options)))) + (impl/enrich-displayable-units options/temperature mash options)))) (defn enrich-display-sparge-temperature @@ -356,7 +357,7 @@ impl/fine-grain-target-units display-sparge-temperature-target-units impl/fine-grain-precision display-sparge-temperature-precision impl/fine-grain-suffix display-sparge-temperature-suffix})] - (impl/enrich-displayable-temperature mash options)))) + (impl/enrich-displayable-units options/temperature mash options)))) (defn enrich-display-tun-weight @@ -393,7 +394,7 @@ impl/fine-grain-target-units display-tun-weight-target-units impl/fine-grain-precision display-tun-weight-precision impl/fine-grain-suffix display-tun-weight-suffix})] - (impl/enrich-displayable-weight mash options)))) + (impl/enrich-displayable-units options/weight mash options)))) (defn enrich-mash diff --git a/src/brewtility/enrich/miscs.cljc b/src/brewtility/enrich/miscs.cljc index 3dce83a..64490b2 100644 --- a/src/brewtility/enrich/miscs.cljc +++ b/src/brewtility/enrich/miscs.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.styles" "brewtility.enrich.waters" "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-amount-is-weight @@ -62,7 +63,7 @@ impl/fine-grain-target-units misc-time-target-units impl/fine-grain-precision misc-time-precision impl/fine-grain-suffix misc-time-suffix})] - (impl/enrich-displayable-time misc options)))) + (impl/enrich-displayable-units options/time misc options)))) (defn enrich-display-amount @@ -103,8 +104,8 @@ impl/fine-grain-precision misc-amount-precision impl/fine-grain-suffix misc-amount-suffix})] (if (:amount-is-weight misc) - (impl/enrich-displayable-weight misc options) - (impl/enrich-displayable-volume misc options))))) + (impl/enrich-displayable-units options/weight misc options) + (impl/enrich-displayable-units options/volume misc options))))) (defn enrich-misc diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index eb0e3ec..03c8a94 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.recipes" "brewtility.enrich.waters" "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-display-og-min @@ -47,7 +48,7 @@ impl/fine-grain-target-units style-display-og-min-target-units impl/fine-grain-precision style-display-og-min-precision impl/fine-grain-suffix style-display-og-min-suffix})] - (impl/enrich-displayable-specific-gravity style options)))) + (impl/enrich-displayable-units options/specific-gravity style options)))) (defn enrich-display-og-max @@ -85,7 +86,7 @@ impl/fine-grain-target-units style-display-og-max-target-units impl/fine-grain-precision style-display-og-max-precision impl/fine-grain-suffix style-display-og-max-suffix})] - (impl/enrich-displayable-specific-gravity style options)))) + (impl/enrich-displayable-units options/specific-gravity style options)))) (defn enrich-display-fg-min @@ -124,7 +125,7 @@ impl/fine-grain-target-units style-display-fg-min-target-units impl/fine-grain-precision style-display-fg-min-precision impl/fine-grain-suffix style-display-fg-min-suffix})] - (impl/enrich-displayable-specific-gravity style options)))) + (impl/enrich-displayable-units options/specific-gravity style options)))) (defn enrich-display-fg-max @@ -163,7 +164,7 @@ impl/fine-grain-target-units style-display-fg-max-target-units impl/fine-grain-precision style-display-fg-max-precision impl/fine-grain-suffix style-display-fg-max-suffix})] - (impl/enrich-displayable-specific-gravity style options)))) + (impl/enrich-displayable-units options/specific-gravity style options)))) (defn enrich-display-color-min @@ -202,7 +203,7 @@ impl/fine-grain-target-units style-display-color-min-target-units impl/fine-grain-precision style-display-color-min-precision impl/fine-grain-suffix style-display-color-min-suffix})] - (impl/enrich-displayable-color style options)))) + (impl/enrich-displayable-units options/color style options)))) (defn enrich-display-color-max @@ -241,4 +242,4 @@ impl/fine-grain-target-units style-display-color-max-target-units impl/fine-grain-precision style-display-color-max-precision impl/fine-grain-suffix style-display-color-max-suffix})] - (impl/enrich-displayable-color style options)))) + (impl/enrich-displayable-units options/color style options)))) diff --git a/src/brewtility/enrich/waters.cljc b/src/brewtility/enrich/waters.cljc index 2c565ac..5cd1734 100644 --- a/src/brewtility/enrich/waters.cljc +++ b/src/brewtility/enrich/waters.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.recipes" "brewtility.enrich.styles" "brewtility.enrich.yeast"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-display-amount @@ -47,7 +48,7 @@ impl/fine-grain-target-units water-amount-target-units impl/fine-grain-precision water-amount-precision impl/fine-grain-suffix water-amount-suffix})] - (impl/enrich-displayable-volume water options)))) + (impl/enrich-displayable-units options/volume water options)))) (defn enrich-water @@ -84,7 +85,7 @@ (defn enrich-water-wrapper "An enricher pattern function to derive as many values from an [water record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. - + An option map may be passed as an optional second argument. The following keys are supported for controlling high-level behavior: @@ -115,7 +116,7 @@ (defn enrich-waters "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. - + An option map may be passed as an optional second argument. The following keys are supported for controlling high-level behavior: @@ -146,7 +147,7 @@ (defn enrich-waters-wrapper "An enricher pattern function to derive as many values from a collection of [water records](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/waters.cljc) as possible. - + An option map may be passed as an optional second argument. The following keys are supported for controlling high-level behavior: diff --git a/src/brewtility/enrich/yeasts.cljc b/src/brewtility/enrich/yeasts.cljc index b0f9dd4..f1bddb7 100644 --- a/src/brewtility/enrich/yeasts.cljc +++ b/src/brewtility/enrich/yeasts.cljc @@ -9,7 +9,8 @@ "brewtility.enrich.recipes" "brewtility.enrich.styles" "brewtility.enrich.waters"]} - (:require [brewtility.enrich.impl :as impl])) + (:require [brewtility.enrich.impl :as impl] + [brewtility.units.options :as options])) (defn enrich-amount-is-weight @@ -65,14 +66,14 @@ impl/fine-grain-precision yeast-amount-precision impl/fine-grain-suffix yeast-amount-suffix})] (if (:amount-is-weight yeast) - (impl/enrich-displayable-weight yeast options) - (impl/enrich-displayable-volume yeast options))))) + (impl/enrich-displayable-units options/weight yeast options) + (impl/enrich-displayable-units options/volume yeast options))))) (defn enrich-display-min-temperature "An enricher pattern function to render a human-readable display minimum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. If the `min-temperature` key is not present, the map will not be changed. - + An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: @@ -106,14 +107,14 @@ impl/fine-grain-target-units yeast-min-temperature-target-units impl/fine-grain-precision yeast-min-temperature-precision impl/fine-grain-suffix yeast-min-temperature-suffix})] - (impl/enrich-displayable-temperature yeast options)) + (impl/enrich-displayable-units options/temperature yeast options)) yeast))) (defn enrich-display-max-temperature "An enricher pattern function to render a human-readable display maximum-viable fermentation temperature of a [yeast](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) is in a given system. If the `max-temperature` key is not present, the map will not be changed. - + An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: @@ -147,16 +148,16 @@ impl/fine-grain-target-units yeast-max-temperature-target-units impl/fine-grain-precision yeast-max-temperature-precision impl/fine-grain-suffix yeast-max-temperature-suffix})] - (impl/enrich-displayable-temperature yeast options)) + (impl/enrich-displayable-units options/temperature yeast options)) yeast))) (defn enrich-yeast "An enricher pattern function to derive as many values from a [yeast record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. - + An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - + The following keys are supported for controlling high-level behavior: + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -168,7 +169,7 @@ - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - + - [[enrich-display-amount]] - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. @@ -200,10 +201,10 @@ (defn enrich-yeast-wrapper "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. - + An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - + The following keys are supported for controlling high-level behavior: + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -215,7 +216,7 @@ - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - + - [[enrich-display-amount]] - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. @@ -243,10 +244,10 @@ (defn enrich-yeasts "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. - + An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - + The following keys are supported for controlling high-level behavior: + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -258,7 +259,7 @@ - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - + - [[enrich-display-amount]] - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. @@ -286,10 +287,10 @@ (defn enrich-yeasts-wrapper "An enricher pattern function to derive as many values from a [yeast-wrapper record](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/yeasts.cljc) as possible. - + An option map may be passed as an optional second argument. - The following keys are supported for controlling high-level behavior: - + The following keys are supported for controlling high-level behavior: + - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -301,7 +302,7 @@ - `:full`: The full name of the selected unit. For example, `\"° Lovibond\"` for `:lovibond`. To support fine-grained control of behavior, this function also supports the following keys inherited from the other field-specific enrichers: - + - [[enrich-display-amount]] - `:yeast-amount-target-units`: The unit to convert the amount into. Supersedes `:system-of-measure`. - `yeast-amount-precision`: The number of significant decimal places to display. Supersedes `:precision`. diff --git a/src/brewtility/units/color.cljc b/src/brewtility/units/color.cljc index 71218f9..0c4bd05 100644 --- a/src/brewtility/units/color.cljc +++ b/src/brewtility/units/color.cljc @@ -1,9 +1,9 @@ (ns brewtility.units.color "A namespace for converting between different units of color. - + In the BeerXML spec, color is measured in different units in different contexts. This namespace provides a way to convert between SRM and other units of color. - + Currently, brewtility supports the following types of color: - [SRM](https://en.wikipedia.org/wiki/Standard_Reference_Method) - [EBC](https://en.wikipedia.org/wiki/European_Brewery_Convention) @@ -11,7 +11,8 @@ - [RGBa](https://en.wikipedia.org/wiki/RGBA_color_model)" {:added "2.0"} (:require [brewtility.precision :as precision] - [brewtility.units.options :as options])) + [brewtility.units.options :as options] + [clojure.set :as set])) (def measurements @@ -284,6 +285,11 @@ 40 srm-40}) +(def rgba-lookup-map + "A map of known RGBa color codes to their closest SRM value." + (set/map-invert srm-color-map)) + + (defn- lovibond->srm "Convert the color described in degrees `lovibond` to the equivalent SRM color." {:added "2.0"} @@ -322,13 +328,23 @@ (get srm-color-map srm-color))) +(defn- rgba->srm + "Given one of the known `rgba-string` color codes, return the closest SRM value." + {:added "2.1"} + [rgba-string] + (if-let [srm-value (get rgba-lookup-map rgba-string)] + srm-value + (throw (ex-info "Unsupported RGBa color value" + {:allowed-values (-> rgba-lookup-map keys set) + :color rgba-string})))) + + (def measurement->srm - "A map from color systems to the implementation function that converts to SRM. - - Note: RGBa is not included because it is not a color system, but a color representation." + "A map from color systems to the implementation function that converts to SRM." {options/ebc ebc->srm options/lovibond lovibond->srm - options/srm identity}) + options/srm identity + options/rgba rgba->srm}) (def srm->measurement @@ -348,7 +364,9 @@ [color-val source-system target-system] (if (and (contains? measurement->srm source-system) (contains? measurements target-system) - (number? color-val)) + (if (= source-system options/rgba) + (string? color-val) + (number? color-val))) (if (= source-system target-system) color-val (let [source->srm-fn (measurement->srm source-system) diff --git a/test/brewtility/enrich/fermentables_test.cljc b/test/brewtility/enrich/fermentables_test.cljc index a3992dd..a36bd7c 100644 --- a/test/brewtility/enrich/fermentables_test.cljc +++ b/test/brewtility/enrich/fermentables_test.cljc @@ -143,7 +143,7 @@ :yield 78.0 :supplier "Gnome Brew" :color 500.1 - :display-color "500.1°L" + :display-color "500.1 °L" :name "Black Barley" :moisture 5.0 :type "Grain" diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index f522210..599b427 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -43,141 +43,141 @@ (deftest ->displayable-color-test (testing "Ensure ->displayable-color supports its full suite of options." (is (= "2.955 ebc" - (sut/->displayable-color 1.5 options/srm options/ebc) - (sut/->displayable-color 1.5 options/srm options/ebc sut/default-display-options)) + (sut/->displayable-units options/color 1.5 options/srm options/ebc) + (sut/->displayable-units options/color 1.5 options/srm options/ebc sut/default-display-options)) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "3.0 ebc" - (sut/->displayable-color 1.5 options/srm options/ebc {options/precision 1}) - (sut/->displayable-color 1.5 options/srm options/ebc {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/color 1.5 options/srm options/ebc {options/precision 1}) + (sut/->displayable-units options/color 1.5 options/srm options/ebc {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "1.668 degrees lovibond" - (sut/->displayable-color 1.5 options/srm options/lovibond {options/suffix options/full}) - (sut/->displayable-color 1.5 options/srm options/lovibond {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/color 1.5 options/srm options/lovibond {options/suffix options/full}) + (sut/->displayable-units options/color 1.5 options/srm options/lovibond {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) (deftest ->displayable-pressure-test (testing "Ensure ->displayable-pressure supports its full suite of options" (is (= "0.103 bar" - (sut/->displayable-pressure 1.5 options/psi options/bar) - (sut/->displayable-pressure 1.5 options/psi options/bar sut/default-display-options)) + (sut/->displayable-units options/pressure 1.5 options/psi options/bar) + (sut/->displayable-units options/pressure 1.5 options/psi options/bar sut/default-display-options)) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "0.1 bar" - (sut/->displayable-pressure 1.5 options/psi options/bar {options/precision 1}) - (sut/->displayable-pressure 1.5 options/psi options/bar {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/pressure 1.5 options/psi options/bar {options/precision 1}) + (sut/->displayable-units options/pressure 1.5 options/psi options/bar {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "10.342 kilopascals" - (sut/->displayable-pressure 1.5 options/psi options/kilopascal {options/suffix options/full}) - (sut/->displayable-pressure 1.5 options/psi options/kilopascal {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/pressure 1.5 options/psi options/kilopascal {options/suffix options/full}) + (sut/->displayable-units options/pressure 1.5 options/psi options/kilopascal {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) (deftest ->displayable-specific-gravity-test (testing "Ensure ->displayable-specific-gravity supports its full suite of options" (is (= "1.5 sg" - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity) - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity sut/default-display-options)) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity sut/default-display-options)) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "1.5 sg" - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1}) - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1}) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "1.5 specific gravity" - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/suffix options/full}) - (sut/->displayable-specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/suffix options/full}) + (sut/->displayable-units options/specific-gravity 1.5 options/specific-gravity options/specific-gravity {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) (deftest ->displayable-temperature-test (testing "Ensure ->displayable-temperature supports its full suite of options" (is (= "318.75 k" - (sut/->displayable-temperature 45.6 options/c options/k) - (sut/->displayable-temperature 45.6 options/c options/k {options/precision 3 - options/suffix options/short})) + (sut/->displayable-units options/temperature 45.6 options/c options/k) + (sut/->displayable-units options/temperature 45.6 options/c options/k {options/precision 3 + options/suffix options/short})) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "318.8 k" - (sut/->displayable-temperature 45.6 options/c options/k {options/precision 1}) - (sut/->displayable-temperature 45.6 options/c options/k {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/temperature 45.6 options/c options/k {options/precision 1}) + (sut/->displayable-units options/temperature 45.6 options/c options/k {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "318.75 kelvin" - (sut/->displayable-temperature 45.6 options/c options/k {options/precision 3 - options/suffix options/full}) - (sut/->displayable-temperature 45.6 options/c options/k {options/suffix options/full})) + (sut/->displayable-units options/temperature 45.6 options/c options/k {options/precision 3 + options/suffix options/full}) + (sut/->displayable-units options/temperature 45.6 options/c options/k {options/suffix options/full})) "Conversion may override the default suffix"))) (deftest ->displayable-time-test (testing "Ensure ->displayable-time supports its full suite of options" (is (= "0.76 m" - (sut/->displayable-time 45.6 options/second options/minute) - (sut/->displayable-time 45.6 options/second options/minute {options/precision 3 - options/suffix options/short})) + (sut/->displayable-units options/time 45.6 options/second options/minute) + (sut/->displayable-units options/time 45.6 options/second options/minute {options/precision 3 + options/suffix options/short})) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "0.8 m" - (sut/->displayable-time 45.6 options/second options/minute {options/precision 1}) - (sut/->displayable-time 45.6 options/second options/minute {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/time 45.6 options/second options/minute {options/precision 1}) + (sut/->displayable-units options/time 45.6 options/second options/minute {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "0.76 minute" - (sut/->displayable-time 45.6 options/second options/minute {options/suffix options/full}) - (sut/->displayable-time 45.6 options/second options/minute {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/time 45.6 options/second options/minute {options/suffix options/full}) + (sut/->displayable-units options/time 45.6 options/second options/minute {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) (deftest ->displayable-volume-test (testing "Ensure ->displayable-volume supports its full suite of options" (is (= "5.678 l" - (sut/->displayable-volume 1.5 :american-gallon :liter) - (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 3 - options/suffix :short})) + (sut/->displayable-units options/volume 1.5 :american-gallon :liter) + (sut/->displayable-units options/volume 1.5 :american-gallon :liter {options/precision 3 + options/suffix :short})) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "5.7 l" - (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 1 - options/suffix :short})) + (sut/->displayable-units options/volume 1.5 :american-gallon :liter {options/precision 1 + options/suffix :short})) "Conversion may override the default precision") (is (= "5.678 liter" - (sut/->displayable-volume 1.5 :american-gallon :liter {options/precision 3 - options/suffix :full})) + (sut/->displayable-units options/volume 1.5 :american-gallon :liter {options/precision 3 + options/suffix :full})) "Conversion may override the default suffix")) (testing "Ensure ->displayable-volume supports its full suite of options with static keys" (is (= "5.678 l" - (sut/->displayable-volume 1.5 options/american-gallon options/liter) - (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision options/default-precision - options/suffix options/short})) + (sut/->displayable-units options/volume 1.5 options/american-gallon options/liter) + (sut/->displayable-units options/volume 1.5 options/american-gallon options/liter {options/precision options/default-precision + options/suffix options/short})) "Conversion defaults to 3 digits of precisions and shorthand unit names with static keys") (is (= "5.7 l" - (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/volume 1.5 options/american-gallon options/liter {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision with static keys") (is (= "5.678 liter" - (sut/->displayable-volume 1.5 options/american-gallon options/liter {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/volume 1.5 options/american-gallon options/liter {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix with static keys"))) (deftest ->displayable-weight-test (testing "Ensure ->displayable-weight supports its full suite of options" (is (= "0.053 oz" - (sut/->displayable-weight 1.5 options/gram options/ounce) - (sut/->displayable-weight 1.5 options/gram options/ounce sut/default-display-options)) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce sut/default-display-options)) "Conversion defaults to 3 digits of precisions and shorthand unit names") (is (= "0.1 oz" - (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 1}) - (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 1 - options/suffix options/short})) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce {options/precision 1}) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce {options/precision 1 + options/suffix options/short})) "Conversion may override the default precision") (is (= "0.053 ounce" - (sut/->displayable-weight 1.5 options/gram options/ounce {options/suffix options/full}) - (sut/->displayable-weight 1.5 options/gram options/ounce {options/precision 3 - options/suffix options/full})) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce {options/suffix options/full}) + (sut/->displayable-units options/weight 1.5 options/gram options/ounce {options/precision 3 + options/suffix options/full})) "Conversion may override the default suffix"))) @@ -499,9 +499,9 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable color enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-color-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-color-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/color valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/lovibond @@ -509,22 +509,22 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-color-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/color valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-color-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-pressure-opts-test @@ -532,35 +532,35 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable pressure enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-pressure-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-pressure-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/pressure valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-pressure-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/psi options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-pressure-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/pressure valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-pressure-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/pressure (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-specific-gravity-opts-test @@ -568,35 +568,35 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable specific gravity enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-specific-gravity-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-specific-gravity-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/specific-gravity valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-specific-gravity-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/specific-gravity options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-specific-gravity-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/specific-gravity valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-specific-gravity-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/specific-gravity (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-temperature-opts-test @@ -604,35 +604,35 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable temperature enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-temperature-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/temperature valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/c options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-temperature-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/temperature valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-temperature-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/temperature (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-time-opts-test @@ -640,35 +640,35 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable time enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-time-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-time-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/time valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/minute options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-time-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/time valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-time-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/time (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-volume-opts-test @@ -676,35 +676,35 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable volume enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-volume-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-volume-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/volume valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/teaspoon options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-volume-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/volume valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-volume-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/volume (assoc valid-opts options/suffix :fake)))))))) (deftest parse-enrich-displayable-weight-opts-test @@ -712,138 +712,138 @@ options/system-of-measure options/metric options/precision 2 options/suffix options/full} - error-regex #"Invalid displayable weight enrichment options"] + error-regex #"Invalid enrichment options for ->displayable-units:"] (testing "Ensure parse-enrich-displayable-weight-opts returns valid opts" - (is (= valid-opts (sut/parse-enrich-displayable-weight-opts valid-opts)) + (is (= valid-opts (sut/parse-enrich-displayable-units-opts options/weight valid-opts)) "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/pound options/system-of-measure options/metric options/precision 2 options/suffix options/full}] - (is (= valid-opts-w-keys (sut/parse-enrich-displayable-weight-opts valid-opts-w-keys)) + (is (= valid-opts-w-keys (sut/parse-enrich-displayable-units-opts options/weight valid-opts-w-keys)) "Valid opts are returned unchanged with static keys"))) (testing "Missing any option throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts :target-units))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/system-of-measure))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/system-of-measure))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/precision))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/precision))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/suffix))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (dissoc valid-opts options/suffix)))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts :target-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/system-of-measure))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/system-of-measure))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/precision))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/precision))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/suffix))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (dissoc valid-opts options/suffix)))))) (testing "An invalid selection for any require value throws an error" - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts :target-units :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/system-of-measure :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/precision :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/precision :fake))))) - #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/suffix :fake))))) - #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-weight-opts (assoc valid-opts options/suffix :fake)))))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts :target-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/system-of-measure :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/system-of-measure :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/precision :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/precision :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/suffix :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/weight (assoc valid-opts options/suffix :fake)))))))) (deftest enrich-displayable-color-test (testing "Validate displayable color enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-color base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/color base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "0.595 srm")] - (is (= result-map (sut/enrich-displayable-color base-map {:display-key :display - :value-key :value - :source-units options/lovibond - :target-units options/srm}))))))) + (is (= result-map (sut/enrich-displayable-units options/color base-map {:display-key :display + :value-key :value + :source-units options/lovibond + :target-units options/srm}))))))) (deftest enrich-displayable-pressure-test (testing "Validate displayable pressure enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-pressure base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/pressure base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1000.0 pa")] - (is (= result-map (sut/enrich-displayable-pressure base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/pascal}))))))) + (is (= result-map (sut/enrich-displayable-units options/pressure base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/pascal}))))))) (deftest enrich-displayable-specific-gravity-test (testing "Validate displayable specific-gravity enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-specific-gravity base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/specific-gravity base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1.0 sg")] - (is (= result-map (sut/enrich-displayable-specific-gravity base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/specific-gravity}))))))) + (is (= result-map (sut/enrich-displayable-units options/specific-gravity base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/specific-gravity}))))))) (deftest enrich-displayable-temperature-test (testing "Validate displayable temperature enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-temperature base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/temperature base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "274.15 k")] - (is (= result-map (sut/enrich-displayable-temperature base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/k}))))))) + (is (= result-map (sut/enrich-displayable-units options/temperature base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/k}))))))) (deftest enrich-displayable-time-test (testing "Validate displayable time enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-time base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/time base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1.0 m")] - (is (= result-map (sut/enrich-displayable-time base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/minute}))))))) + (is (= result-map (sut/enrich-displayable-units options/time base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/minute}))))))) (deftest enrich-displayable-volume-test (testing "Validate displayable volume enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-volume base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/volume base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "202.884 tsp")] - (is (= result-map (sut/enrich-displayable-volume base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/teaspoon}))))))) + (is (= result-map (sut/enrich-displayable-units options/volume base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/teaspoon}))))))) (deftest enrich-displayable-weight-test (testing "Validate displayable weight enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-weight base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/weight base-map {:display-key :hello + :value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "2.205 lb")] - (is (= result-map (sut/enrich-displayable-weight base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/pound}))))))) + (is (= result-map (sut/enrich-displayable-units options/weight base-map {:display-key :display + :value-key :value + :fine-grain-target-units options/pound}))))))) diff --git a/test/brewtility/units/color_test.cljc b/test/brewtility/units/color_test.cljc index de39d4e..e4f7be4 100644 --- a/test/brewtility/units/color_test.cljc +++ b/test/brewtility/units/color_test.cljc @@ -56,6 +56,53 @@ (is (= sut/srm-40 (sut/convert 41 options/srm options/rgba))))) +(deftest rgba->srm-test + (testing "RGBA lookup behaves as expected" + (is (= 1 (sut/convert sut/srm-1 options/rgba options/srm))) + (is (= 2 (sut/convert sut/srm-2 options/rgba options/srm))) + (is (= 3 (sut/convert sut/srm-3 options/rgba options/srm))) + (is (= 4 (sut/convert sut/srm-4 options/rgba options/srm))) + (is (= 5 (sut/convert sut/srm-5 options/rgba options/srm))) + (is (= 6 (sut/convert sut/srm-6 options/rgba options/srm))) + (is (= 7 (sut/convert sut/srm-7 options/rgba options/srm))) + (is (= 8 (sut/convert sut/srm-8 options/rgba options/srm))) + (is (= 9 (sut/convert sut/srm-9 options/rgba options/srm))) + (is (= 10 (sut/convert sut/srm-10 options/rgba options/srm))) + (is (= 11 (sut/convert sut/srm-11 options/rgba options/srm))) + (is (= 12 (sut/convert sut/srm-12 options/rgba options/srm))) + (is (= 13 (sut/convert sut/srm-13 options/rgba options/srm))) + (is (= 14 (sut/convert sut/srm-14 options/rgba options/srm))) + (is (= 15 (sut/convert sut/srm-15 options/rgba options/srm))) + (is (= 16 (sut/convert sut/srm-16 options/rgba options/srm))) + (is (= 17 (sut/convert sut/srm-17 options/rgba options/srm))) + (is (= 18 (sut/convert sut/srm-18 options/rgba options/srm))) + (is (= 19 (sut/convert sut/srm-19 options/rgba options/srm))) + (is (= 20 (sut/convert sut/srm-20 options/rgba options/srm))) + (is (= 21 (sut/convert sut/srm-21 options/rgba options/srm))) + (is (= 22 (sut/convert sut/srm-22 options/rgba options/srm))) + (is (= 23 (sut/convert sut/srm-23 options/rgba options/srm))) + (is (= 24 (sut/convert sut/srm-24 options/rgba options/srm))) + (is (= 25 (sut/convert sut/srm-25 options/rgba options/srm))) + (is (= 26 (sut/convert sut/srm-26 options/rgba options/srm))) + (is (= 27 (sut/convert sut/srm-27 options/rgba options/srm))) + (is (= 28 (sut/convert sut/srm-28 options/rgba options/srm))) + (is (= 29 (sut/convert sut/srm-29 options/rgba options/srm))) + (is (= 30 (sut/convert sut/srm-30 options/rgba options/srm))) + (is (= 31 (sut/convert sut/srm-31 options/rgba options/srm))) + (is (= 32 (sut/convert sut/srm-32 options/rgba options/srm))) + (is (= 33 (sut/convert sut/srm-33 options/rgba options/srm))) + (is (= 34 (sut/convert sut/srm-34 options/rgba options/srm))) + (is (= 35 (sut/convert sut/srm-35 options/rgba options/srm))) + (is (= 36 (sut/convert sut/srm-36 options/rgba options/srm))) + (is (= 37 (sut/convert sut/srm-37 options/rgba options/srm))) + (is (= 38 (sut/convert sut/srm-38 options/rgba options/srm))) + (is (= 39 (sut/convert sut/srm-39 options/rgba options/srm))) + (is (= 40 (sut/convert sut/srm-40 options/rgba options/srm)))) + (testing "Invalid RGBa strings throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported RGBa color value" (sut/convert "invalid" options/rgba options/srm)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported RGBa color value" (sut/convert "invalid" options/rgba options/srm)))))) + + (deftest lovibond->rgba-test (testing "lovibond -> SRM -> rgba lookup behaves as expected" (is (= sut/srm-13 (sut/convert 10.16 options/lovibond options/rgba))) From 8e00e014075cb9bd3c2ad1b6ac28ac1ec2b466b7 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sat, 2 Mar 2024 20:55:22 +0000 Subject: [PATCH 33/44] Fix up linter --- .github/workflows/format.yml | 4 ---- src/brewtility/enrich/fermentables.cljc | 1 - 2 files changed, 5 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 9d165ee..b63cbf7 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -35,10 +35,6 @@ jobs: run: | cljstyle fix --report --report-timing --verbose - - name: Sort Namespaces - run: | - lein ns-sort - - name: Render Changelog run: | lein sealog render diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index 692feb4..a48981b 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -11,7 +11,6 @@ "brewtility.enrich.yeast"]} (:require [brewtility.enrich.impl :as impl] [brewtility.predicates.fermentables :as fermentables.predicate] - [brewtility.units.color :as color] [brewtility.units.options :as options])) From f754859a5ba67b2be897b3147d04d83aaaa7b7cb Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 17:17:04 +0000 Subject: [PATCH 34/44] WIP --- doc/api/units.md | 4 + doc/cljdoc.edn | 1 - src/brewtility/calculations.cljc | 4 +- src/brewtility/enrich/fermentables.cljc | 22 +-- src/brewtility/enrich/impl.cljc | 84 ++++++++---- src/brewtility/predicates/equipment.cljc | 9 +- src/brewtility/predicates/fermentables.cljc | 11 +- src/brewtility/predicates/hops.cljc | 12 +- src/brewtility/predicates/mash.cljc | 11 +- src/brewtility/predicates/options.cljc | 15 ++ src/brewtility/predicates/recipes.cljc | 11 +- src/brewtility/predicates/waters.cljc | 27 ++-- src/brewtility/units.cljc | 53 +++++--- src/brewtility/units/options.cljc | 128 +++++++++--------- test/brewtility/enrich/impl_test.cljc | 97 ++++++++----- .../predicates/fermentables_test.cljc | 8 +- 16 files changed, 299 insertions(+), 198 deletions(-) create mode 100644 src/brewtility/predicates/options.cljc diff --git a/doc/api/units.md b/doc/api/units.md index a6a3e05..b62953e 100644 --- a/doc/api/units.md +++ b/doc/api/units.md @@ -30,6 +30,10 @@ This provides a consistent interface to every system of measure, unit type, and (units/convert units/volume 20 :teaspoon :liter) ;; => 0.099 +;; You can also round the conversion to a specified precision +(units/convert units/volume 20 :teaspoon :liter {:precision 1}) +;; => 0.1 + ;; If you only plan on dealing with volumes, ;; then you can import the `brewtility.units.volume` namespace (volume/convert 9.99209 :imperial-pint :american-pint) diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index ec89b11..9c18375 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -7,7 +7,6 @@ ["Security Policy" {:file "SECURITY.md"}]] ["Functionality" {} ["Calculations" {:file "doc/api/calculations.md"}] - ["Color" {:file "doc/api/color.md"}] ["Precision" {:file "doc/api/precision.md"}] ["Predicates" {:file "doc/api/predicates.md"}] ["Units of Measure" {:file "doc/api/units.md"}] diff --git a/src/brewtility/calculations.cljc b/src/brewtility/calculations.cljc index 0d2f372..783ecc3 100644 --- a/src/brewtility/calculations.cljc +++ b/src/brewtility/calculations.cljc @@ -19,11 +19,11 @@ (if (and (number? amount) (number? color)) (let [is-not-grain? (not (fermentables/grain? fermentable)) - ; MCU is calculated against pounds + ;; MCU is calculated against pounds kg->lbs (fn [w] (weight/convert w options/kilogram options/pound))] (cond-> fermentable true (update :amount kg->lbs) - ; Grain color is in Lovibond, all other fermentables use SRM + ;; Grain color is in Lovibond, all other fermentables use SRM is-not-grain? (update :color #(color/convert % options/srm options/lovibond)))) (throw (ex-info "Cannot calculate color with non-numeric values" {:amount amount :color color})))) diff --git a/src/brewtility/enrich/fermentables.cljc b/src/brewtility/enrich/fermentables.cljc index a48981b..446476b 100644 --- a/src/brewtility/enrich/fermentables.cljc +++ b/src/brewtility/enrich/fermentables.cljc @@ -38,8 +38,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" @@ -63,8 +62,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" @@ -88,8 +86,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" @@ -113,8 +110,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" @@ -138,8 +134,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/grain?" "brewtility.predicates.fermentables/adjunct?" @@ -163,8 +158,7 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "2.1" :see-also ["brewtility.predicates.fermentables/extract?" "enrich-fermentable" @@ -269,7 +263,6 @@ The following keys are supported for controlling high-level behavior: - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -328,7 +321,6 @@ The following keys are supported for controlling high-level behavior: - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -378,7 +370,6 @@ The following keys are supported for controlling high-level behavior: - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. @@ -428,7 +419,6 @@ The following keys are supported for controlling high-level behavior: - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false. - `:system-of-measure`: The unit system of measure to convert the amount into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 3511505..a7af493 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -5,7 +5,8 @@ {:no-doc true :added "2.1" :implementation-only true} - (:require [brewtility.units :as units] + (:require [brewtility.precision :as precision] + [brewtility.units :as units] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -23,32 +24,40 @@ (def value-key - "The key to source data from in `->displayable` functions" + "The key to source data from in `enrich-displayable-*` functions" :value-key) +(def low-value-key + "The key to source data from in `enrich-displayable-*` functions for the lower end of the range" + :low-value-key) + +(def high-value-key + "The key to source data from in `enrich-displayable-*` functions for the higher end of the range" + :high-value-key) + (def display-key - "The key to store displayable data in in `->displayable` functions" + "The key to store displayable data in in `-enrich-displayable-*` functions" :display-key) (def fine-grain-target-units - "The target units to use for fine-grain toggling of displayable units in `->displayable` functions" + "The target units to use for fine-grain toggling of displayable units in `enrich-displayable-*` functions" :fine-grain-target-units) (def fine-grain-precision - "The suffix to use for fine-grain setting of precision in `->displayable` functions" + "The suffix to use for fine-grain setting of precision in `-enrich-displayable-*` functions" :fine-grain-precision) (def fine-grain-suffix - "The suffix to use for fine-grain setting of precision in `->displayable` functions" + "The suffix to use for fine-grain setting of precision in `enrich-displayable-*` functions" :fine-grain-suffix) (def default-color-by-system - "The default color to use for each system in `->displayable` functions." + "The default color to use for each system in `enrich-displayable-*` functions." {options/imperial options/srm options/metric options/srm options/us-customary options/srm @@ -56,7 +65,7 @@ (def default-pressure-by-system - "The default pressure to use for each system in `->displayable` functions." + "The default pressure to use for each system in `enrich-displayable-*` functions." {options/imperial options/psi options/metric options/kilopascal options/us-customary options/psi @@ -64,7 +73,7 @@ (def default-specific-gravity-by-system - "The default specific gravity to use for each system in `->displayable` functions." + "The default specific gravity to use for each system in `enrich-displayable-*` functions." {options/imperial options/specific-gravity options/metric options/specific-gravity options/us-customary options/specific-gravity @@ -72,7 +81,7 @@ (def default-temperature-by-system - "The default temperature to use for each system in `->displayable` functions." + "The default temperature to use for each system in `enrich-displayable-*` functions." {options/imperial options/fahrenheit options/metric options/celsius options/us-customary options/fahrenheit @@ -80,7 +89,7 @@ (def default-time-by-system - "The default time to use for each system in `->displayable` functions." + "The default time to use for each system in `enrich-displayable-*` functions." {options/imperial options/minute options/metric options/minute options/us-customary options/minute @@ -88,7 +97,7 @@ (def default-volume-by-system - "The default volume to use for each system in `->displayable` functions." + "The default volume to use for each system in `enrich-displayable-*` functions." {options/imperial options/imperial-gallon options/metric options/litre options/us-customary options/american-gallon @@ -96,7 +105,7 @@ (def default-weight-by-system - "The default weight to use for each system in `->displayable` functions." + "The default weight to use for each system in `enrich-displayable-*` functions." {options/imperial options/pound options/metric options/kilogram options/us-customary options/pound @@ -233,7 +242,8 @@ ;; Enricher argument validation functions (defn valid-unit-for-measurement-type? - "TODO: Fill me in" + "A functions that confirms if a given `unit` is valid for a given `measurement-type`. + If the `unit` is not valid, a Java Exception or Javascript Error is thrown with information on the invalid options." {:added "2.1" :no-doc false} [measurement-type unit] @@ -305,7 +315,21 @@ (defn enrich-displayable-units - "TODO: Fill me in" + "A function to enrich a `source-data` map with a displayable value for a given `measurement-type`. + This function will convert the `source-value` from `source-units` to `target-units` and store the result in `display-key`. + If the `source-value` is not present, the `source-data` is returned unmodified. + The function will default to the following display options: + + - `system-of-measure` : `:us-customary` + - `suffix` : `:short` + - `precision` : `3` + - `source-units` : The BeerXML default system of measure for the given `measurement-type` (e.g. `:kilogram` for `:weight`) + + Customization of function behavior is handled by the following keys in the `opts` map, and will always take precedence over defaults: + + - `fine-grain-precsion` : The precision to use for this displayable value. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field + - `fine-grain-suffix` : The suffix to use for this displayable value. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field + - `fine-grain-target-units` : The target units to use for this displayable value. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field" {:added "2.1" :no-doc true} [measurement-type @@ -336,7 +360,21 @@ (defn enrich-displayable-range - "TODO: Fill me in" + "A function to enrich a `source-data` map with a displayable range for a given `measurement-type`. + This function will convert the `low-source-value` and `high-source-value` from `source-units` to `target-units` and store the result in `display-key`. + If the `source-value` is not present, the `source-data` is returned unmodified. + The function will default to the following display options: + + - `system-of-measure` : `:us-customary` + - `suffix` : `:short` + - `precision` : `3` + - `source-units` : The BeerXML default system of measure for the given `measurement-type` (e.g. `:kilogram` for `:weight`) + + Customization of function behavior is handled by the following keys in the `opts` map, and will always take precedence over defaults: + + - `fine-grain-precsion` : The precision to use for this displayable range. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field + - `fine-grain-suffix` : The suffix to use for this displayable range. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field + - `fine-grain-target-units` : The target units to use for this displayable range. Enricher functions control their behavior off of uniquely named keys, so behavior can be customized per field" {:added "2.1" :no-doc true :see-also ["enrich-displayable-units"]} @@ -356,13 +394,13 @@ precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) opts (parse-enrich-displayable-units-opts - measurement-type - {:target-units target-units - :source-units source-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix}) - converted-low-value (units/convert measurement-type low-source-value source-units target-units) + measurement-type + {:target-units target-units + :source-units source-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix}) + converted-low-value (units/convert measurement-type low-source-value source-units target-units {options/precision precision}) displayable-high-value (->displayable-units measurement-type high-source-value source-units target-units opts) displayable-range (str converted-low-value " - " displayable-high-value)] (assoc source-data display-key displayable-range)) diff --git a/src/brewtility/predicates/equipment.cljc b/src/brewtility/predicates/equipment.cljc index ddddea4..193a469 100644 --- a/src/brewtility/predicates/equipment.cljc +++ b/src/brewtility/predicates/equipment.cljc @@ -16,7 +16,8 @@ In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the :calc-boil-volume field is not present, this function will explicitly return false." {:added "1.5"} - [equipment] - (if (contains? equipment :calc-boil-volume) - (:calc-boil-volume equipment) - false)) + ([equipment] (calculated-boil-volume? equipment {})) ; Added to match the arity of the other predicate functions + ([equipment _opts] + (if (contains? equipment :calc-boil-volume) + (:calc-boil-volume equipment) + false))) diff --git a/src/brewtility/predicates/fermentables.cljc b/src/brewtility/predicates/fermentables.cljc index 82ca517..2c4074d 100644 --- a/src/brewtility/predicates/fermentables.cljc +++ b/src/brewtility/predicates/fermentables.cljc @@ -19,10 +19,13 @@ Therefore, if the :add-after-boil field is not present, this function will explicitly return false." {:added "1.5"} - [fermentable] - (if (contains? fermentable :add-after-boil) - (:add-after-boil fermentable) - false)) + ([fermentable] (add-after-boil? fermentable {})) + ;; Added to match the arity of the other predicate functions + + ([fermentable _opts] + (if (contains? fermentable :add-after-boil) + (:add-after-boil fermentable) + false))) (defn grain? diff --git a/src/brewtility/predicates/hops.cljc b/src/brewtility/predicates/hops.cljc index 50a73be..617ef1a 100644 --- a/src/brewtility/predicates/hops.cljc +++ b/src/brewtility/predicates/hops.cljc @@ -148,8 +148,7 @@ "A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was added for both bittering and aroma. An option map can be passed to this function as an optional second parameter. Supported keys are: - - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:type` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:type` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "1.5" :see-also ["aroma-type?" "bittering?" @@ -169,8 +168,7 @@ "A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed pellet. An option map can be passed to this function as an optional second parameter. Supported keys are: - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "1.5" :see-also ["plug?" "leaf?" @@ -185,8 +183,7 @@ "A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a compressed whole-hop plug. An option map can be passed to this function as an optional second parameter. Supported keys are: - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "1.5" :see-also ["pellet?" "leaf?" @@ -201,8 +198,7 @@ "A predicate function to determine if a [hop](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/hops.cljc) was a whole hop cone. An option map can be passed to this function as an optional second parameter. Supported keys are: - - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false. - - `:coerce` - If the `:form` field should be coerced to a string for comparison. Default is false." + - `:uppercase?` - If the string comparison for the `:form` should be cast to UPPERCASE instead of lowercase. Default is false." {:added "1.5" :see-also ["pellet?" "plug?" diff --git a/src/brewtility/predicates/mash.cljc b/src/brewtility/predicates/mash.cljc index d937eab..2408f21 100644 --- a/src/brewtility/predicates/mash.cljc +++ b/src/brewtility/predicates/mash.cljc @@ -18,10 +18,13 @@ In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the `:equip-adjust` field is not present, this function will return false." {:added "1.5"} - [mash] - (if (contains? mash :equip-adjust) - (:equip-adjust mash) - false)) + ([mash] (adjust-for-equipment? mash {})) + ;; Added to match the arity of the other predicate functions + + ([mash _opts] + (if (contains? mash :equip-adjust) + (:equip-adjust mash) + false))) (defn infusion? diff --git a/src/brewtility/predicates/options.cljc b/src/brewtility/predicates/options.cljc new file mode 100644 index 0000000..036c564 --- /dev/null +++ b/src/brewtility/predicates/options.cljc @@ -0,0 +1,15 @@ +(ns brewtility.predicates.options + "A namespace of static symbolic keywords and values used in the option maps throughout brewtility. + + Implemented as part of the Symbolic Keyword pattern." + {:added "2.1"}) + + +;; Option keys + +(def uppercase? + "A keyword used to determine if a string comparison should be cast to UPPERCASE instead of lowercase. + + This option is inherited from the functions in `com.wallbrew.spoon.string`" + :uppercase?) + diff --git a/src/brewtility/predicates/recipes.cljc b/src/brewtility/predicates/recipes.cljc index 709ef5d..382b611 100644 --- a/src/brewtility/predicates/recipes.cljc +++ b/src/brewtility/predicates/recipes.cljc @@ -18,10 +18,13 @@ In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the :forced-carbonation field is not present, this function will explicitly return false." {:added "1.5"} - [recipe] - (if (contains? recipe :forced-carbonation) - (:forced-carbonation recipe) - false)) + ([recipe] (forced-carbonation? recipe {})) + ;; Added to match the arity of the other predicate functions + + ([recipe _opts] + (if (contains? recipe :forced-carbonation) + (:forced-carbonation recipe) + false))) (defn extract? diff --git a/src/brewtility/predicates/waters.cljc b/src/brewtility/predicates/waters.cljc index 71a5892..da5cb33 100644 --- a/src/brewtility/predicates/waters.cljc +++ b/src/brewtility/predicates/waters.cljc @@ -17,9 +17,12 @@ {:added "1.5" :see-also ["alkaline?" "neutral?"]} - [water] - (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine acidity.")] - (> 7 ph))) + ([water] (acidic? water {})) + ;; Added to match the arity of the other predicate functions + + ([water _opts] + (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine acidity.")] + (> 7 ph)))) (defn alkaline? @@ -27,9 +30,12 @@ {:added "1.5" :see-also ["acidic?" "neutral?"]} - [water] - (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine alkalinity.")] - (< 7 ph))) + ([water] (alkaline? water {})) + ;; Added to match the arity of the other predicate functions + + ([water _opts] + (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine alkalinity.")] + (< 7 ph)))) (defn neutral? @@ -37,6 +43,9 @@ {:added "1.5" :see-also ["acidic?" "alkaline?"]} - [water] - (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine ph neutrality.")] - (== 7 ph))) + ([water] (neutral? water {})) + ;; Added to match the arity of the other predicate functions + + ([water _opts] + (let [ph (impl/fetch-or-throw! water :ph "Water `:ph` is required to determine ph neutrality.")] + (== 7 ph)))) diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 76b1735..4561f0d 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -1,8 +1,8 @@ (ns brewtility.units "Namespace for converting between different units of measure. - + Currently, brewtility supports the following types of measurements: - + - [Color](https://en.wikipedia.org/wiki/Beer_measurement#Colour) - [Pressure](https://en.wikipedia.org/wiki/Pressure) - [Specific Gravity](https://en.wikipedia.org/wiki/Relative_density) @@ -10,16 +10,17 @@ - [Time](https://en.wikipedia.org/wiki/Time) - [Volume](https://en.wikipedia.org/wiki/Volume) - [Weight](https://en.wikipedia.org/wiki/Mass) - + These types of measurement cover four systems of measure: - + - [The British Imperial System](https://en.wikipedia.org/wiki/Imperial_units) - [The Metric System](https://en.wikipedia.org/wiki/Metric_system) - [The International System](https://en.wikipedia.org/wiki/International_System_of_Units) - [The US Customary Scale](https://en.wikipedia.org/wiki/United_States_customary_units)" {:added "1.0" :changed "2.0"} - (:require [brewtility.units.color :as color] + (:require [brewtility.precision :as precision] + [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] [brewtility.units.specific-gravity :as specific-gravity] @@ -31,15 +32,18 @@ (defn convert "Given a `measurement` in `source-units`, convert it to the `target-units` in a given `measurement-type`. - + For example: - + ```clj (convert :weight 1.5 :kg :lb) ;; => 3.31 ``` - + Supported values for `source-units` and `target-units` are enumerated in each unit system namespace. - This function will throw an exception if unsupported unit values are passed." + This function will throw an exception if unsupported unit values are passed. + + This function accepts an option map as an optional fourth argument. The following options are available: + - `precision`: The number of decimal places to round to. Defaults to the precision of the converted value." {:added "2.0" :see-also ["brewtility.units.color/convert" "brewtility.units.pressure/convert" @@ -48,19 +52,24 @@ "brewtility.units.time/convert" "brewtility.units.volume/convert" "brewtility.units.weight/convert"]} - [measurement-type measurement source-units target-units] - (case measurement-type - :color (color/convert measurement source-units target-units) - :pressure (pressure/convert measurement source-units target-units) - :specific-gravity (specific-gravity/convert measurement source-units target-units) - :temperature (temperature/convert measurement source-units target-units) - :time (time/convert measurement source-units target-units) - :volume (volume/convert measurement source-units target-units) - :weight (weight/convert measurement source-units target-units) - (throw (ex-info "Unsupported unit system" - {:measurement-type measurement-type - :allowed-values options/measurement-types - :measurement measurement})))) + ([measurement-type measurement source-units target-units] + (convert measurement-type measurement source-units target-units {})) + ([measurement-type measurement source-units target-units {:keys [precision]}] + (let [converted-value (case measurement-type + :color (color/convert measurement source-units target-units) + :pressure (pressure/convert measurement source-units target-units) + :specific-gravity (specific-gravity/convert measurement source-units target-units) + :temperature (temperature/convert measurement source-units target-units) + :time (time/convert measurement source-units target-units) + :volume (volume/convert measurement source-units target-units) + :weight (weight/convert measurement source-units target-units) + (throw (ex-info "Unsupported unit system" + {:measurement-type measurement-type + :allowed-values options/measurement-types + :measurement measurement})))] + (if precision + (precision/->precision converted-value precision) + converted-value)))) (defn display diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 0e5a9b1..6596a26 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -1,6 +1,6 @@ (ns brewtility.units.options "A namespace of static symbolic keywords and values used in the option maps throughout brewtility. - + Implemented as part of the Symbolic Keyword pattern." {:added "2.0"} (:refer-clojure :exclude [second short time])) @@ -20,7 +20,7 @@ (def system-of-measure "The system of measure used in the recipe or for a given unit. - + Commonly used with `brewtility.units` and in argument/option maps. Brewility supports the following systems of measure: - [British imperial](https://en.wikipedia.org/wiki/Imperial_units) @@ -35,7 +35,7 @@ (def imperial "The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :imperial) @@ -45,7 +45,7 @@ (def metric "The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :metric) @@ -55,7 +55,7 @@ (def us-customary "The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - + Commonly used with `brewtility.units` and in argument/option maps.." :us) @@ -65,14 +65,14 @@ (def international-system "The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :si) (def systems-of-measure "The set of supported measurement systems" - #{imperial metric us-customary international-system}) + #{imperial international-system metric us-customary}) ;; Enricher Setting Keys @@ -80,14 +80,14 @@ (def precision "The number of decimal places to which a value is rounded. - + Commonly used with `brewtility.units` and in argument/option maps." :precision) (def suffix "The type of suffix to add on to displayed units of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Brewility supports the following suffix types: - `:short` - A short suffix. (e.g. \"tsp\" instead of \"teaspoon\") @@ -96,9 +96,9 @@ (def short - "A short suffix. + "A short suffix. (e.g. \"tsp\" instead of \"teaspoon\") - + Commonly used with `brewtility.units` and in argument/option maps." :short) @@ -106,7 +106,7 @@ (def full "The full name as a suffix. (e.g. \"teaspoon\") - + Commonly used with `brewtility.units` and in argument/option maps." :full) @@ -118,7 +118,7 @@ (def color "The color systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.color` and in argument/option maps. Brewility supports the following color systems: - [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) @@ -130,7 +130,7 @@ (def pressure "The pressure systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.pressure` and in argument/option maps. Currently, brewtility supports the following types of pressure: - [pascal](https://en.wikipedia.org/wiki/Pascal_(unit)#Multiples_and_submultiples) @@ -144,7 +144,7 @@ (def specific-gravity "The specific gravity systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.specific-gravity` and in argument/option maps. Currently, brewtility supports the following types of specific gravity: Currently, brewtility supports the following types of specific gravity: @@ -154,7 +154,7 @@ (def temperature "The temperature systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.temperature` and in argument/option maps. Currently, brewtility supports the following types of temperature: - [celsius](https://en.wikipedia.org/wiki/Celsius) @@ -165,7 +165,7 @@ (def time "The time systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.time` and in argument/option maps. Currently, brewtility supports the following types of time measurements: - [microsecond](https://en.wikipedia.org/wiki/Microsecond) @@ -181,7 +181,7 @@ (def volume "The volume systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.volume` and in argument/option maps. Currently, brewtility supports the following types of volume: - [american-fluid-ounce](https://en.wikipedia.org/wiki/Fluid_ounce) @@ -204,7 +204,7 @@ (def weight "The weight systems used in the recipe or for a given unit. - + Commonly used with `brewtility.units.weight` and in argument/option maps. Currently, brewtility supports the following types of weight: - [gram](https://en.wikipedia.org/wiki/Gram) @@ -230,28 +230,28 @@ (def srm "The [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) color system. - + Commonly used with `brewtility.units.color` and in argument/option maps." :srm) (def ebc "The [European Brewery Convention](https://en.wikipedia.org/wiki/European_Brewery_Convention) color system. - + Commonly used with `brewtility.units.color` and in argument/option maps." :ebc) (def lovibond "The [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) color system. - + Commonly used with `brewtility.units.color` and in argument/option maps." :lovibond) (def rgba "The [RGBA](https://en.wikipedia.org/wiki/RGBA_color_space) color system. - + Commonly used with `brewtility.units.color` and in argument/option maps." :rgba) @@ -260,70 +260,70 @@ (def american-fluid-ounce "The [American fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#American_fluid_ounce) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :american-fluid-ounce) (def american-gallon "The [American gallon](https://en.wikipedia.org/wiki/Gallon#Us_liquid_gallon) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :american-gallon) (def american-pint "The [American pint](https://en.wikipedia.org/wiki/Pint#US_liquid_pint) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :american-pint) (def american-quart "The [American quart](https://en.wikipedia.org/wiki/Quart#US_liquid_quart) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :american-quart) (def cup "The [cup](https://en.wikipedia.org/wiki/Cup_(unit)) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :cup) (def imperial-fluid-ounce "The [Imperial fluid ounce](https://en.wikipedia.org/wiki/Fluid_ounce#Imperial_fluid_ounce) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :imperial-fluid-ounce) (def imperial-gallon "The [Imperial gallon](https://en.wikipedia.org/wiki/Gallon#Imperial_gallon) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :imperial-gallon) (def imperial-pint "The [Imperial pint](https://en.wikipedia.org/wiki/Pint#Imperial_pint) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :imperial-pint) (def imperial-quart "The [Imperial quart](https://en.wikipedia.org/wiki/Quart#Imperial_quart) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :imperial-quart) (def liter "The [liter](https://en.wikipedia.org/wiki/Liter) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." :liter) @@ -331,7 +331,7 @@ (def litre "The [liter](https://en.wikipedia.org/wiki/Litre) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: Both `litre` and `liter` are valid keys throughout brewtility to support regional spelling." :litre) @@ -339,7 +339,7 @@ (def milliliter "The [milliliter](https://en.wikipedia.org/wiki/Milliliter) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." :milliliter) @@ -347,7 +347,7 @@ (def millilitre "The [milliliter](https://en.wikipedia.org/wiki/Millilitre) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: Both `millilitre` and `milliliter` are valid keys throughout brewtility to support regional spelling." :millilitre) @@ -355,14 +355,14 @@ (def teaspoon "The [teaspoon](https://en.wikipedia.org/wiki/Teaspoon) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :teaspoon) (def tablespoon "The [tablespoon](https://en.wikipedia.org/wiki/Tablespoon) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :tablespoon) @@ -371,35 +371,35 @@ (def gram "The [gram](https://en.wikipedia.org/wiki/Gram) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :gram) (def kilogram "The [kilogram](https://en.wikipedia.org/wiki/Kilogram) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :kilogram) (def milligram "The [milligram](https://en.wikipedia.org/wiki/Milligram) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :milligram) (def ounce "The [ounce](https://en.wikipedia.org/wiki/Ounce#International_avoirdupois_ounce) unit of measure; specifically, the International avoirdupois ounce. - + Commonly used with `brewtility.units` and in argument/option maps." :ounce) (def pound "The [pound](https://en.wikipedia.org/wiki/Pound_(mass)) unit of measure - + Commonly used with `brewtility.units` and in argument/option maps." :pound) @@ -408,7 +408,7 @@ (def celsius "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." :celsius) @@ -416,7 +416,7 @@ (def c "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." :c) @@ -424,7 +424,7 @@ (def centigrade "The [Celsius](https://en.wikipedia.org/wiki/Celsius) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `celsius`, `centigrade`, and `c` are all valid keys throughout brewtility to support multiple conventions." :centigrade) @@ -432,7 +432,7 @@ (def fahrenheit "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." :fahrenheit) @@ -440,7 +440,7 @@ (def f "The [Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `fahrenheit` and `f` are all valid keys throughout brewtility to support multiple conventions." :f) @@ -448,7 +448,7 @@ (def kelvin "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." :kelvin) @@ -456,7 +456,7 @@ (def k "The [Kelvin](https://en.wikipedia.org/wiki/Kelvin) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps. Note: `kelvin` and `k` are all valid keys throughout brewtility to support multiple conventions." :k) @@ -466,56 +466,56 @@ (def day "The [day](https://en.wikipedia.org/wiki/Day) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :day) (def hour "The [hour](https://en.wikipedia.org/wiki/Hour) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :hour) (def microsecond "The [microsecond](https://en.wikipedia.org/wiki/Microsecond) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :microsecond) (def millisecond "The [millisecond](https://en.wikipedia.org/wiki/Millisecond) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :millisecond) (def minute "The [minute](https://en.wikipedia.org/wiki/Minute) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :minute) (def nanosecond "The [nanosecond](https://en.wikipedia.org/wiki/Nanosecond) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :nanosecond) (def second "The [second](https://en.wikipedia.org/wiki/Second) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :second) (def week "The [week](https://en.wikipedia.org/wiki/Week) unit of measure. - + Commonly used with `brewtility.units` and in argument/option maps." :week) @@ -524,21 +524,21 @@ (def pascal "The [Pascal](https://en.wikipedia.org/wiki/Pascal_(unit)) unit of measure. - + Commonly used with `brewtility.units.pressure` and in argument maps." :pascal) (def kilopascal "The [Kilopascal](https://en.wikipedia.org/wiki/Kilopascal) unit of measure. - + Commonly used with `brewtility.units.pressure` and in argument maps." :kilopascal) (def bar "The [Bar](https://en.wikipedia.org/wiki/Bar_(unit)) unit of measure. - + Commonly used with `brewtility.units.pressure` and in argument maps." :bar) @@ -546,21 +546,21 @@ (def atmosphere "The [Atmosphere](https://en.wikipedia.org/wiki/Atmosphere_(unit)) unit of measure. Specifically, this is a [standard atmosphere](https://en.wikipedia.org/wiki/Standard_atmosphere). - + Commonly used with `brewtility.units.pressure` and in argument maps." :atmosphere) (def torr "The [Torr](https://en.wikipedia.org/wiki/Torr_(unit)) unit of measure. - + Commonly used with `brewtility.units.pressure` and in argument maps." :torr) (def psi "The [Pounds per square inch](https://en.wikipedia.org/wiki/Pound-force_per_square_inch) unit of measure. - + Commonly used with `brewtility.units.pressure` and in argument maps." :psi) diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index 599b427..395f8da 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -32,8 +32,20 @@ (is (set/subset? (set (vals sut/default-time-by-system)) time/measurements)) (is (set/subset? (set (vals sut/default-volume-by-system)) volume/measurements)) (is (set/subset? (set (vals sut/default-weight-by-system)) weight/measurements)))) + (testing "BeerXML Standard Units" + (is (= (sort (keys sut/beer-xml-standard-units)) + (sort (vec options/measurement-types)))) + (is (contains? color/measurements (get sut/beer-xml-standard-units options/color))) + (is (contains? pressure/measurements (get sut/beer-xml-standard-units options/pressure))) + (is (contains? specific-gravity/measurements (get sut/beer-xml-standard-units options/specific-gravity))) + (is (contains? temperature/measurements (get sut/beer-xml-standard-units options/temperature))) + (is (contains? time/measurements (get sut/beer-xml-standard-units options/time))) + (is (contains? volume/measurements (get sut/beer-xml-standard-units options/volume))) + (is (contains? weight/measurements (get sut/beer-xml-standard-units options/weight)))) (testing "Option keys" (is (keyword? sut/value-key)) + (is (keyword? sut/low-value-key)) + (is (keyword? sut/high-value-key)) (is (keyword? sut/display-key)) (is (keyword? sut/fine-grain-target-units)) (is (keyword? sut/fine-grain-precision)) @@ -747,14 +759,14 @@ (testing "Validate displayable color enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/color base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/color base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "0.595 srm")] - (is (= result-map (sut/enrich-displayable-units options/color base-map {:display-key :display - :value-key :value + (is (= result-map (sut/enrich-displayable-units options/color base-map {sut/display-key :display + sut/value-key :value :source-units options/lovibond :target-units options/srm}))))))) @@ -763,87 +775,104 @@ (testing "Validate displayable pressure enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/pressure base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/pressure base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1000.0 pa")] - (is (= result-map (sut/enrich-displayable-units options/pressure base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/pascal}))))))) + (is (= result-map (sut/enrich-displayable-units options/pressure base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/pascal}))))))) (deftest enrich-displayable-specific-gravity-test (testing "Validate displayable specific-gravity enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/specific-gravity base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/specific-gravity base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1.0 sg")] - (is (= result-map (sut/enrich-displayable-units options/specific-gravity base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/specific-gravity}))))))) + (is (= result-map (sut/enrich-displayable-units options/specific-gravity base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/specific-gravity}))))))) (deftest enrich-displayable-temperature-test (testing "Validate displayable temperature enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/temperature base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/temperature base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "274.15 k")] - (is (= result-map (sut/enrich-displayable-units options/temperature base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/k}))))))) + (is (= result-map (sut/enrich-displayable-units options/temperature base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/k}))))))) (deftest enrich-displayable-time-test (testing "Validate displayable time enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/time base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/time base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "1.0 m")] - (is (= result-map (sut/enrich-displayable-units options/time base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/minute}))))))) + (is (= result-map (sut/enrich-displayable-units options/time base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/minute}))))))) (deftest enrich-displayable-volume-test (testing "Validate displayable volume enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/volume base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/volume base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "202.884 tsp")] - (is (= result-map (sut/enrich-displayable-units options/volume base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/teaspoon}))))))) + (is (= result-map (sut/enrich-displayable-units options/volume base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/teaspoon}))))))) (deftest enrich-displayable-weight-test (testing "Validate displayable weight enrichment." (testing "If no value is provided, return the original map." (let [base-map {:hello "there"}] - (is (= base-map (sut/enrich-displayable-units options/weight base-map {:display-key :hello - :value-key :missing}))))) + (is (= base-map (sut/enrich-displayable-units options/weight base-map {sut/display-key :hello + sut/value-key :missing}))))) (testing "When a value is provided, add the data at `:display-key`" (let [base-map {:hello "there" :value 1} result-map (assoc base-map :display "2.205 lb")] - (is (= result-map (sut/enrich-displayable-units options/weight base-map {:display-key :display - :value-key :value - :fine-grain-target-units options/pound}))))))) + (is (= result-map (sut/enrich-displayable-units options/weight base-map {sut/display-key :display + sut/value-key :value + sut/fine-grain-target-units options/pound}))))))) + +(deftest enrich-displayable-range-test + (testing "Validate displayable range enrichment." + (testing "If neither value is provided, return the original map." + (let [base-map {:a 1 + :b 3}] + (is (= base-map (sut/enrich-displayable-range options/weight base-map {sut/display-key :hello + sut/low-value-key :missing + sut/high-value-key :also-gone}))))) + (testing "When all values are provided, add the data at `:display-key`" + (let [base-map {:a 3 + :b 6} + result-map (assoc base-map :display "6.614 - 13.228 lb")] + (is (= result-map (sut/enrich-displayable-range options/weight base-map {sut/display-key :display + sut/low-value-key :a + sut/high-value-key :b + sut/fine-grain-target-units options/pound}))))))) diff --git a/test/brewtility/predicates/fermentables_test.cljc b/test/brewtility/predicates/fermentables_test.cljc index 5115337..ebcbb39 100644 --- a/test/brewtility/predicates/fermentables_test.cljc +++ b/test/brewtility/predicates/fermentables_test.cljc @@ -3,6 +3,7 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.data.fermentables :as fermentables] [brewtility.predicates.fermentables :as sut] + [brewtility.predicates.options :as options] [common-beer-format.fermentables :as cbf-fermentables])) @@ -20,7 +21,7 @@ (deftest grain?-test (testing "A fermentable with a `:type` matching `\"grain\" returns true" (is (true? (sut/grain? (assoc fermentables/sample-fermentable :type "Grain")))) - (is (true? (sut/grain? (assoc fermentables/sample-fermentable :type cbf-fermentables/grain))))) + (is (true? (sut/grain? (assoc fermentables/sample-fermentable :type cbf-fermentables/grain) {options/uppercase? true})))) (testing "A fermentable with a `:type` not matching `\"grain\" returns false" (is (false? (sut/grain? (assoc fermentables/sample-fermentable :type "extract")))) (is (false? (sut/grain? (assoc fermentables/sample-fermentable :type cbf-fermentables/extract)))) @@ -78,7 +79,7 @@ (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type "Dry EXTract")))) (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type "adJunct")))) (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type cbf-fermentables/sugar)))) - (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type cbf-fermentables/grain)))) + (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type cbf-fermentables/grain) {options/uppercase? true}))) (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type cbf-fermentables/dry-extract)))) (is (false? (sut/extract? (assoc fermentables/sample-fermentable :type cbf-fermentables/adjunct))))) (testing "This is a function from a fermentable to a boolean" @@ -121,12 +122,13 @@ (deftest adjunct?-test (testing "A fermentable with a `:type` matching `\"grain\" returns true" (is (true? (sut/adjunct? (assoc fermentables/sample-fermentable :type "adJunct")))) + (is (true? (sut/adjunct? (assoc fermentables/sample-fermentable :type "adJunct") {options/uppercase? true}))) (is (true? (sut/adjunct? (assoc fermentables/sample-fermentable :type cbf-fermentables/adjunct))))) (testing "A fermentable with a `:type` not matching `\"grain\" returns false" (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type "sugar")))) (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type "GRAIN")))) (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type "EXTract")))) - (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type "DRY EXTRact")))) + (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type "DRY EXTRact") {options/uppercase? true}))) (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type cbf-fermentables/sugar)))) (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type cbf-fermentables/grain)))) (is (false? (sut/adjunct? (assoc fermentables/sample-fermentable :type cbf-fermentables/extract)))) From 1854f179958b62fb1947e011587724d8acf9d2f4 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 17:56:54 +0000 Subject: [PATCH 35/44] Clean up test data --- src/brewtility/enrich/impl.cljc | 15 ++- src/brewtility/enrich/styles.cljc | 30 +++-- test/brewtility/data/equipment.cljc | 34 ++--- test/brewtility/data/fermentables.cljc | 32 ++--- test/brewtility/data/hops.cljc | 26 ++-- test/brewtility/data/mash.cljc | 26 ++-- test/brewtility/data/miscs.cljc | 18 +-- test/brewtility/data/recipes.cljc | 44 +++---- test/brewtility/data/styles.cljc | 70 +++++----- test/brewtility/data/waters.cljc | 28 ++-- test/brewtility/data/yeasts.cljc | 34 ++--- test/brewtility/enrich/impl_test.cljc | 128 +++++++++++-------- test/brewtility/predicates/options_test.cljc | 8 ++ test/brewtility/runner.cljs | 4 +- 14 files changed, 264 insertions(+), 233 deletions(-) create mode 100644 test/brewtility/predicates/options_test.cljc diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index a7af493..840449e 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -5,8 +5,7 @@ {:no-doc true :added "2.1" :implementation-only true} - (:require [brewtility.precision :as precision] - [brewtility.units :as units] + (:require [brewtility.units :as units] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -157,7 +156,7 @@ target-units "`. Allowed values are: " allowed-values)] - (assoc error-map :units error-msg))) + (assoc error-map :target-units error-msg))) (defn source-unit-error @@ -186,7 +185,7 @@ source-units "`. Allowed values are: " allowed-values)] - (assoc error-map :units error-msg))) + (assoc error-map :source-units error-msg))) (defn systems-of-meaure-error @@ -203,7 +202,7 @@ system-of-measure ". Allowed values are:" options/systems-of-measure)] - (assoc error-map :system-of-measure error-msg))) + (assoc error-map options/system-of-measure error-msg))) (defn precision-error @@ -268,14 +267,16 @@ :no-doc true :see-also ["enrich-displayable-pressure"]} [measurement-type - {:keys [target-units system-of-measure precision suffix] + {:keys [target-units source-units system-of-measure precision suffix] :as opts}] - (let [valid-target? (valid-unit-for-measurement-type? measurement-type target-units) + (let [valid-source? (valid-unit-for-measurement-type? measurement-type source-units) + valid-target? (valid-unit-for-measurement-type? measurement-type target-units) valid-system? (contains? options/systems-of-measure system-of-measure) valid-precision? (int? precision) valid-suffix? (contains? options/supported-suffixes suffix) errors (cond-> {} (not valid-target?) (target-unit-error measurement-type target-units) + (not valid-source?) (source-unit-error measurement-type source-units) (not valid-system?) (systems-of-meaure-error measurement-type system-of-measure) (not valid-precision?) (precision-error measurement-type precision) (not valid-suffix?) (suffix-error measurement-type suffix))] diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index 03c8a94..2f8363e 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -173,11 +173,11 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: -- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - `:precision`: The number of significant decimal places to display. Defaults to 3. - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: @@ -194,13 +194,14 @@ "enrich-styles" "enrich-styles-wrapper"]} ([style] (enrich-display-color-min style {})) - ([style {:keys [style-display-color-min-target-units + ([style {:keys [color-system + style-display-color-min-target-units style-display-color-min-precision style-display-color-min-suffix] :as opts}] (let [options (merge opts {impl/value-key :color-min impl/display-key :display-color-min - impl/fine-grain-target-units style-display-color-min-target-units + impl/fine-grain-target-units (or style-display-color-min-target-units color-system) impl/fine-grain-precision style-display-color-min-precision impl/fine-grain-suffix style-display-color-min-suffix})] (impl/enrich-displayable-units options/color style options)))) @@ -212,11 +213,11 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: -- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: - - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:color-system` - The color system to use for the conversion. Default is `:lovibond` for type `:grain`, and `:srm` otherwise. Acceptable values are: + - `:lovibond` - Use the [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) system. + - `:srm` - Use the [Standard Reference Method](https://en.wikipedia.org/wiki/Standard_Reference_Method) system. + - `:ebc` - Use the [European Brewing Convention](https://www.lovibond.com/en/PC/Colour-Measurement/Colour-Scales-Standards/EBC-European-Brewing-Convention) system. + - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - `:precision`: The number of significant decimal places to display. Defaults to 3. - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: @@ -233,13 +234,14 @@ "enrich-styles" "enrich-styles-wrapper"]} ([style] (enrich-display-color-max style {})) - ([style {:keys [style-display-color-max-target-units + ([style {:keys [color-system + style-display-color-max-target-units style-display-color-max-precision style-display-color-max-suffix] :as opts}] (let [options (merge opts {impl/value-key :color-max impl/display-key :display-color-max - impl/fine-grain-target-units style-display-color-max-target-units + impl/fine-grain-target-units (or style-display-color-max-target-units color-system) impl/fine-grain-precision style-display-color-max-precision impl/fine-grain-suffix style-display-color-max-suffix})] (impl/enrich-displayable-units options/color style options)))) diff --git a/test/brewtility/data/equipment.cljc b/test/brewtility/data/equipment.cljc index b90468c..ece2246 100644 --- a/test/brewtility/data/equipment.cljc +++ b/test/brewtility/data/equipment.cljc @@ -10,27 +10,27 @@ (def sample-equipment "A hard-coded sample equipment for static unit tests" - {:batch-size 19.9 - :boil-size 26.2 - :boil-time 60.5 - :calc-boil-volume true - :evap-rate 9.0 - :hop-utilization 100.5 - :lauter-deadspace 0.8 - :name "8 Gal pot with 5 gal Igloo Cooler" - :notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." - :top-up-kettle 0.5 - :top-up-water 0.5 - :trub-chiller-loss 0.8 - :tun-specific-heat 0.3 - :tun-volume 19.9 - :tun-weight 2.5 - :version 1}) + {equipment.format/batch-size 19.9 + equipment.format/boil-size 26.2 + equipment.format/boil-time 60.5 + equipment.format/calc-boil-volume true + equipment.format/evap-rate 9.0 + equipment.format/hop-utilization 100.5 + equipment.format/lauter-deadspace 0.8 + equipment.format/name "8 Gal pot with 5 gal Igloo Cooler" + equipment.format/notes "Popular all grain setup. 5 Gallon Gott or Igloo cooler as mash tun with false bottom, and 7-9 gallon brewpot capable of boiling at least 6 gallons of wort. Primarily used for single infusion mashes." + equipment.format/top-up-kettle 0.5 + equipment.format/top-up-water 0.5 + equipment.format/trub-chiller-loss 0.8 + equipment.format/tun-specific-heat 0.3 + equipment.format/tun-volume 19.9 + equipment.format/tun-weight 2.5 + equipment.format/version 1}) (def sample-equipment-wrapper "A hard-coded sample equipment-wrapper for static unit tests" - {:equipment sample-equipment}) + {equipment.format/equipment sample-equipment}) (defn generate-equipment diff --git a/test/brewtility/data/fermentables.cljc b/test/brewtility/data/fermentables.cljc index 219525e..03fcc46 100644 --- a/test/brewtility/data/fermentables.cljc +++ b/test/brewtility/data/fermentables.cljc @@ -10,25 +10,25 @@ (def sample-fermentable "A hard-coded sample fermentable for static unit tests" - {:amount 0.45 - :coarse-fine-diff 1.5 - :color 500.1 - :diastatic-power 0.0 - :max-in-batch 10.0 - :moisture 5.0 - :name "Black Barley" - :notes "Unmalted roasted barley for stouts, porters" - :origin "United States" - :protein 13.2 - :supplier "Gnome Brew" - :type "Grain" - :version 1 - :yield 78.0}) + {fermentables.format/amount 0.45 + fermentables.format/coarse-fine-diff 1.5 + fermentables.format/color 500.1 + fermentables.format/diastatic-power 0.0 + fermentables.format/max-in-batch 10.0 + fermentables.format/moisture 5.0 + fermentables.format/name "Black Barley" + fermentables.format/notes "Unmalted roasted barley for stouts, porters" + fermentables.format/origin "United States" + fermentables.format/protein 13.2 + fermentables.format/supplier "Gnome Brew" + fermentables.format/type "Grain" + fermentables.format/version 1 + fermentables.format/yield 78.0}) (def sample-fermentable-wrapper "A hard-coded sample fermentable-wrapper for static unit tests" - {:fermentable sample-fermentable}) + {fermentables.format/fermentable sample-fermentable}) (def sample-fermentables @@ -38,7 +38,7 @@ (def sample-fermentables-wrapper "A hard-coded sample fermentables-wrapper for static unit tests" - {:fermentables sample-fermentables}) + {fermentables.format/fermentables sample-fermentables}) (defn generate-fermentable diff --git a/test/brewtility/data/hops.cljc b/test/brewtility/data/hops.cljc index cf90ad2..7d59eae 100644 --- a/test/brewtility/data/hops.cljc +++ b/test/brewtility/data/hops.cljc @@ -43,18 +43,18 @@ (def sample-hop "A hard-coded sample hop for static unit tests" - {:alpha 5.0 - :amount 0.0638 - :name "Goldings, East Kent" - :notes "Great all purpose UK hop for ales, stouts, porters" - :time 60.1 - :use "Boil" - :version 1}) + {hops.format/alpha 5.0 + hops.format/amount 0.0638 + hops.format/name "Goldings, East Kent" + hops.format/notes "Great all purpose UK hop for ales, stouts, porters" + hops.format/time 60.1 + hops.format/use "Boil" + hops.format/version 1}) (def sample-hop-wrapper "A hard-coded sample hop-wrapper for static unit tests" - {:hop sample-hop}) + {hops.format/hop sample-hop}) (def sample-hops @@ -64,7 +64,7 @@ (def sample-hops-wrapper "A hard-coded sample hops-wrapper for static unit tests" - {:hops sample-hops}) + {hops.format/hops sample-hops}) (defn generate-hop @@ -103,9 +103,9 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" (is (spoon.spec/test-valid? ::hops.format/hop sample-hop) "Static test data should conform to common-beer-format.hop/hop") - (is (spoon.spec/test-valid? ::hops.format/hop (assoc sample-hop :type (random-hop-type))) + (is (spoon.spec/test-valid? ::hops.format/hop (assoc sample-hop hops.format/type (random-hop-type))) "Static test data should conform to common-beer-format.hop/hop, even with an added optional type") - (is (spoon.spec/test-valid? ::hops.format/hop (assoc sample-hop :form (random-hop-form))) + (is (spoon.spec/test-valid? ::hops.format/hop (assoc sample-hop hops.format/form (random-hop-form))) "Static test data should conform to common-beer-format.hop/hop, even with an added optional form") (is (spoon.spec/test-valid? ::hops.format/hop sample-hop) "Static test data should conform to common-beer-format.hop/hop") @@ -119,9 +119,9 @@ (deftest generative-test-data-check (testing "Since this library assumes common-beer-format data is utilized, make sure generative test data conforms" - (is (spoon.spec/test-valid? ::hops.format/hop (assoc (generate-hop) :type (random-hop-type))) + (is (spoon.spec/test-valid? ::hops.format/hop (assoc (generate-hop) hops.format/type (random-hop-type))) "Generative test data should conform to common-beer-format.hop/hop, even with an added optional type") - (is (spoon.spec/test-valid? ::hops.format/hop (assoc (generate-hop) :form (random-hop-form))) + (is (spoon.spec/test-valid? ::hops.format/hop (assoc (generate-hop) hops.format/form (random-hop-form))) "Generative test data should conform to common-beer-format.hop/hop, even with an added optional form") (is (spoon.spec/test-valid? ::hops.format/hop (generate-hop)) "Generative test data should conform to common-beer-format.hop/hop") diff --git a/test/brewtility/data/mash.cljc b/test/brewtility/data/mash.cljc index 4ff7911..7789a25 100644 --- a/test/brewtility/data/mash.cljc +++ b/test/brewtility/data/mash.cljc @@ -10,17 +10,17 @@ (def sample-mash-step "A hard-coded sample mash step for static unit tests" - {:infuse-amount 10.0 - :name "Conversion Step, 68C" - :step-temp 68.0 - :step-time 60.0 - :type "Infusion" - :version 1}) + {mash.format/infuse-amount 10.0 + mash.format/name "Conversion Step, 68C" + mash.format/step-temp 68.0 + mash.format/step-time 60.0 + mash.format/type "Infusion" + mash.format/version 1}) (def sample-mash-step-wrapper "A hard-coded sample mash-step-wrapper for static unit tests" - {:mash-step sample-mash-step}) + {mash.format/mash-step sample-mash-step}) (def sample-mash-steps @@ -30,15 +30,15 @@ (def sample-mash-steps-wrapper "A hard-coded sample mash-steps-wrapper for static unit tests" - {:mash-steps sample-mash-steps}) + {mash.format/mash-steps sample-mash-steps}) (def sample-mash "A hard-coded sample mash for static unit tests" - {:name "Single Step Infusion, 68 C" - :version 1 - :grain-temp 22.0 - :mash-steps sample-mash-steps}) + {mash.format/name "Single Step Infusion, 68 C" + mash.format/version 1 + mash.format/grain-temp 22.0 + mash.format/mash-steps sample-mash-steps}) (def sample-mash-wrapper @@ -75,7 +75,7 @@ {:added "2.0" :no-doc true} [] - {:mash-steps (gen/generate (spec/gen ::mash.format/mash-steps))}) + {mash.format/mash-steps (gen/generate (spec/gen ::mash.format/mash-steps))}) (defn generate-mash diff --git a/test/brewtility/data/miscs.cljc b/test/brewtility/data/miscs.cljc index 0aa7545..59ecf42 100644 --- a/test/brewtility/data/miscs.cljc +++ b/test/brewtility/data/miscs.cljc @@ -10,18 +10,18 @@ (def sample-misc "A hard-coded sample misc for static unit tests" - {:amount 0.010 - :name "Irish Moss" - :notes "Used as a clarifying agent during the last few minutes of the boil" - :time 15.1 - :type "Fining" - :use "Boil" - :version 1}) + {miscs.format/amount 0.010 + miscs.format/name "Irish Moss" + miscs.format/notes "Used as a clarifying agent during the last few minutes of the boil" + miscs.format/time 15.1 + miscs.format/type "Fining" + miscs.format/use "Boil" + miscs.format/version 1}) (def sample-misc-wrapper "A hard-coded sample misc-wrapper for static unit tests" - {:misc sample-misc}) + {miscs.format/misc sample-misc}) (def sample-miscs @@ -31,7 +31,7 @@ (def sample-miscs-wrapper "A hard-coded sample miscs-wrapper for static unit tests" - {:miscs sample-miscs}) + {miscs.format/miscs sample-miscs}) (defn generate-misc diff --git a/test/brewtility/data/recipes.cljc b/test/brewtility/data/recipes.cljc index ca23f72..3abdb11 100644 --- a/test/brewtility/data/recipes.cljc +++ b/test/brewtility/data/recipes.cljc @@ -35,24 +35,24 @@ (def sample-recipe "A hard-coded sample recipe for static unit tests" - (merge {:age 24.0 - :age-temp 17.0 - :batch-size 18.93 - :boil-size 20.82 - :boil-time 60.0 - :brewer "Brad Smith" - :carbonation 2.1 - :carbonation-used "Kegged" - :date "3 Jan 04" - :efficiency 72.0 - :fermentation-stages 2 - :fg 1.012 - :name "Dry Stout" - :og 1.036 - :rating "41" - :taste-notes "Nice dry Irish stout with a warm body but low starting gravity much like the famous drafts." - :type "All Grain" - :version 1} + (merge {recipes.format/age 24.0 + recipes.format/age-temp 17.0 + recipes.format/batch-size 18.93 + recipes.format/boil-size 20.82 + recipes.format/boil-time 60.0 + recipes.format/brewer "Brad Smith" + recipes.format/carbonation 2.1 + recipes.format/carbonation-used "Kegged" + recipes.format/date "3 Jan 04" + recipes.format/efficiency 72.0 + recipes.format/fermentation-stages 2 + recipes.format/fg 1.012 + recipes.format/name "Dry Stout" + recipes.format/og 1.036 + recipes.format/taste-rating "41" + recipes.format/taste-notes "Nice dry Irish stout with a warm body but low starting gravity much like the famous drafts." + recipes.format/type "All Grain" + recipes.format/version 1} equipment/sample-equipment-wrapper fermentables/sample-fermentables-wrapper hops/sample-hops-wrapper @@ -65,7 +65,7 @@ (def sample-recipe-wrapper "A hard-coded sample recipe-wrapper for static unit tests" - {:recipe sample-recipe}) + {recipes.format/recipe sample-recipe}) (def sample-recipes @@ -75,7 +75,7 @@ (def sample-recipes-wrapper "A hard-coded sample recipes-wrapper for static unit tests" - {:recipes sample-recipes}) + {recipes.format/recipes sample-recipes}) (defn generate-recipe @@ -114,7 +114,7 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" (is (spoon.spec/test-valid? ::recipes.format/recipe sample-recipe) "Static test data should conform to common-beer-format.recipe/recipe") - (is (spoon.spec/test-valid? ::recipes.format/recipe (assoc sample-recipe :ibu-method (random-ibu-method))) + (is (spoon.spec/test-valid? ::recipes.format/recipe (assoc sample-recipe recipes.format/ibu-method (random-ibu-method))) "Static test data should conform to common-beer-format.recipe/recipe, even with a random IBU method") (is (spoon.spec/test-valid? ::recipes.format/recipe-wrapper sample-recipe-wrapper) "Static test data should conform to common-beer-format.recipe/recipe-wrapper") @@ -128,7 +128,7 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure generative test data conforms" (is (spoon.spec/test-valid? ::recipes.format/recipe (generate-recipe)) "Generative test data should conform to common-beer-format.recipe/recipe") - (is (spoon.spec/test-valid? ::recipes.format/recipe (assoc (generate-recipe) :ibu-method (random-ibu-method))) + (is (spoon.spec/test-valid? ::recipes.format/recipe (assoc (generate-recipe) recipes.format/ibu-method (random-ibu-method))) "Generative test data should conform to common-beer-format.recipe/recipe, even with a random IBU method") (is (spoon.spec/test-valid? ::recipes.format/recipe-wrapper (generate-recipe-wrapper)) "Generative test data should conform to common-beer-format.recipe/recipe-wrapper") diff --git a/test/brewtility/data/styles.cljc b/test/brewtility/data/styles.cljc index b457109..ed4bf68 100644 --- a/test/brewtility/data/styles.cljc +++ b/test/brewtility/data/styles.cljc @@ -3,38 +3,38 @@ (:require [clojure.spec.alpha :as spec] [clojure.spec.gen.alpha :as gen] [com.wallbrew.spoon.spec :as spoon.spec] - [common-beer-format.styles :as style.format] + [common-beer-format.styles :as styles.format] #? (:clj [clojure.test :refer [deftest is testing]]) #? (:cljs [cljs.test :refer-macros [deftest is testing]]))) (def sample-style "A hard-coded sample style for static unit tests" - {:abv-max 5.5 - :abv-min 3.2 - :carb-max 2.1 - :carb-min 1.6 - :category "Stout" - :category-number "16" - :color-max 200.0 - :color-min 35.0 - :fg-max 1.011 - :fg-min 1.007 - :ibu-max 50.0 - :ibu-min 30.0 - :name "Dry Stout" - :notes "Famous Irish Stout. Dry, roasted, almost coffee like flavor." - :og-max 1.050 - :og-min 1.035 - :style-guide "BJCP" - :style-letter "A" - :type "Ale" - :version 1}) + {styles.format/abv-max 5.5 + styles.format/abv-min 3.2 + styles.format/carb-max 2.1 + styles.format/carb-min 1.6 + styles.format/category "Stout" + styles.format/category-number "16" + styles.format/color-max 200.0 + styles.format/color-min 35.0 + styles.format/fg-max 1.011 + styles.format/fg-min 1.007 + styles.format/ibu-max 50.0 + styles.format/ibu-min 30.0 + styles.format/name "Dry Stout" + styles.format/notes "Famous Irish Stout. Dry, roasted, almost coffee like flavor." + styles.format/og-max 1.050 + styles.format/og-min 1.035 + styles.format/style-guide "BJCP" + styles.format/style-letter "A" + styles.format/type "Ale" + styles.format/version 1}) (def sample-style-wrapper "A hard-coded sample style-wrapper for static unit tests" - {:style sample-style}) + {styles.format/style sample-style}) (def sample-styles @@ -44,7 +44,7 @@ (def sample-styles-wrapper "A hard-coded sample styles-wrapper for static unit tests" - {:styles sample-styles}) + {styles.format/styles sample-styles}) (defn generate-style @@ -52,7 +52,7 @@ {:added "1.4" :no-doc true} [] - (gen/generate (spec/gen ::style.format/style))) + (gen/generate (spec/gen ::styles.format/style))) (defn generate-style-wrapper @@ -60,7 +60,7 @@ {:added "1.4" :no-doc true} [] - (gen/generate (spec/gen ::style.format/style-wrapper))) + (gen/generate (spec/gen ::styles.format/style-wrapper))) (defn generate-styles @@ -68,7 +68,7 @@ {:added "1.4" :no-doc true} [] - (gen/generate (spec/gen ::style.format/styles))) + (gen/generate (spec/gen ::styles.format/styles))) (defn generate-styles-wrapper @@ -76,28 +76,28 @@ {:added "1.4" :no-doc true} [] - (gen/generate (spec/gen ::style.format/styles-wrapper))) + (gen/generate (spec/gen ::styles.format/styles-wrapper))) (deftest static-test-data-check (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" - (is (spoon.spec/test-valid? ::style.format/style sample-style) + (is (spoon.spec/test-valid? ::styles.format/style sample-style) "Static test data should conform to common-beer-format.style/style") - (is (spoon.spec/test-valid? ::style.format/style-wrapper sample-style-wrapper) + (is (spoon.spec/test-valid? ::styles.format/style-wrapper sample-style-wrapper) "Static test data should conform to common-beer-format.style/style-wrapper") - (is (spoon.spec/test-valid? ::style.format/styles sample-styles) + (is (spoon.spec/test-valid? ::styles.format/styles sample-styles) "Static test data should conform to common-beer-format.style/style") - (is (spoon.spec/test-valid? ::style.format/styles-wrapper sample-styles-wrapper) + (is (spoon.spec/test-valid? ::styles.format/styles-wrapper sample-styles-wrapper) "Static test data should conform to common-beer-format.style/style-wrapper"))) (deftest generative-test-data-check (testing "Since this library assumes common-beer-format data is utilized, make sure generative test data conforms" - (is (spoon.spec/test-valid? ::style.format/style (generate-style)) + (is (spoon.spec/test-valid? ::styles.format/style (generate-style)) "Generative test data should conform to common-beer-format.style/style") - (is (spoon.spec/test-valid? ::style.format/style-wrapper (generate-style-wrapper)) + (is (spoon.spec/test-valid? ::styles.format/style-wrapper (generate-style-wrapper)) "Generative test data should conform to common-beer-format.style/style-wrapper") - (is (spoon.spec/test-valid? ::style.format/styles (generate-styles)) + (is (spoon.spec/test-valid? ::styles.format/styles (generate-styles)) "Generative test data should conform to common-beer-format.style/style") - (is (spoon.spec/test-valid? ::style.format/styles-wrapper (generate-styles-wrapper)) + (is (spoon.spec/test-valid? ::styles.format/styles-wrapper (generate-styles-wrapper)) "Generative test data should conform to common-beer-format.style/style-wrapper"))) diff --git a/test/brewtility/data/waters.cljc b/test/brewtility/data/waters.cljc index 1c07eb5..1118935 100644 --- a/test/brewtility/data/waters.cljc +++ b/test/brewtility/data/waters.cljc @@ -23,22 +23,22 @@ (def sample-water "A hard-coded sample water for static unit tests" - {:amount 20.0 - :bicarbonate 300.0 - :calcium 295.0 - :chloride 25.0 - :magnesium 45.0 - :name "Chicago" - :notes "The best there is" - :ph 8.0 - :sodium 55.0 - :sulfate 725.0 - :version 1}) + {waters.format/amount 20.0 + waters.format/bicarbonate 300.0 + waters.format/calcium 295.0 + waters.format/chloride 25.0 + waters.format/magnesium 45.0 + waters.format/name "Chicago" + waters.format/notes "The best there is" + waters.format/ph 8.0 + waters.format/sodium 55.0 + waters.format/sulfate 725.0 + waters.format/version 1}) (def sample-water-wrapper "A hard-coded sample water-wrapper for static unit tests" - {:water sample-water}) + {waters.format/water sample-water}) (def sample-waters @@ -48,7 +48,7 @@ (def sample-waters-wrapper "A hard-coded sample waters-wrapper for static unit tests" - {:waters sample-waters}) + {waters.format/waters sample-waters}) (defn generate-water @@ -87,6 +87,8 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" (is (spoon.spec/test-valid? ::waters.format/water sample-water) "Static test data should conform to common-beer-format.water/water") + (is (spoon.spec/test-valid? ::waters.format/water (assoc sample-water waters.format/ph (random-ph))) + "Static test data should conform to common-beer-format.water/water") (is (spoon.spec/test-valid? ::waters.format/water-wrapper sample-water-wrapper) "Static test data should conform to common-beer-format.water/water-wrapper") (is (spoon.spec/test-valid? ::waters.format/waters sample-waters) diff --git a/test/brewtility/data/yeasts.cljc b/test/brewtility/data/yeasts.cljc index 04c2495..ea85c90 100644 --- a/test/brewtility/data/yeasts.cljc +++ b/test/brewtility/data/yeasts.cljc @@ -27,24 +27,24 @@ (def sample-yeast "A hard-coded sample yeast for static unit tests" - {:amount 0.250 - :attenuation 73.0 - :best-for "Irish Dry Stouts" - :flocculation "Medium" - :form "Liquid" - :laboratory "Wyeast Labs" - :max-temperature 22.2 - :min-temperature 16.7 - :name "Irish Ale" - :notes "Dry, fruity flavor characteristic of stouts. Full bodied, dry, clean flavor." - :product-id "1084" - :type "Ale" - :version 1}) + {yeasts.format/amount 0.250 + yeasts.format/attenuation 73.0 + yeasts.format/best-for "Irish Dry Stouts" + yeasts.format/flocculation "Medium" + yeasts.format/form "Liquid" + yeasts.format/laboratory "Wyeast Labs" + yeasts.format/max-temperature 22.2 + yeasts.format/min-temperature 16.7 + yeasts.format/name "Irish Ale" + yeasts.format/notes "Dry, fruity flavor characteristic of stouts. Full bodied, dry, clean flavor." + yeasts.format/product-id "1084" + yeasts.format/type "Ale" + yeasts.format/version 1}) (def sample-yeast-wrapper "A hard-coded sample yeast-wrapper for static unit tests" - {:yeast sample-yeast}) + {yeasts.format/yeast sample-yeast}) (def sample-yeasts @@ -54,7 +54,7 @@ (def sample-yeasts-wrapper "A hard-coded sample yeasts-wrapper for static unit tests" - {:yeasts sample-yeasts}) + {yeasts.format/yeasts sample-yeasts}) (defn generate-yeast @@ -93,7 +93,7 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure static test data conforms" (is (spoon.spec/test-valid? ::yeasts.format/yeast sample-yeast) "Static test data should conform to common-beer-format.yeast/yeast") - (is (spoon.spec/test-valid? ::yeasts.format/yeast (assoc sample-yeast :flocculation (random-flocculation))) + (is (spoon.spec/test-valid? ::yeasts.format/yeast (assoc sample-yeast yeasts.format/flocculation (random-flocculation))) "Static test data should conform to common-beer-format.yeast/yeast, even with random flocculation") (is (spoon.spec/test-valid? ::yeasts.format/yeast-wrapper sample-yeast-wrapper) "Static test data should conform to common-beer-format.yeast/yeast-wrapper") @@ -107,7 +107,7 @@ (testing "Since this library assumes common-beer-format data is utilized, make sure generative test data conforms" (is (spoon.spec/test-valid? ::yeasts.format/yeast (generate-yeast)) "Generative test data should conform to common-beer-format.yeast/yeast") - (is (spoon.spec/test-valid? ::yeasts.format/yeast (assoc (generate-yeast) :flocculation (random-flocculation))) + (is (spoon.spec/test-valid? ::yeasts.format/yeast (assoc (generate-yeast) yeasts.format/flocculation (random-flocculation))) "Generative test data should conform to common-beer-format.yeast/yeast, even with random flocculation") (is (spoon.spec/test-valid? ::yeasts.format/yeast-wrapper (generate-yeast-wrapper)) "Generative test data should conform to common-beer-format.yeast/yeast-wrapper") diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index 395f8da..ebda0e6 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -199,91 +199,91 @@ new-error-map (sut/target-unit-error error-map options/color :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "color") + (is (str/includes? (:target-units new-error-map) "color") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "lovibond") + (is (str/includes? (:target-units new-error-map) "lovibond") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for pressure" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/pressure :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "pressure") + (is (str/includes? (:target-units new-error-map) "pressure") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "psi") + (is (str/includes? (:target-units new-error-map) "psi") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for specific-gravity" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/specific-gravity :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "specific-gravity") + (is (str/includes? (:target-units new-error-map) "specific-gravity") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "specific-gravity") + (is (str/includes? (:target-units new-error-map) "specific-gravity") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for temperature" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/temperature :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "temperature") + (is (str/includes? (:target-units new-error-map) "temperature") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "celsius") + (is (str/includes? (:target-units new-error-map) "celsius") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for time" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/time :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "time") + (is (str/includes? (:target-units new-error-map) "time") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "minute") + (is (str/includes? (:target-units new-error-map) "minute") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for volume" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/volume :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "volume") + (is (str/includes? (:target-units new-error-map) "volume") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "teaspoon") + (is (str/includes? (:target-units new-error-map) "teaspoon") "The valid units are included in the error message"))) (testing "Ensure target-unit-error sets an appropriate error for weight" (let [error-map {:some "error"} new-error-map (sut/target-unit-error error-map options/weight :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :target-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "weight") + (is (str/includes? (:target-units new-error-map) "weight") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:target-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "pound") + (is (str/includes? (:target-units new-error-map) "pound") "The valid units are included in the error message")))) @@ -293,91 +293,91 @@ new-error-map (sut/source-unit-error error-map options/color :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "color") + (is (str/includes? (:source-units new-error-map) "color") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "lovibond") + (is (str/includes? (:source-units new-error-map) "lovibond") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for pressure" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/pressure :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "pressure") + (is (str/includes? (:source-units new-error-map) "pressure") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "psi") + (is (str/includes? (:source-units new-error-map) "psi") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for specific-gravity" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/specific-gravity :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "specific-gravity") + (is (str/includes? (:source-units new-error-map) "specific-gravity") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "specific-gravity") + (is (str/includes? (:source-units new-error-map) "specific-gravity") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for temperature" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/temperature :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "temperature") + (is (str/includes? (:source-units new-error-map) "temperature") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "celsius") + (is (str/includes? (:source-units new-error-map) "celsius") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for time" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/time :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "time") + (is (str/includes? (:source-units new-error-map) "time") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "minute") + (is (str/includes? (:source-units new-error-map) "minute") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for volume" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/volume :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "volume") + (is (str/includes? (:source-units new-error-map) "volume") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "teaspoon") + (is (str/includes? (:source-units new-error-map) "teaspoon") "The valid units are included in the error message"))) (testing "Ensure source-unit-error sets an appropriate error for weight" (let [error-map {:some "error"} new-error-map (sut/source-unit-error error-map options/weight :fake)] (is (contains? new-error-map :some) "Previously recorded errors are preserved") - (is (contains? new-error-map :units) + (is (contains? new-error-map :source-units) "The new error is recorded") - (is (str/includes? (:units new-error-map) "weight") + (is (str/includes? (:source-units new-error-map) "weight") "The type of attempted conversion is included in the error message") - (is (str/includes? (:units new-error-map) "fake") + (is (str/includes? (:source-units new-error-map) "fake") "The invalid unit is included in the error message") - (is (str/includes? (:units new-error-map) "pound") + (is (str/includes? (:source-units new-error-map) "pound") "The valid units are included in the error message")))) @@ -526,6 +526,8 @@ (testing "Missing any option throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :target-units))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :target-units))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :source-units))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts :source-units))))) #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/precision))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/precision))))) #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (dissoc valid-opts options/suffix))))) @@ -533,6 +535,8 @@ (testing "An invalid selection for any require value throws an error" #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :target-units :fake))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :target-units :fake))))) + #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :source-units :fake))))) + #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts :source-units :fake))))) #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/precision :fake))))) #?(:cljs (is (thrown-with-msg? js/Error error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/precision :fake))))) #?(:clj (is (thrown-with-msg? Exception error-regex (sut/parse-enrich-displayable-units-opts options/color (assoc valid-opts options/suffix :fake))))) @@ -541,6 +545,7 @@ (deftest parse-enrich-displayable-pressure-opts-test (let [valid-opts {:target-units options/psi + :source-units options/kilopascal options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -550,6 +555,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-pressure-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/psi + :source-units options/kilopascal options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -577,6 +583,7 @@ (deftest parse-enrich-displayable-specific-gravity-opts-test (let [valid-opts {:target-units options/specific-gravity + :source-units options/specific-gravity options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -586,6 +593,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-specific-gravity-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/specific-gravity + :source-units options/specific-gravity options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -613,6 +621,7 @@ (deftest parse-enrich-displayable-temperature-opts-test (let [valid-opts {:target-units options/c + :source-units options/c options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -622,6 +631,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/c + :source-units options/c options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -649,6 +659,7 @@ (deftest parse-enrich-displayable-time-opts-test (let [valid-opts {:target-units options/minute + :source-units options/minute options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -658,6 +669,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/minute + :source-units options/minute options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -685,6 +697,7 @@ (deftest parse-enrich-displayable-volume-opts-test (let [valid-opts {:target-units options/teaspoon + :source-units options/litre options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -694,6 +707,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/teaspoon + :source-units options/litre options/system-of-measure options/metric options/precision 2 options/suffix options/full}] @@ -721,6 +735,7 @@ (deftest parse-enrich-displayable-weight-opts-test (let [valid-opts {:target-units options/pound + :source-units options/kilogram options/system-of-measure options/metric options/precision 2 options/suffix options/full} @@ -730,6 +745,7 @@ "Valid opts are returned unchanged")) (testing "Ensure parse-enrich-displayable-temperature-opts returns valid opts with static keys" (let [valid-opts-w-keys {:target-units options/pound + :source-units options/kilogram options/system-of-measure options/metric options/precision 2 options/suffix options/full}] diff --git a/test/brewtility/predicates/options_test.cljc b/test/brewtility/predicates/options_test.cljc new file mode 100644 index 0000000..b980c33 --- /dev/null +++ b/test/brewtility/predicates/options_test.cljc @@ -0,0 +1,8 @@ +(ns brewtility.predicates.options-test + (:require #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + [brewtility.predicates.options :as sut])) + +(deftest type-test + (testing "A sanity test for all option keywords" + (is (keyword? sut/uppercase?)))) diff --git a/test/brewtility/runner.cljs b/test/brewtility/runner.cljs index 2dbe1f7..f95ca5a 100644 --- a/test/brewtility/runner.cljs +++ b/test/brewtility/runner.cljs @@ -1,6 +1,6 @@ (ns brewtility.runner "The ClojureScript test runner for brewtility. - + This namespace is responsible for running all of the ClojureScript tests. To add new test namespaces, add them to the `:require` and `doo-tests` clauses below." (:require [brewtility.calculations-test] @@ -27,6 +27,7 @@ [brewtility.predicates.impl-test] [brewtility.predicates.mash-test] [brewtility.predicates.miscs-test] + [brewtility.predicates.options-test] [brewtility.predicates.recipes-test] [brewtility.predicates.styles-test] [brewtility.predicates.waters-test] @@ -68,6 +69,7 @@ 'brewtility.predicates.impl-test 'brewtility.predicates.mash-test 'brewtility.predicates.miscs-test + 'brewtility.predicates.options-test 'brewtility.predicates.recipes-test 'brewtility.predicates.styles-test 'brewtility.predicates.waters-test From 56bd49d1a2e7addf14615c5d5bb4b096f9cf8e3c Mon Sep 17 00:00:00 2001 From: nnichols Date: Sun, 3 Mar 2024 17:57:28 +0000 Subject: [PATCH 36/44] [Format] Auto-formatting --- src/brewtility/enrich/impl.cljc | 14 ++++++++------ src/brewtility/predicates/equipment.cljc | 4 +++- test/brewtility/enrich/impl_test.cljc | 1 + test/brewtility/predicates/options_test.cljc | 1 + 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 840449e..ef8431b 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -26,10 +26,12 @@ "The key to source data from in `enrich-displayable-*` functions" :value-key) + (def low-value-key "The key to source data from in `enrich-displayable-*` functions for the lower end of the range" :low-value-key) + (def high-value-key "The key to source data from in `enrich-displayable-*` functions for the higher end of the range" :high-value-key) @@ -395,12 +397,12 @@ precision (or fine-grain-precision precision) suffix (or fine-grain-suffix suffix) opts (parse-enrich-displayable-units-opts - measurement-type - {:target-units target-units - :source-units source-units - options/system-of-measure system-of-measure - options/precision precision - options/suffix suffix}) + measurement-type + {:target-units target-units + :source-units source-units + options/system-of-measure system-of-measure + options/precision precision + options/suffix suffix}) converted-low-value (units/convert measurement-type low-source-value source-units target-units {options/precision precision}) displayable-high-value (->displayable-units measurement-type high-source-value source-units target-units opts) displayable-range (str converted-low-value " - " displayable-high-value)] diff --git a/src/brewtility/predicates/equipment.cljc b/src/brewtility/predicates/equipment.cljc index 193a469..d235ecc 100644 --- a/src/brewtility/predicates/equipment.cljc +++ b/src/brewtility/predicates/equipment.cljc @@ -16,7 +16,9 @@ In the BeerXML spec, this behavior is implicitly falsey. Therefore, if the :calc-boil-volume field is not present, this function will explicitly return false." {:added "1.5"} - ([equipment] (calculated-boil-volume? equipment {})) ; Added to match the arity of the other predicate functions + ([equipment] (calculated-boil-volume? equipment {})) +; Added to match the arity of the other predicate functions + ([equipment _opts] (if (contains? equipment :calc-boil-volume) (:calc-boil-volume equipment) diff --git a/test/brewtility/enrich/impl_test.cljc b/test/brewtility/enrich/impl_test.cljc index ebda0e6..2b060dc 100644 --- a/test/brewtility/enrich/impl_test.cljc +++ b/test/brewtility/enrich/impl_test.cljc @@ -876,6 +876,7 @@ sut/value-key :value sut/fine-grain-target-units options/pound}))))))) + (deftest enrich-displayable-range-test (testing "Validate displayable range enrichment." (testing "If neither value is provided, return the original map." diff --git a/test/brewtility/predicates/options_test.cljc b/test/brewtility/predicates/options_test.cljc index b980c33..07e0ea8 100644 --- a/test/brewtility/predicates/options_test.cljc +++ b/test/brewtility/predicates/options_test.cljc @@ -3,6 +3,7 @@ #? (:cljs [cljs.test :refer-macros [deftest is testing]]) [brewtility.predicates.options :as sut])) + (deftest type-test (testing "A sanity test for all option keywords" (is (keyword? sut/uppercase?)))) From 4ab767bf71910b4ac595c33fd596fd20c602c7b5 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 18:56:59 +0000 Subject: [PATCH 37/44] Begin accumulating changes for sealog --- .sealog/changes/2-1-0.edn | 12 +++ package-lock.json | 4 +- package.json | 2 +- pom.xml | 4 +- project.clj | 2 +- src/brewtility/enrich/impl.cljc | 10 ++- src/brewtility/enrich/styles.cljc | 123 ++++++++++++++++++++++----- src/brewtility/units.cljc | 9 +- src/brewtility/units/bitterness.cljc | 78 +++++++++++++++++ src/brewtility/units/options.cljc | 18 +++- 10 files changed, 230 insertions(+), 32 deletions(-) create mode 100644 .sealog/changes/2-1-0.edn create mode 100644 src/brewtility/units/bitterness.cljc diff --git a/.sealog/changes/2-1-0.edn b/.sealog/changes/2-1-0.edn new file mode 100644 index 0000000..6e971a0 --- /dev/null +++ b/.sealog/changes/2-1-0.edn @@ -0,0 +1,12 @@ +{:version {:major 2 + :minor 1 + :patch 0} + :version-type :semver3 + :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values" + "`brewtility.predicates.options` for option map keys shared across predicate namespaces."] + :changed ["Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." + "Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." + "`brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value." + "All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent."] + :removed ["`^:const` metadata has been removed from conversion maps"]} + :timestamp "2024-03-03T18:47:13.522931300Z"} diff --git a/package-lock.json b/package-lock.json index 85e61dd..79ff4e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "brewtility", - "version": "2.0.1", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "brewtility", - "version": "2.0.1", + "version": "2.1.0", "license": "MIT", "devDependencies": { "karma": "^6.3.16", diff --git a/package.json b/package.json index 3a45f00..ba98fc5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "brewtility", - "version": "2.0.1", + "version": "2.1.0", "description": "Utility functions for all of your brewing needs.", "main": "index.js", "directories": { diff --git a/pom.xml b/pom.xml index 1e9929a..81b5a8b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.wallbrew brewtility jar - 2.0.1 + 2.1.0 brewtility Utility functions for all of your brewing needs. https://github.com/Wall-Brew-Co/brewtility @@ -20,7 +20,7 @@ https://github.com/Wall-Brew-Co/brewtility scm:git:git://github.com/Wall-Brew-Co/brewtility.git scm:git:ssh://git@github.com/Wall-Brew-Co/brewtility.git - 0c12a150d6a7e185d1d1887bc8580aecf44dadf6 + 56bd49d1a2e7addf14615c5d5bb4b096f9cf8e3c src diff --git a/project.clj b/project.clj index 0023b39..476754e 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject com.wallbrew/brewtility "2.0.1" +(defproject com.wallbrew/brewtility "2.1.0" :description "Utility functions for all of your brewing needs." :url "https://github.com/Wall-Brew-Co/brewtility" :license {:name "MIT" diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index ef8431b..607d731 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -6,6 +6,7 @@ :added "2.1" :implementation-only true} (:require [brewtility.units :as units] + [brewtility.units.bitterness :as bitterness] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -18,7 +19,7 @@ (def default-display-options "The default display options used for all enrichers." - {options/precision 3 + {options/precision options/default-precision options/suffix options/short}) @@ -56,6 +57,13 @@ "The suffix to use for fine-grain setting of precision in `enrich-displayable-*` functions" :fine-grain-suffix) +(def default-bitterness-by-system + "The default bitterness to use for each system in `enrich-displayable-*` functions." + {options/imperial options/ibu + options/metric options/ibu + options/us-customary options/ibu + options/international-system options/ibu}) + (def default-color-by-system "The default color to use for each system in `enrich-displayable-*` functions." diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index 2f8363e..b2af6d9 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -19,20 +19,20 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:system-of-measure`: The unit system of measure to convert the minimum gravity into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the minimum gravity Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-og-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-og-min-target-units`: The unit to convert the minimum gravity into. Supersedes `:system-of-measure`. - `:style-display-og-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-og-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-og-min-suffix`: The suffix type to append to the minimum gravity. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -57,20 +57,20 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: - - `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: + - `:system-of-measure`: The unit system of measure to convert the maximum gravity into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the maximum gravity Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-og-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-og-max-target-units`: The unit to convert the maximum gravity into. Supersedes `:system-of-measure`. - `:style-display-og-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-og-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-og-max-suffix`: The suffix type to append to the maximum gravity. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -95,21 +95,21 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: -- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: +- `:system-of-measure`: The unit system of measure to convert the minimum gravity into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the minimum gravity Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-fg-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-fg-min-target-units`: The unit to convert the minimum gravity into. Supersedes `:system-of-measure`. - `:style-display-fg-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-fg-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-fg-min-suffix`: The suffix type to append to the minimum gravity. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -134,21 +134,21 @@ An option map may be passed as an optional second argument to this function to override the default behavior. Supported keys include: -- `:system-of-measure`: The unit system of measure to convert the min-temperature into. Defaults to `:us`. Acceptable values are: +- `:system-of-measure`: The unit system of measure to convert the maximum gravity into. Defaults to `:us`. Acceptable values are: - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the maximum gravity Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-fg-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-fg-max-target-units`: The unit to convert the maximum gravity into. Supersedes `:system-of-measure`. - `:style-display-fg-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-fg-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-fg-max-suffix`: The suffix type to append to the maximum gravity. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -180,14 +180,14 @@ - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the minimum color Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-color-min-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-color-min-target-units`: The unit to convert the minimum color into. Supersedes `:system-of-measure`. - `:style-display-color-min-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-color-min-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-color-min-suffix`: The suffix type to append to the minimum color. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -220,14 +220,14 @@ - `:rgba` - USe the [RGBa](https://www.w3schools.com/cssref/func_rgba.asp) color system, commonly used in CSS. - `:precision`: The number of significant decimal places to display. Defaults to 3. - - `:suffix`: The suffix type to append to the min-temperature Defaults to `:short`. Acceptable values are: + - `:suffix`: The suffix type to append to the maximum color Defaults to `:short`. Acceptable values are: - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: - - `:style-display-color-max-target-units`: The unit to convert the min-temperature into. Supersedes `:system-of-measure`. + - `:style-display-color-max-target-units`: The unit to convert the maximum color into. Supersedes `:system-of-measure`. - `:style-display-color-max-precision`: The number of significant decimal places to display. Supersedes `:precision`. - - `:style-display-color-max-suffix`: The suffix type to append to the min-temperature. Supersedes `:suffix`." + - `:style-display-color-max-suffix`: The suffix type to append to the maximum color. Supersedes `:suffix`." {:added "2.1" :see-also ["enrich-style" "enrich-style-wrapper" @@ -245,3 +245,82 @@ impl/fine-grain-precision style-display-color-max-precision impl/fine-grain-suffix style-display-color-max-suffix})] (impl/enrich-displayable-units options/color style options)))) + +(defn enrich-og-range + "An enricher pattern function to render a human-readable display original gravity ranges for a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the gravity range into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the gravity range Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-og-range-target-units`: The unit to convert the gravity range into. Supersedes `:system-of-measure`. + - `:style-display-og-range-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-og-range-suffix`: The suffix type to append to the gravity range. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-og-range style {})) + ([style {:keys [style-display-og-range-target-units + style-display-og-range-precision + style-display-og-range-suffix] + :as opts}] + (let [options (merge opts {impl/low-value-key :og-min + impl/high-value-key :og-max + impl/display-key :og-range + impl/fine-grain-target-units style-display-og-range-target-units + impl/fine-grain-precision style-display-og-range-precision + impl/fine-grain-suffix style-display-og-range-suffix})] + (impl/enrich-displayable-range options/specific-gravity style options)))) + +(defn enrich-fg-range + "An enricher pattern function to render a human-readable display final gravity ranges for a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. + + An option map may be passed as an optional second argument to this function to override the default behavior. + Supported keys include: + + - `:system-of-measure`: The unit system of measure to convert the gravity range into. Defaults to `:us`. Acceptable values are: + - `:imperial`: The [British imperial](https://en.wikipedia.org/wiki/Imperial_units) system of measure. + - `:metric`: The [metric system](https://en.wikipedia.org/wiki/Metric_system) of measure. + - `:us`: The [United States Customary Units](https://en.wikipedia.org/wiki/United_States_customary_units) system of measure. + - `:si`: The [International System of Units](https://en.wikipedia.org/wiki/International_System_of_Units) system of measure. + - `:precision`: The number of significant decimal places to display. Defaults to 3. + - `:suffix`: The suffix type to append to the gravity range Defaults to `:short`. Acceptable values are: + - `:short`: A customary abbreviation for the selected unit. For example, `\"lb\"` for `\"pounds\"`. + - `:full`: The full name of the selected unit. For example, `\"gram\"` for `\"gram\"`. + + To support fine-grained selections within the context of `enrich-style` and `enrich-style-wrapper`, this function also supports the following keys: + - `:style-display-fg-range-target-units`: The unit to convert the gravity range into. Supersedes `:system-of-measure`. + - `:style-display-fg-range-precision`: The number of significant decimal places to display. Supersedes `:precision`. + - `:style-display-fg-range-suffix`: The suffix type to append to the gravity range. Supersedes `:suffix`." + {:added "2.1" + :see-also ["enrich-style" + "enrich-style-wrapper" + "enrich-styles" + "enrich-styles-wrapper"]} + ([style] (enrich-fg-range style {})) + ([style {:keys [style-display-fg-range-target-units + style-display-fg-range-precision + style-display-fg-range-suffix] + :as opts}] + (let [options (merge opts {impl/low-value-key :fg-min + impl/high-value-key :fg-max + impl/display-key :fg-range + impl/fine-grain-target-units style-display-fg-range-target-units + impl/fine-grain-precision style-display-fg-range-precision + impl/fine-grain-suffix style-display-fg-range-suffix})] + (impl/enrich-displayable-range options/specific-gravity style options)))) + + +;;; NOTE CARB AND ABV MIN/MAXES ARE OPTIONAL diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 4561f0d..5e0651a 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -20,6 +20,7 @@ {:added "1.0" :changed "2.0"} (:require [brewtility.precision :as precision] + [brewtility.units.bitterness :as bitterness] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -45,7 +46,8 @@ This function accepts an option map as an optional fourth argument. The following options are available: - `precision`: The number of decimal places to round to. Defaults to the precision of the converted value." {:added "2.0" - :see-also ["brewtility.units.color/convert" + :see-also ["brewtility.units.bitterness/convert" + "brewtility.units.color/convert" "brewtility.units.pressure/convert" "brewtility.units.specific-gravity/convert" "brewtility.units.temperature/convert" @@ -56,6 +58,7 @@ (convert measurement-type measurement source-units target-units {})) ([measurement-type measurement source-units target-units {:keys [precision]}] (let [converted-value (case measurement-type + :bitterness (bitterness/convert measurement source-units target-units) :color (color/convert measurement source-units target-units) :pressure (pressure/convert measurement source-units target-units) :specific-gravity (specific-gravity/convert measurement source-units target-units) @@ -85,7 +88,8 @@ - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`." {:added "2.0" - :see-also ["brewtility.units.color/display" + :see-also ["brewtility.units.bitterness/display" + "brewtility.units.color/display" "brewtility.units.pressure/display" "brewtility.units.specific-gravity/display" "brewtility.units.temperature/display" @@ -99,6 +103,7 @@ (let [options (merge {options/precision options/default-precision options/suffix options/short} opts)] (case measurement-type + :bitterness (bitterness/display measurement source-units options) :color (color/display measurement source-units options) :pressure (pressure/display measurement source-units options) :specific-gravity (specific-gravity/display measurement source-units options) diff --git a/src/brewtility/units/bitterness.cljc b/src/brewtility/units/bitterness.cljc new file mode 100644 index 0000000..3ede155 --- /dev/null +++ b/src/brewtility/units/bitterness.cljc @@ -0,0 +1,78 @@ +(ns brewtility.units.bitterness + "A namespace for converting between different units of international bitterness units (IBU). + + In the BeerXML spec, IBU is a measure of the bitterness of beer, which is determined by the quantity, type, and timing of hops used in brewing. + This namespace converts between that measure and other units. + + Currently, brewtility supports the following types of IBU: + - [international-bitterness-units](https://en.wikipedia.org/wiki/International_bitterness_units)" + {:added "2.1"} + (:require [brewtility.precision :as precision] + [brewtility.units.options :as options])) + +(def measurements + "The IBU systems available across brewtility." + #{options/ibu}) + +(def measurements->display-name + "A map from IBU system names to their full and short unit names." + {options/ibu {options/full "international bitterness units" + options/short "ibu"}}) + +(def measurement->ibu + "A map from IBU system names to the conversion function to IBU." + {options/ibu identity}) + +(def ibu->measurement + "A map from IBU system names to the conversion function from IBU." + {options/ibu identity}) + +(defn convert + "Given a `bitterness` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[bitterness-measurements]]. + This function will throw an exception if unsupported measurement values are passed." + {:added "2.1"} + [bitterness source-measurement target-measurement] + (if (and (contains? measurements source-measurement) + (contains? measurements target-measurement) + (number? bitterness)) + (if (= source-measurement target-measurement) + bitterness + (let [source->ibu-fn (measurement->ibu source-measurement) + ibu->target-fn (ibu->measurement target-measurement)] + (-> bitterness source->ibu-fn ibu->target-fn))) + (throw (ex-info "Unsupported bitterness conversion units" + {:source-measurement source-measurement + :target-measurement target-measurement + :allowed-values measurements + :bitterness bitterness})))) + +(defn display + "A function to render a human-readable `bitterness` in `source-units`. + + For example, + ```clj + (display 10 options/ibu) + ;; => \"10 ibu\" + ```" + {:added "2.1"} + ([bitterness source-units] + (display bitterness source-units {})) + ([bitterness source-units {:keys [precision suffix] + :or {precision options/default-precision + suffix options/short}}] + (if (and (contains? measurements source-units) + (number? bitterness) + (integer? precision) + (contains? options/supported-suffixes suffix)) + (let [display-name (get-in measurements->display-name [source-units suffix])] + (-> bitterness + (precision/->precision precision) + (str " " display-name))) + (throw (ex-info "Unsupported bitterness display units" + {:source-units source-units + :allowed-values measurements + :bitterness bitterness + :precision precision + :suffix suffix + :supported-suffixes options/supported-suffixes}))))) diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 6596a26..98663e5 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -115,6 +115,14 @@ "A set of supported suffix types." #{short full}) +(def bitterness + "The bitterness systems used in the recipe or for a given unit. + + Commonly used with `brewtility.units.bitterness` and in argument/option maps. + Currently, brewtility supports the following types of bitterness: + - [international-bitterness-units](https://en.wikipedia.org/wiki/International_bitterness_units)" + :bitterness) + (def color "The color systems used in the recipe or for a given unit. @@ -217,7 +225,8 @@ (def measurement-types "The measurement types available across brewtility." - #{color + #{bitterness + color pressure specific-gravity temperature @@ -225,6 +234,13 @@ volume weight}) +;; Bitterness Systems +(def ibu + "The [International Bitterness Units](https://en.wikipedia.org/wiki/International_bitterness_units) system of measure. + + Commonly used with `brewtility.units.bitterness` and in argument/option maps." + :ibu) + ;; Color Systems From b2d9c27a90f12806fbc8915e52009580eed539fa Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 18:59:12 +0000 Subject: [PATCH 38/44] Document bitterness unit --- doc/api/units.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/api/units.md b/doc/api/units.md index b62953e..d9d7cc2 100644 --- a/doc/api/units.md +++ b/doc/api/units.md @@ -76,6 +76,7 @@ Brewtility supports four systems of measure: These are the most commonly seen systems in brewing. There are measurement functions for the most common types of measurements within these systems: +- [Bitterness](##bitterness) - [Color](##color) - [Pressure](##pressure) - [Specific Gravity](##specific-gravity) @@ -84,6 +85,15 @@ There are measurement functions for the most common types of measurements within - [Volume](##volume) - [Weight](##weight) +### Bitterness + +Currently, brewtility supports the following bitterness measurements: + +- [IBU](https://en.wikipedia.org/wiki/International_bitterness_units) + +While there is currently only one system, the same namespace and functionality exists as the other measurement types. +This allows for progressive evolution, and provides a consistent interface to every measurement type encoded in the BeerXML specification. + ### Color Currently, brewtility supports the following types of color: @@ -93,10 +103,6 @@ Currently, brewtility supports the following types of color: - [Lovibond](https://en.wikipedia.org/wiki/Beer_measurement#Colour) - [RGBa](https://en.wikipedia.org/wiki/RGBA_color_model) -The `RGBa` system is special, as it can only be used as an argument for the result of a unit conversion. -Unfortunately, there is not a great deterministic way to cast the values back to the other systems. -brewtility will thrown an exception in this case and explain the problem. - ### Pressure Currently, brewtility supports the following types of pressure: From 81bbea0b00aea1c8dfa130b814732685d700d3e6 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 19:12:23 +0000 Subject: [PATCH 39/44] Add carbonation units --- .sealog/changes/2-1-0.edn | 17 ++--- CHANGELOG.md | 15 ++++ doc/api/units.md | 10 ++- src/brewtility/units.cljc | 7 ++ src/brewtility/units/carbonation.cljc | 100 ++++++++++++++++++++++++++ src/brewtility/units/options.cljc | 23 ++++++ 6 files changed, 163 insertions(+), 9 deletions(-) create mode 100644 src/brewtility/units/carbonation.cljc diff --git a/.sealog/changes/2-1-0.edn b/.sealog/changes/2-1-0.edn index 6e971a0..eecd44e 100644 --- a/.sealog/changes/2-1-0.edn +++ b/.sealog/changes/2-1-0.edn @@ -2,11 +2,12 @@ :minor 1 :patch 0} :version-type :semver3 - :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values" - "`brewtility.predicates.options` for option map keys shared across predicate namespaces."] - :changed ["Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." - "Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." - "`brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value." - "All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent."] - :removed ["`^:const` metadata has been removed from conversion maps"]} - :timestamp "2024-03-03T18:47:13.522931300Z"} + :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values" + "`brewtility.units.carbonation` for rendering displayable carbonation values" + "`brewtility.predicates.options` for option map keys shared across predicate namespaces."] + :changed ["Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." + "Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." + "`brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value." + "All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent."] + :removed ["`^:const` metadata has been removed from conversion maps"]} + :timestamp "2024-03-11T18:47:13.522931300Z"} diff --git a/CHANGELOG.md b/CHANGELOG.md index f1ba80a..71460f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## Table of Contents +* [2.1.0 - 2024-03-11](#210---2024-03-11) * [2.0.1 - 2024-03-11](#201---2024-03-11) * [2.0.0 - 2023-06-11](#200---2023-06-11) * [1.5.0 - 2023-02-13](#150---2023-02-13) @@ -15,6 +16,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * [1.1.0 - 2020-08-15](#110---2020-08-15) * [1.0.0 - 2020-07-19](#100---2020-07-19) +## 2.1.0 - 2024-03-11 + +* Added + * `brewtility.units.bitterness` for rendering displayable IBU values + * `brewtility.units.carbonation` for rendering displayable carbonation values + * `brewtility.predicates.options` for option map keys shared across predicate namespaces. +* Changed + * Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so. + * Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so. + * `brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value. + * All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent. +* Removed + * `^:const` metadata has been removed from conversion maps + ## 2.0.1 - 2024-03-11 * Security diff --git a/doc/api/units.md b/doc/api/units.md index d9d7cc2..762a4b9 100644 --- a/doc/api/units.md +++ b/doc/api/units.md @@ -77,6 +77,7 @@ These are the most commonly seen systems in brewing. There are measurement functions for the most common types of measurements within these systems: - [Bitterness](##bitterness) +- [Carbonation](##carbonation) - [Color](##color) - [Pressure](##pressure) - [Specific Gravity](##specific-gravity) @@ -94,6 +95,13 @@ Currently, brewtility supports the following bitterness measurements: While there is currently only one system, the same namespace and functionality exists as the other measurement types. This allows for progressive evolution, and provides a consistent interface to every measurement type encoded in the BeerXML specification. +### Carbonation + +Currently, brewtility supports the following carbonation measurements: + +- [Volumes of CO2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) +- [Grams per Liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) + ### Color Currently, brewtility supports the following types of color: @@ -166,7 +174,7 @@ Currently, brewtility supports the following types of volume: - [tablespoon](https://en.wikipedia.org/wiki/Tablespoon) - [teaspoon](https://en.wikipedia.org/wiki/Teaspoon)) -Given the prevalence of the French spellings in English recipes, both `:litre` and `:liter` can be passed as options. +Given the prevalence of the non-US spellings in English recipes, both `:litre` and `:liter` can be passed as options. ### Weight diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 5e0651a..17b18d1 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -3,6 +3,8 @@ Currently, brewtility supports the following types of measurements: + - [Bitterness](https://en.wikipedia.org/wiki/Beer_measurement#Bitterness) + - [Carbonation](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) - [Color](https://en.wikipedia.org/wiki/Beer_measurement#Colour) - [Pressure](https://en.wikipedia.org/wiki/Pressure) - [Specific Gravity](https://en.wikipedia.org/wiki/Relative_density) @@ -21,6 +23,7 @@ :changed "2.0"} (:require [brewtility.precision :as precision] [brewtility.units.bitterness :as bitterness] + [brewtility.units.carbonation :as carbonation] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -47,6 +50,7 @@ - `precision`: The number of decimal places to round to. Defaults to the precision of the converted value." {:added "2.0" :see-also ["brewtility.units.bitterness/convert" + "brewtility.units.carbonation/convert" "brewtility.units.color/convert" "brewtility.units.pressure/convert" "brewtility.units.specific-gravity/convert" @@ -59,6 +63,7 @@ ([measurement-type measurement source-units target-units {:keys [precision]}] (let [converted-value (case measurement-type :bitterness (bitterness/convert measurement source-units target-units) + :carbonation (carbonation/convert measurement source-units target-units) :color (color/convert measurement source-units target-units) :pressure (pressure/convert measurement source-units target-units) :specific-gravity (specific-gravity/convert measurement source-units target-units) @@ -89,6 +94,7 @@ - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`." {:added "2.0" :see-also ["brewtility.units.bitterness/display" + "brewtility.units.carbonation/display" "brewtility.units.color/display" "brewtility.units.pressure/display" "brewtility.units.specific-gravity/display" @@ -104,6 +110,7 @@ options/suffix options/short} opts)] (case measurement-type :bitterness (bitterness/display measurement source-units options) + :carbonation (carbonation/display measurement source-units options) :color (color/display measurement source-units options) :pressure (pressure/display measurement source-units options) :specific-gravity (specific-gravity/display measurement source-units options) diff --git a/src/brewtility/units/carbonation.cljc b/src/brewtility/units/carbonation.cljc new file mode 100644 index 0000000..d678b59 --- /dev/null +++ b/src/brewtility/units/carbonation.cljc @@ -0,0 +1,100 @@ +(ns brewtility.units.carbonation + "A namespace for converting between different units of carbonation. + + In the BeerXML spec, carbonation is a measure of the amount of carbon dioxide dissolved in beer. + This namespace converts between that measure and other units. + + Currently, brewtility supports the following types of carbonation: + - [volumes-of-co2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) + - [grams-per-liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages)" + {:added "2.1"} + (:require [brewtility.precision :as precision] + [brewtility.units.options :as options])) + +(def measurements + "The carbonation systems available across brewtility." + #{options/volumes-of-co2 options/grams-per-liter}) + +(def measurements->display-name + "A map from carbonation system names to their full and short unit names." + {options/volumes-of-co2 {options/full "volumes of CO2" + options/short "vols"} + options/grams-per-liter {options/full "grams per liter" + options/short "g/L"}}) + +(defn- volumes-of-co2->grams-per-liter + "An implementation function to convert `volumes-of-co2` to grams per liter" + {:no-doc true + :added "2.1"} + [volumes-of-co2] + (* 1.96 volumes-of-co2)) + + +(defn- grams-per-liter->volumes-of-co2 + "An implementation function to convert `grams-per-liter` to volumes of CO2" + {:no-doc true + :added "2.1"} + [grams-per-liter] + (/ grams-per-liter 1.96)) + +(def measurement->volumes-of-co2 + "A map from carbonation system names to the conversion function to volumes of CO2." + {options/volumes-of-co2 identity + options/grams-per-liter volumes-of-co2->grams-per-liter}) + +(def volumes-of-co2->measurement + "A map from carbonation system names to the conversion function from volumes of CO2." + {options/volumes-of-co2 identity + options/grams-per-liter grams-per-liter->volumes-of-co2}) + + +(defn convert + "Given a `carbonation` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[carbonation-measurements]]. + This function will throw an exception if unsupported measurement values are passed." + {:added "2.1"} + [carbonation source-measurement target-measurement] + (if (and (contains? measurements source-measurement) + (contains? measurements target-measurement) + (number? carbonation)) + (if (= source-measurement target-measurement) + carbonation + (let [source->volumes-of-co2-fn (measurement->volumes-of-co2 source-measurement) + volumes-of-co2->target-fn (volumes-of-co2->measurement target-measurement)] + (-> carbonation source->volumes-of-co2-fn volumes-of-co2->target-fn))) + (throw (ex-info "Unsupported carbonation conversion units" + {:source-measurement source-measurement + :target-measurement target-measurement + :allowed-values measurements + :carbonation carbonation})))) + +(defn display + "A function to render a human-readable `carbonation` in `source-units`. + + For example, + ```clj + (display 10 options/volumes-of-co2) + ;; => \"10 vols\" + ```" + {:added "2.1"} + ([carbonation source-units] + (display carbonation source-units {})) + ([carbonation source-units {:keys [precision suffix] + :or {precision options/default-precision + suffix options/short}}] + (if (and (contains? measurements source-units) + (number? carbonation) + (integer? precision) + (contains? options/supported-suffixes suffix)) + (let [display-name (get-in measurements->display-name [source-units suffix])] + (-> carbonation + (convert source-units options/volumes-of-co2) + (precision/->precision precision) + (str display-name suffix))) + (throw (ex-info "Unsupported carbonation display units" + {:source-units source-units + :allowed-values measurements + :carbonation carbonation + :precision precision + :suffix suffix + :supported-suffixes options/supported-suffixes}))))) diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 98663e5..b6d65a2 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -123,6 +123,15 @@ - [international-bitterness-units](https://en.wikipedia.org/wiki/International_bitterness_units)" :bitterness) +(def carbonation + "The carbonation systems used in the recipe or for a given unit. + + Commonly used with `brewtility.units.carbonation` and in argument/option maps. + Currently, brewtility supports the following types of carbonation: + - [volumes-of-co2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) + - [grams-per-liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages)" + :carbonation) + (def color "The color systems used in the recipe or for a given unit. @@ -226,6 +235,7 @@ (def measurement-types "The measurement types available across brewtility." #{bitterness + carbonation color pressure specific-gravity @@ -241,6 +251,19 @@ Commonly used with `brewtility.units.bitterness` and in argument/option maps." :ibu) +;; Carbonation Systems +(def volumes-of-co2 + "The [volumes of CO2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) system of measure. + + Commonly used with `brewtility.units.carbonation` and in argument/option maps." + :volumes-of-co2) + +(def grams-per-liter + "The [grams per liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) system of measure. + + Commonly used with `brewtility.units.carbonation` and in argument/option maps." + :grams-per-liter) + ;; Color Systems From 96ee281ab4aece46e652f23ac8acc82a9d5d3c31 Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Sun, 3 Mar 2024 20:52:42 +0000 Subject: [PATCH 40/44] Add tests for new unit systems --- src/brewtility/enrich/impl.cljc | 32 +++++++---- src/brewtility/enrich/styles.cljc | 4 +- src/brewtility/predicates/equipment.cljc | 2 +- src/brewtility/units/bitterness.cljc | 24 +++++---- src/brewtility/units/carbonation.cljc | 48 +++++++++-------- src/brewtility/units/options.cljc | 5 ++ test/brewtility/runner.cljs | 4 ++ test/brewtility/units/bitterness_test.cljc | 55 +++++++++++++++++++ test/brewtility/units/carbonation_test.cljc | 59 +++++++++++++++++++++ 9 files changed, 192 insertions(+), 41 deletions(-) create mode 100644 test/brewtility/units/bitterness_test.cljc create mode 100644 test/brewtility/units/carbonation_test.cljc diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 607d731..7ebe64b 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -7,6 +7,7 @@ :implementation-only true} (:require [brewtility.units :as units] [brewtility.units.bitterness :as bitterness] + [brewtility.units.carbonation :as carbonation] [brewtility.units.color :as color] [brewtility.units.options :as options] [brewtility.units.pressure :as pressure] @@ -57,6 +58,7 @@ "The suffix to use for fine-grain setting of precision in `enrich-displayable-*` functions" :fine-grain-suffix) + (def default-bitterness-by-system "The default bitterness to use for each system in `enrich-displayable-*` functions." {options/imperial options/ibu @@ -65,6 +67,14 @@ options/international-system options/ibu}) +(def default-carbonation-by-system + "The default carbonation to use for each system in `enrich-displayable-*` functions." + {options/imperial options/volumes-of-co2 + options/metric options/volumes-of-co2 + options/us-customary options/volumes-of-co2 + options/international-system options/volumes-of-co2}) + + (def default-color-by-system "The default color to use for each system in `enrich-displayable-*` functions." {options/imperial options/srm @@ -123,7 +133,9 @@ (def beer-xml-standard-units "The standard units for each measurement type in BeerXML." - {options/color options/srm + {options/bitterness options/ibu + options/carbonation options/volumes-of-co2 + options/color options/srm options/pressure options/kilopascal options/specific-gravity options/specific-gravity options/temperature options/celsius @@ -153,6 +165,8 @@ "suffix-error"]} [error-map conversion-type target-units] (let [allowed-values (case conversion-type + :bitterness bitterness/measurements + :carbonation carbonation/measurements :color color/measurements :pressure pressure/measurements :specific-gravity specific-gravity/measurements @@ -182,6 +196,8 @@ "target-unit-error"]} [error-map conversion-type source-units] (let [allowed-values (case conversion-type + :bitterness bitterness/measurements + :carbonation carbonation/measurements :color color/measurements :pressure pressure/measurements :specific-gravity specific-gravity/measurements @@ -257,6 +273,8 @@ :no-doc false} [measurement-type unit] (case measurement-type + :bitterness (contains? bitterness/measurements unit) + :carbonation (contains? carbonation/measurements unit) :color (contains? color/measurements unit) :pressure (contains? pressure/measurements unit) :specific-gravity (contains? specific-gravity/measurements unit) @@ -275,7 +293,7 @@ If any of these are invalid, a Java Exception or Javascript Error is thrown with information on the invalid options." {:added "2.1" :no-doc true - :see-also ["enrich-displayable-pressure"]} + :see-also ["enrich-displayable-units"]} [measurement-type {:keys [target-units source-units system-of-measure precision suffix] :as opts}] @@ -300,16 +318,12 @@ If the measurement type is not supported, a Java Exception or Javascript Error is thrown with information on the invalid options." {:added "2.1" :no-doc true - :see-also ["enrich-displayable-color" - "enrich-displayable-pressure" - "enrich-displayable-specific-gravity" - "enrich-displayable-temperature" - "enrich-displayable-time" - "enrich-displayable-volume" - "enrich-displayable-weight" + :see-also ["enrich-displayable-units" "enrich-displayable-range"]} [measurement-type system-of-measure] (case measurement-type + :bitterness (get default-bitterness-by-system system-of-measure) + :carbonation (get default-carbonation-by-system system-of-measure) :color (get default-color-by-system system-of-measure) :pressure (get default-pressure-by-system system-of-measure) :specific-gravity (get default-specific-gravity-by-system system-of-measure) diff --git a/src/brewtility/enrich/styles.cljc b/src/brewtility/enrich/styles.cljc index b2af6d9..a3e364b 100644 --- a/src/brewtility/enrich/styles.cljc +++ b/src/brewtility/enrich/styles.cljc @@ -246,6 +246,7 @@ impl/fine-grain-suffix style-display-color-max-suffix})] (impl/enrich-displayable-units options/color style options)))) + (defn enrich-og-range "An enricher pattern function to render a human-readable display original gravity ranges for a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. @@ -284,6 +285,7 @@ impl/fine-grain-suffix style-display-og-range-suffix})] (impl/enrich-displayable-range options/specific-gravity style options)))) + (defn enrich-fg-range "An enricher pattern function to render a human-readable display final gravity ranges for a [style](https://github.com/Wall-Brew-Co/common-beer-format/blob/master/src/common_beer_format/style.cljc) is in a given system. @@ -323,4 +325,4 @@ (impl/enrich-displayable-range options/specific-gravity style options)))) -;;; NOTE CARB AND ABV MIN/MAXES ARE OPTIONAL +;; NOTE CARB AND ABV MIN/MAXES ARE OPTIONAL diff --git a/src/brewtility/predicates/equipment.cljc b/src/brewtility/predicates/equipment.cljc index d235ecc..36559c8 100644 --- a/src/brewtility/predicates/equipment.cljc +++ b/src/brewtility/predicates/equipment.cljc @@ -17,7 +17,7 @@ Therefore, if the :calc-boil-volume field is not present, this function will explicitly return false." {:added "1.5"} ([equipment] (calculated-boil-volume? equipment {})) -; Added to match the arity of the other predicate functions + ;; Added to match the arity of the other predicate functions ([equipment _opts] (if (contains? equipment :calc-boil-volume) diff --git a/src/brewtility/units/bitterness.cljc b/src/brewtility/units/bitterness.cljc index 3ede155..ed5de77 100644 --- a/src/brewtility/units/bitterness.cljc +++ b/src/brewtility/units/bitterness.cljc @@ -10,22 +10,27 @@ (:require [brewtility.precision :as precision] [brewtility.units.options :as options])) + (def measurements - "The IBU systems available across brewtility." - #{options/ibu}) + "The IBU systems available across brewtility." + #{options/ibu}) + (def measurements->display-name - "A map from IBU system names to their full and short unit names." - {options/ibu {options/full "international bitterness units" - options/short "ibu"}}) + "A map from IBU system names to their full and short unit names." + {options/ibu {options/full "international bitterness units" + options/short "ibu"}}) + (def measurement->ibu - "A map from IBU system names to the conversion function to IBU." - {options/ibu identity}) + "A map from IBU system names to the conversion function to IBU." + {options/ibu identity}) + (def ibu->measurement - "A map from IBU system names to the conversion function from IBU." - {options/ibu identity}) + "A map from IBU system names to the conversion function from IBU." + {options/ibu identity}) + (defn convert "Given a `bitterness` in `source-measurement`, convert it to the `target-measurement`. @@ -47,6 +52,7 @@ :allowed-values measurements :bitterness bitterness})))) + (defn display "A function to render a human-readable `bitterness` in `source-units`. diff --git a/src/brewtility/units/carbonation.cljc b/src/brewtility/units/carbonation.cljc index d678b59..9d50799 100644 --- a/src/brewtility/units/carbonation.cljc +++ b/src/brewtility/units/carbonation.cljc @@ -11,41 +11,46 @@ (:require [brewtility.precision :as precision] [brewtility.units.options :as options])) + (def measurements - "The carbonation systems available across brewtility." - #{options/volumes-of-co2 options/grams-per-liter}) + "The carbonation systems available across brewtility." + #{options/volumes-of-co2 options/grams-per-liter}) + (def measurements->display-name - "A map from carbonation system names to their full and short unit names." - {options/volumes-of-co2 {options/full "volumes of CO2" - options/short "vols"} - options/grams-per-liter {options/full "grams per liter" - options/short "g/L"}}) + "A map from carbonation system names to their full and short unit names." + {options/volumes-of-co2 {options/full "volumes of CO2" + options/short "vols"} + options/grams-per-liter {options/full "grams per liter" + options/short "g/L"}}) + (defn- volumes-of-co2->grams-per-liter - "An implementation function to convert `volumes-of-co2` to grams per liter" - {:no-doc true - :added "2.1"} - [volumes-of-co2] - (* 1.96 volumes-of-co2)) + "An implementation function to convert `volumes-of-co2` to grams per liter" + {:no-doc true + :added "2.1"} + [volumes-of-co2] + (* 1.96 volumes-of-co2)) (defn- grams-per-liter->volumes-of-co2 - "An implementation function to convert `grams-per-liter` to volumes of CO2" - {:no-doc true - :added "2.1"} - [grams-per-liter] - (/ grams-per-liter 1.96)) + "An implementation function to convert `grams-per-liter` to volumes of CO2" + {:no-doc true + :added "2.1"} + [grams-per-liter] + (/ grams-per-liter 1.96)) + (def measurement->volumes-of-co2 "A map from carbonation system names to the conversion function to volumes of CO2." {options/volumes-of-co2 identity options/grams-per-liter volumes-of-co2->grams-per-liter}) + (def volumes-of-co2->measurement - "A map from carbonation system names to the conversion function from volumes of CO2." - {options/volumes-of-co2 identity - options/grams-per-liter grams-per-liter->volumes-of-co2}) + "A map from carbonation system names to the conversion function from volumes of CO2." + {options/volumes-of-co2 identity + options/grams-per-liter grams-per-liter->volumes-of-co2}) (defn convert @@ -68,6 +73,7 @@ :allowed-values measurements :carbonation carbonation})))) + (defn display "A function to render a human-readable `carbonation` in `source-units`. @@ -90,7 +96,7 @@ (-> carbonation (convert source-units options/volumes-of-co2) (precision/->precision precision) - (str display-name suffix))) + (str " " display-name))) (throw (ex-info "Unsupported carbonation display units" {:source-units source-units :allowed-values measurements diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index b6d65a2..57282e7 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -115,6 +115,7 @@ "A set of supported suffix types." #{short full}) + (def bitterness "The bitterness systems used in the recipe or for a given unit. @@ -123,6 +124,7 @@ - [international-bitterness-units](https://en.wikipedia.org/wiki/International_bitterness_units)" :bitterness) + (def carbonation "The carbonation systems used in the recipe or for a given unit. @@ -244,6 +246,7 @@ volume weight}) + ;; Bitterness Systems (def ibu "The [International Bitterness Units](https://en.wikipedia.org/wiki/International_bitterness_units) system of measure. @@ -251,6 +254,7 @@ Commonly used with `brewtility.units.bitterness` and in argument/option maps." :ibu) + ;; Carbonation Systems (def volumes-of-co2 "The [volumes of CO2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) system of measure. @@ -258,6 +262,7 @@ Commonly used with `brewtility.units.carbonation` and in argument/option maps." :volumes-of-co2) + (def grams-per-liter "The [grams per liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) system of measure. diff --git a/test/brewtility/runner.cljs b/test/brewtility/runner.cljs index f95ca5a..9752b63 100644 --- a/test/brewtility/runner.cljs +++ b/test/brewtility/runner.cljs @@ -33,6 +33,8 @@ [brewtility.predicates.waters-test] [brewtility.predicates.yeasts-test] [brewtility.units-test] + [brewtility.units.bitterness-test] + [brewtility.units.carbonation-test] [brewtility.units.color-test] [brewtility.units.pressure-test] [brewtility.units.specific-gravity-test] @@ -75,6 +77,8 @@ 'brewtility.predicates.waters-test 'brewtility.predicates.yeasts-test 'brewtility.units-test + 'brewtility.units.bitterness-test + 'brewtility.units.carbonation-test 'brewtility.units.color-test 'brewtility.units.pressure-test 'brewtility.units.specific-gravity-test diff --git a/test/brewtility/units/bitterness_test.cljc b/test/brewtility/units/bitterness_test.cljc new file mode 100644 index 0000000..37d1979 --- /dev/null +++ b/test/brewtility/units/bitterness_test.cljc @@ -0,0 +1,55 @@ +(ns brewtility.units.bitterness-test + (:require #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + [brewtility.precision :as precision] + [brewtility.units.bitterness :as sut] + [brewtility.units.options :as options])) + + +(deftest conversion-test + (testing "Ensure various color unit conversions behave as expected" + (is (= 100.0 + (precision/->2dp (sut/convert 100.0 options/ibu options/ibu)) + (precision/->2dp (sut/convert 100.0 :ibu :ibu))))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert 10.0 :invalid :broken)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :invalid :broken)))))) + + +(deftest display-test + (testing "Ensure various color unit conversions behave as expected" + (is (= "1.5 ibu" + (sut/display 1.5 :ibu) + (sut/display 1.5 options/ibu)))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display 10.0 :invalid)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display 10.0 :invalid)))))) + + +(deftest code-type-tests + (testing "Ensure maps used for options are structurally correct" + (testing "Measurement types" + (is (set? sut/measurements)) + (is (every? keyword? sut/measurements)) + (is (not-empty sut/measurements))) + (testing "Measurement display names" + (is (map? sut/measurements->display-name)) + (is (not-empty sut/measurements->display-name)) + (is (every? keyword? (keys sut/measurements->display-name))) + (is (every? map? (vals sut/measurements->display-name))) + (is (every? #(contains? % options/full) (vals sut/measurements->display-name))) + (is (every? #(contains? % options/short) (vals sut/measurements->display-name)))) + (testing "measurement->ibu" + (is (map? sut/measurement->ibu)) + (is (not-empty sut/measurement->ibu)) + (is (every? keyword? (keys sut/measurement->ibu))) + (is (every? ifn? (vals sut/measurement->ibu)))) + (testing "ibu->measurement" + (is (map? sut/ibu->measurement)) + (is (not-empty sut/ibu->measurement)) + (is (every? keyword? (keys sut/ibu->measurement))) + (is (= (set (keys sut/measurement->ibu)) + (set (keys sut/ibu->measurement)) + (set (keys sut/measurements->display-name)) + sut/measurements)) + (is (every? ifn? (vals sut/ibu->measurement)))))) diff --git a/test/brewtility/units/carbonation_test.cljc b/test/brewtility/units/carbonation_test.cljc new file mode 100644 index 0000000..163956f --- /dev/null +++ b/test/brewtility/units/carbonation_test.cljc @@ -0,0 +1,59 @@ +(ns brewtility.units.carbonation-test + (:require #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + [brewtility.precision :as precision] + [brewtility.units.carbonation :as sut] + [brewtility.units.options :as options])) + + +(deftest conversion-test + (testing "Ensure various color unit conversions behave as expected" + (is (= 100.0 + (precision/->2dp (sut/convert 100.0 options/volumes-of-co2 options/volumes-of-co2)) + (precision/->2dp (sut/convert 100.0 :volumes-of-co2 :volumes-of-co2)))) + (is (= 51.02 (precision/->2dp (sut/convert 100.0 options/volumes-of-co2 options/grams-per-liter)))) + (is (= 196.0 (precision/->2dp (sut/convert 100.0 options/grams-per-liter options/volumes-of-co2))))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert 10.0 :invalid :broken)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :invalid :broken)))))) + + +(deftest display-test + (testing "Ensure various color unit conversions behave as expected" + (is (= "1.5 vols" + (sut/display 1.5 :volumes-of-co2) + (sut/display 1.5 options/volumes-of-co2))) + (is (= "1.5 volumes of CO2" + (sut/display 1.5 :volumes-of-co2 {options/suffix options/full})))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display 10.0 :invalid)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display 10.0 :invalid)))))) + + +(deftest code-type-tests + (testing "Ensure maps used for options are structurally correct" + (testing "Measurement types" + (is (set? sut/measurements)) + (is (every? keyword? sut/measurements)) + (is (not-empty sut/measurements))) + (testing "Measurement display names" + (is (map? sut/measurements->display-name)) + (is (not-empty sut/measurements->display-name)) + (is (every? keyword? (keys sut/measurements->display-name))) + (is (every? map? (vals sut/measurements->display-name))) + (is (every? #(contains? % options/full) (vals sut/measurements->display-name))) + (is (every? #(contains? % options/short) (vals sut/measurements->display-name)))) + (testing "measurement->volumes-of-co2" + (is (map? sut/measurement->volumes-of-co2)) + (is (not-empty sut/measurement->volumes-of-co2)) + (is (every? keyword? (keys sut/measurement->volumes-of-co2))) + (is (every? ifn? (vals sut/measurement->volumes-of-co2)))) + (testing "volumes-of-co2->measurement" + (is (map? sut/volumes-of-co2->measurement)) + (is (not-empty sut/volumes-of-co2->measurement)) + (is (every? keyword? (keys sut/volumes-of-co2->measurement))) + (is (= (set (keys sut/measurement->volumes-of-co2)) + (set (keys sut/volumes-of-co2->measurement)) + (set (keys sut/measurements->display-name)) + sut/measurements)) + (is (every? ifn? (vals sut/volumes-of-co2->measurement)))))) From bc0fff636c2aac0b7688631ed6f5479750cb39ff Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Wed, 6 Mar 2024 14:24:40 +0000 Subject: [PATCH 41/44] Add degrees plato --- .sealog/changes/2-1-0.edn | 5 +-- src/brewtility/units/options.cljc | 8 +++++ src/brewtility/units/specific_gravity.cljc | 30 +++++++++++++---- .../units/specific_gravity_test.cljc | 32 +++++++++++++++---- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/.sealog/changes/2-1-0.edn b/.sealog/changes/2-1-0.edn index eecd44e..c47bac5 100644 --- a/.sealog/changes/2-1-0.edn +++ b/.sealog/changes/2-1-0.edn @@ -2,8 +2,9 @@ :minor 1 :patch 0} :version-type :semver3 - :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values" - "`brewtility.units.carbonation` for rendering displayable carbonation values" + :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values." + "`brewtility.units.carbonation` for rendering displayable carbonation values." + "`brewtility.units.specific-gravity` now supports measurements in degrees plato." "`brewtility.predicates.options` for option map keys shared across predicate namespaces."] :changed ["Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." "Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 57282e7..886846c 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -299,6 +299,14 @@ Commonly used with `brewtility.units.color` and in argument/option maps." :rgba) +;; Specific Gravity Units + +(def plato + "The [Degrees Plato](https://en.wikipedia.org/wiki/Plato_scale#Extract) system of measure. + + Commonly used with `brewtility.units.specific-gravity` and in argument/option maps." + :plato) + ;; Volume Units diff --git a/src/brewtility/units/specific_gravity.cljc b/src/brewtility/units/specific_gravity.cljc index 759d673..a499d1f 100644 --- a/src/brewtility/units/specific_gravity.cljc +++ b/src/brewtility/units/specific_gravity.cljc @@ -1,9 +1,9 @@ (ns brewtility.units.specific-gravity "A namespace for converting between different units of specific gravity. - + In the BeerXML spec, specific gravity is measured in relative to the weight of the same size sample of water. This namespace converts between that ratio and other units. - + Currently, brewtility supports the following types of specific gravity: - [specific-gravity](https://en.wikipedia.org/wiki/Specific_gravity)" {:added "2.0"} @@ -13,23 +13,41 @@ (def measurements "The specific gravity systems available across brewtility." - #{options/specific-gravity}) + #{options/specific-gravity options/plato}) (def measurements->display-name "A map from specific gravity system names to their full and short unit names." {options/specific-gravity {options/full "specific gravity" - options/short "sg"}}) + options/short "sg"} + options/plato {options/full "degrees plato" + options/short "°P"}}) + +(defn- plato->specific-gravity + "Converts a `plato` value to a `specific-gravity` value." + [plato] + (let [denom (- 258.6 (* (/ plato 258.2) 227.1))] + (+ 1 (/ plato denom)))) + +(defn- specific-gravity->plato + "Converts a `specific-gravity` value to a `plato` value." + [gravity] + (let [g1 (* 1111.14 gravity) + g2 (* 630.272 (Math/pow gravity 2)) + g3 (* 135.997 (Math/pow gravity 3))] + (- (- (+ g1 g3) g2) 616.868))) (def measurement->specific-gravity "A map from specific gravity system names to the conversion function to specific gravity." - {options/specific-gravity identity}) + {options/specific-gravity identity + options/plato plato->specific-gravity}) (def specific-gravity->measurement "A map from specific gravity system names to the conversion function from specific gravity." - {options/specific-gravity identity}) + {options/specific-gravity identity + options/plato specific-gravity->plato}) (defn convert diff --git a/test/brewtility/units/specific_gravity_test.cljc b/test/brewtility/units/specific_gravity_test.cljc index f386473..0e0da80 100644 --- a/test/brewtility/units/specific_gravity_test.cljc +++ b/test/brewtility/units/specific_gravity_test.cljc @@ -7,23 +7,43 @@ (deftest conversion-test - (testing "Ensure various color unit conversions behave as expected" + (testing "Ensure various specific gravity unit conversions behave as expected" (is (= 100.0 (precision/->2dp (sut/convert 100.0 options/specific-gravity options/specific-gravity)) - (precision/->2dp (sut/convert 100.0 :specific-gravity :specific-gravity))))) + (precision/->2dp (sut/convert 100.0 :specific-gravity :specific-gravity)))) + (is (= 100.0 + (precision/->2dp (sut/convert 100.0 options/plato options/plato)) + (precision/->2dp (sut/convert 100.0 :plato :plato)))) + (is (= 0.5 (precision/->1dp (sut/convert 1.002 options/specific-gravity options/plato)))) + (is (= 3.1 (precision/->1dp (sut/convert 1.012 options/specific-gravity options/plato)))) + (is (= 7.6 (precision/->1dp (sut/convert 1.03 options/specific-gravity options/plato)))) + (is (= 19.6 (precision/->1dp (sut/convert 1.081 options/specific-gravity options/plato)))) + (is (= 1.002 (precision/->3dp (sut/convert 0.5 options/plato options/specific-gravity)))) + (is (= 1.012 (precision/->3dp (sut/convert 3.0 options/plato options/specific-gravity)))) + (is (= 1.03 (precision/->3dp (sut/convert 7.5 options/plato options/specific-gravity)))) + (is (= 1.081 (precision/->3dp (sut/convert 19.5 options/plato options/specific-gravity))))) (testing "Invalid options throw an exception" #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert 10.0 :invalid :broken)))) - #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :invalid :broken)))))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :invalid :broken)))) + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert 10.0 :plato :broken)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :plato :broken)))) + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert nil :plato :specific-gravity)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert nil :plato :specific-gravity)))))) (deftest display-test - (testing "Ensure various color unit conversions behave as expected" + (testing "Ensure various specific gravity unit conversions behave as expected" (is (= "1.5 sg" (sut/display 1.5 :specific-gravity) - (sut/display 1.5 options/specific-gravity)))) + (sut/display 1.5 options/specific-gravity))) + (is (= "1.5 °P" + (sut/display 1.5 :plato) + (sut/display 1.5 options/plato)))) (testing "Invalid options throw an exception" #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display 10.0 :invalid)))) - #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display 10.0 :invalid)))))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display 10.0 :invalid)))) + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display nil :plato)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display nil :plato)))))) (deftest code-type-tests From 7aa178d7a40702df66e07450789b0fc46a116afc Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 11 Mar 2024 13:05:50 +0000 Subject: [PATCH 42/44] WIP --- .sealog/changes/2-1-0.edn | 1 + 1 file changed, 1 insertion(+) diff --git a/.sealog/changes/2-1-0.edn b/.sealog/changes/2-1-0.edn index c47bac5..ee20ec1 100644 --- a/.sealog/changes/2-1-0.edn +++ b/.sealog/changes/2-1-0.edn @@ -9,6 +9,7 @@ :changed ["Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." "Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so." "`brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value." + "`brewtility.units.color` now supports a reverse-lookup for known RGBa values." "All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent."] :removed ["`^:const` metadata has been removed from conversion maps"]} :timestamp "2024-03-11T18:47:13.522931300Z"} From 29b750b99ded090bf1aa761d013b8f0aab8a88b2 Mon Sep 17 00:00:00 2001 From: nnichols Date: Mon, 11 Mar 2024 13:16:28 +0000 Subject: [PATCH 43/44] [Format] Auto-formatting --- CHANGELOG.md | 6 ++++-- src/brewtility/units/specific_gravity.cljc | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71460f5..640c1eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,13 +19,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## 2.1.0 - 2024-03-11 * Added - * `brewtility.units.bitterness` for rendering displayable IBU values - * `brewtility.units.carbonation` for rendering displayable carbonation values + * `brewtility.units.bitterness` for rendering displayable IBU values. + * `brewtility.units.carbonation` for rendering displayable carbonation values. + * `brewtility.units.specific-gravity` now supports measurements in degrees plato. * `brewtility.predicates.options` for option map keys shared across predicate namespaces. * Changed * Functions in `brewtility.calculations` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so. * Functions in `brewtility.precision` will throw targeted exceptions for invalid values instead of relying on the underlying Math implementation to do so. * `brewtility.units` now supports a `:precision` option map key for all conversion functions. This key will round the converted value to the specified number of decimal places. Defaults to the precision of the converted value. + * `brewtility.units.color` now supports a reverse-lookup for known RGBa values. * All functions in `brewtility.predicates` now support an option map as a second argument to make their arities consistent. * Removed * `^:const` metadata has been removed from conversion maps diff --git a/src/brewtility/units/specific_gravity.cljc b/src/brewtility/units/specific_gravity.cljc index a499d1f..45dae6a 100644 --- a/src/brewtility/units/specific_gravity.cljc +++ b/src/brewtility/units/specific_gravity.cljc @@ -23,12 +23,14 @@ options/plato {options/full "degrees plato" options/short "°P"}}) + (defn- plato->specific-gravity "Converts a `plato` value to a `specific-gravity` value." [plato] (let [denom (- 258.6 (* (/ plato 258.2) 227.1))] (+ 1 (/ plato denom)))) + (defn- specific-gravity->plato "Converts a `specific-gravity` value to a `plato` value." [gravity] From 6f05b566d0ebc0c73c3db07aedbe39d2ff9402df Mon Sep 17 00:00:00 2001 From: Nick Nichols Date: Mon, 11 Mar 2024 13:46:24 +0000 Subject: [PATCH 44/44] Add alcohol content measurements --- .sealog/changes/2-1-0.edn | 3 +- CHANGELOG.md | 1 + src/brewtility/enrich/impl.cljc | 16 +++- src/brewtility/units.cljc | 9 +- src/brewtility/units/alcohol_content.cljc | 85 +++++++++++++++++++ src/brewtility/units/bitterness.cljc | 4 +- src/brewtility/units/options.cljc | 43 +++++++--- src/brewtility/units/specific_gravity.cljc | 4 + .../units/alcohol_content_test.cljc | 57 +++++++++++++ 9 files changed, 204 insertions(+), 18 deletions(-) create mode 100644 src/brewtility/units/alcohol_content.cljc create mode 100644 test/brewtility/units/alcohol_content_test.cljc diff --git a/.sealog/changes/2-1-0.edn b/.sealog/changes/2-1-0.edn index ee20ec1..4fd519c 100644 --- a/.sealog/changes/2-1-0.edn +++ b/.sealog/changes/2-1-0.edn @@ -2,7 +2,8 @@ :minor 1 :patch 0} :version-type :semver3 - :changes {:added ["`brewtility.units.bitterness` for rendering displayable IBU values." + :changes {:added ["`brewtility.units.alcohol-content` for converting and displaying alcohol content." + "`brewtility.units.bitterness` for rendering displayable IBU values." "`brewtility.units.carbonation` for rendering displayable carbonation values." "`brewtility.units.specific-gravity` now supports measurements in degrees plato." "`brewtility.predicates.options` for option map keys shared across predicate namespaces."] diff --git a/CHANGELOG.md b/CHANGELOG.md index 640c1eb..f33d632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## 2.1.0 - 2024-03-11 * Added + * `brewtility.units.alcohol-content` for converting and displaying alcohol content. * `brewtility.units.bitterness` for rendering displayable IBU values. * `brewtility.units.carbonation` for rendering displayable carbonation values. * `brewtility.units.specific-gravity` now supports measurements in degrees plato. diff --git a/src/brewtility/enrich/impl.cljc b/src/brewtility/enrich/impl.cljc index 7ebe64b..4e1af5a 100644 --- a/src/brewtility/enrich/impl.cljc +++ b/src/brewtility/enrich/impl.cljc @@ -6,6 +6,7 @@ :added "2.1" :implementation-only true} (:require [brewtility.units :as units] + [brewtility.units.alcohol-content :as alcohol-content] [brewtility.units.bitterness :as bitterness] [brewtility.units.carbonation :as carbonation] [brewtility.units.color :as color] @@ -59,6 +60,14 @@ :fine-grain-suffix) +(def default-alcohol-content-by-system + "The default alcohol content system to use for each system in `enrich-displayable-*` functions." + {options/imperial options/abv + options/metric options/abv + options/us-customary options/abv + options/international-system options/abv}) + + (def default-bitterness-by-system "The default bitterness to use for each system in `enrich-displayable-*` functions." {options/imperial options/ibu @@ -133,7 +142,8 @@ (def beer-xml-standard-units "The standard units for each measurement type in BeerXML." - {options/bitterness options/ibu + {options/alcohol-content options/abv + options/bitterness options/ibu options/carbonation options/volumes-of-co2 options/color options/srm options/pressure options/kilopascal @@ -165,6 +175,7 @@ "suffix-error"]} [error-map conversion-type target-units] (let [allowed-values (case conversion-type + :alcohol-content alcohol-content/measurements :bitterness bitterness/measurements :carbonation carbonation/measurements :color color/measurements @@ -196,6 +207,7 @@ "target-unit-error"]} [error-map conversion-type source-units] (let [allowed-values (case conversion-type + :alcohol-content alcohol-content/measurements :bitterness bitterness/measurements :carbonation carbonation/measurements :color color/measurements @@ -273,6 +285,7 @@ :no-doc false} [measurement-type unit] (case measurement-type + :alcohol-content (contains? alcohol-content/measurements unit) :bitterness (contains? bitterness/measurements unit) :carbonation (contains? carbonation/measurements unit) :color (contains? color/measurements unit) @@ -322,6 +335,7 @@ "enrich-displayable-range"]} [measurement-type system-of-measure] (case measurement-type + :alcohol-content (get default-alcohol-content-by-system system-of-measure) :bitterness (get default-bitterness-by-system system-of-measure) :carbonation (get default-carbonation-by-system system-of-measure) :color (get default-color-by-system system-of-measure) diff --git a/src/brewtility/units.cljc b/src/brewtility/units.cljc index 17b18d1..c877693 100644 --- a/src/brewtility/units.cljc +++ b/src/brewtility/units.cljc @@ -22,6 +22,7 @@ {:added "1.0" :changed "2.0"} (:require [brewtility.precision :as precision] + [brewtility.units.alcohol-content :as alcohol-content] [brewtility.units.bitterness :as bitterness] [brewtility.units.carbonation :as carbonation] [brewtility.units.color :as color] @@ -49,7 +50,8 @@ This function accepts an option map as an optional fourth argument. The following options are available: - `precision`: The number of decimal places to round to. Defaults to the precision of the converted value." {:added "2.0" - :see-also ["brewtility.units.bitterness/convert" + :see-also ["brewtility.units.alcohol-content/convert" + "brewtility.units.bitterness/convert" "brewtility.units.carbonation/convert" "brewtility.units.color/convert" "brewtility.units.pressure/convert" @@ -62,6 +64,7 @@ (convert measurement-type measurement source-units target-units {})) ([measurement-type measurement source-units target-units {:keys [precision]}] (let [converted-value (case measurement-type + :alcohol-content (alcohol-content/convert measurement source-units target-units) :bitterness (bitterness/convert measurement source-units target-units) :carbonation (carbonation/convert measurement source-units target-units) :color (color/convert measurement source-units target-units) @@ -93,7 +96,8 @@ - `:short`: A customary abbreviation for the selected unit. For example, `\"gal\"` for `\" US gallons\"`. - `:full`: The full name of the selected unit. For example, `\"teaspoon\"` for `\"teaspoon\"`." {:added "2.0" - :see-also ["brewtility.units.bitterness/display" + :see-also ["brewtility.units.alcohol-content/display" + "brewtility.units.bitterness/display" "brewtility.units.carbonation/display" "brewtility.units.color/display" "brewtility.units.pressure/display" @@ -109,6 +113,7 @@ (let [options (merge {options/precision options/default-precision options/suffix options/short} opts)] (case measurement-type + :alcohol-content (alcohol-content/display measurement source-units options) :bitterness (bitterness/display measurement source-units options) :carbonation (carbonation/display measurement source-units options) :color (color/display measurement source-units options) diff --git a/src/brewtility/units/alcohol_content.cljc b/src/brewtility/units/alcohol_content.cljc new file mode 100644 index 0000000..b4c73cf --- /dev/null +++ b/src/brewtility/units/alcohol_content.cljc @@ -0,0 +1,85 @@ +(ns brewtility.units.alcohol-content + "A namespace for converting between different units for measuring alcohol content. + + In the BeerXML spec, the default unit to measure the alcohol content is ABV (Alcohol by Volume). + This namespace converts between that measure and other units. + + Currently, brewtility supports the following types of IBU: + - [abv](https://en.wikipedia.org/wiki/Alcohol_by_volume)" + {:added "2.1"} + (:require [brewtility.precision :as precision] + [brewtility.units.options :as options])) + + +(def measurements + "The alcohol content measurement systems available across brewtility." + #{options/abv}) + + +(def measurements->display-name + "A map from alcohol content system names to their full and short unit names." + {options/abv {options/full "% alcohol by volume" + options/short "% abv"}}) + + +(def measurement->abv + "A map from alcohol content system names to the conversion function to ABV" + {options/abv identity}) + + +(def abv->measurement + "A map from alcohol content system names to the conversion function from ABV." + {options/abv identity}) + + +(defn convert + "Given an `alcohol-content` in `source-measurement`, convert it to the `target-measurement`. + Supported values for `source-measurement` and `target-measurement` are enumerated in [[alcohol-content-measurements]]. + This function will throw an exception if unsupported measurement values are passed." + {:added "2.1"} + [alcohol-content source-measurement target-measurement] + (if (and (contains? measurements source-measurement) + (contains? measurements target-measurement) + (number? alcohol-content)) + (if (= source-measurement target-measurement) + alcohol-content + (let [source->ibu-fn (measurement->abv source-measurement) + ibu->target-fn (abv->measurement target-measurement)] + (-> alcohol-content source->ibu-fn ibu->target-fn))) + (throw (ex-info "Unsupported alcohol content conversion units" + {:source-measurement source-measurement + :target-measurement target-measurement + :allowed-values measurements + :alcohol-content alcohol-content})))) + + +(defn display + "A function to render a human-readable `alcohol-content` in `source-units`. + + For example, + ```clj + (display .1 options/abv) + ;; => \"10% abv\" + ```" + {:added "2.1"} + ([alcohol-content source-units] + (display alcohol-content source-units {})) + ([alcohol-content source-units {:keys [precision suffix] + :or {precision options/default-precision + suffix options/short}}] + (if (and (contains? measurements source-units) + (number? alcohol-content) + (integer? precision) + (contains? options/supported-suffixes suffix)) + (let [display-name (get-in measurements->display-name [source-units suffix])] + (-> alcohol-content + (* 100.0) ; ABV is a percentage, so multiply by 100 + (precision/->precision precision) + (str display-name))) + (throw (ex-info "Unsupported alcohol content display units" + {:source-units source-units + :allowed-values measurements + :alcohol-content alcohol-content + :precision precision + :suffix suffix + :supported-suffixes options/supported-suffixes}))))) diff --git a/src/brewtility/units/bitterness.cljc b/src/brewtility/units/bitterness.cljc index ed5de77..beb859d 100644 --- a/src/brewtility/units/bitterness.cljc +++ b/src/brewtility/units/bitterness.cljc @@ -1,5 +1,5 @@ (ns brewtility.units.bitterness - "A namespace for converting between different units of international bitterness units (IBU). + "A namespace for converting between different units of bitterness. In the BeerXML spec, IBU is a measure of the bitterness of beer, which is determined by the quantity, type, and timing of hops used in brewing. This namespace converts between that measure and other units. @@ -12,7 +12,7 @@ (def measurements - "The IBU systems available across brewtility." + "The bitterness measurement systems available across brewtility." #{options/ibu}) diff --git a/src/brewtility/units/options.cljc b/src/brewtility/units/options.cljc index 886846c..41d480d 100644 --- a/src/brewtility/units/options.cljc +++ b/src/brewtility/units/options.cljc @@ -116,27 +116,36 @@ #{short full}) +(def alcohol-content + "The alcohol content systems used in the recipe. + + Commonly used with `brewtility.units.alcohol-content` and in argument/option maps. + Currently, brewtility supports the following types of alcohol content measurements: + - [abv](https://en.wikipedia.org/wiki/Alcohol_by_volume)" + :alcohol-content) + + (def bitterness - "The bitterness systems used in the recipe or for a given unit. + "The bitterness systems used in the recipe. Commonly used with `brewtility.units.bitterness` and in argument/option maps. - Currently, brewtility supports the following types of bitterness: + Currently, brewtility supports the following types of bitterness measurements: - [international-bitterness-units](https://en.wikipedia.org/wiki/International_bitterness_units)" :bitterness) (def carbonation - "The carbonation systems used in the recipe or for a given unit. + "The carbonation systems used in the recipe. Commonly used with `brewtility.units.carbonation` and in argument/option maps. - Currently, brewtility supports the following types of carbonation: + Currently, brewtility supports the following types of carbonation measurements: - [volumes-of-co2](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages) - [grams-per-liter](https://en.wikipedia.org/wiki/Carbon_dioxide#Beverages)" :carbonation) (def color - "The color systems used in the recipe or for a given unit. + "The color systems used in the recipe. Commonly used with `brewtility.units.color` and in argument/option maps. Brewility supports the following color systems: @@ -148,7 +157,7 @@ (def pressure - "The pressure systems used in the recipe or for a given unit. + "The pressure systems used in the recipe. Commonly used with `brewtility.units.pressure` and in argument/option maps. Currently, brewtility supports the following types of pressure: @@ -162,7 +171,7 @@ (def specific-gravity - "The specific gravity systems used in the recipe or for a given unit. + "The specific gravity systems used in the recipe. Commonly used with `brewtility.units.specific-gravity` and in argument/option maps. Currently, brewtility supports the following types of specific gravity: @@ -172,7 +181,7 @@ (def temperature - "The temperature systems used in the recipe or for a given unit. + "The temperature systems used in the recipe. Commonly used with `brewtility.units.temperature` and in argument/option maps. Currently, brewtility supports the following types of temperature: @@ -183,7 +192,7 @@ (def time - "The time systems used in the recipe or for a given unit. + "The time systems used in the recipe. Commonly used with `brewtility.units.time` and in argument/option maps. Currently, brewtility supports the following types of time measurements: @@ -199,7 +208,7 @@ (def volume - "The volume systems used in the recipe or for a given unit. + "The volume systems used in the recipe. Commonly used with `brewtility.units.volume` and in argument/option maps. Currently, brewtility supports the following types of volume: @@ -222,7 +231,7 @@ (def weight - "The weight systems used in the recipe or for a given unit. + "The weight systems used in the recipe. Commonly used with `brewtility.units.weight` and in argument/option maps. Currently, brewtility supports the following types of weight: @@ -236,7 +245,8 @@ (def measurement-types "The measurement types available across brewtility." - #{bitterness + #{alcohol-content + bitterness carbonation color pressure @@ -247,6 +257,14 @@ weight}) +;; Alcohol Content Systems +(def abv + "The [Alcohol by Volume](https://en.wikipedia.org/wiki/Alcohol_by_volume) system of measure. + + Commonly used with `brewtility.units.alcohol-content` and in argument/option maps." + :abv) + + ;; Bitterness Systems (def ibu "The [International Bitterness Units](https://en.wikipedia.org/wiki/International_bitterness_units) system of measure. @@ -299,6 +317,7 @@ Commonly used with `brewtility.units.color` and in argument/option maps." :rgba) + ;; Specific Gravity Units (def plato diff --git a/src/brewtility/units/specific_gravity.cljc b/src/brewtility/units/specific_gravity.cljc index 45dae6a..06a9c7d 100644 --- a/src/brewtility/units/specific_gravity.cljc +++ b/src/brewtility/units/specific_gravity.cljc @@ -26,6 +26,8 @@ (defn- plato->specific-gravity "Converts a `plato` value to a `specific-gravity` value." + {:added "2.1" + :no-doc true} [plato] (let [denom (- 258.6 (* (/ plato 258.2) 227.1))] (+ 1 (/ plato denom)))) @@ -33,6 +35,8 @@ (defn- specific-gravity->plato "Converts a `specific-gravity` value to a `plato` value." + {:added "2.1" + :no-doc true} [gravity] (let [g1 (* 1111.14 gravity) g2 (* 630.272 (Math/pow gravity 2)) diff --git a/test/brewtility/units/alcohol_content_test.cljc b/test/brewtility/units/alcohol_content_test.cljc new file mode 100644 index 0000000..b2ce7ff --- /dev/null +++ b/test/brewtility/units/alcohol_content_test.cljc @@ -0,0 +1,57 @@ +(ns brewtility.units.alcohol-content-test + (:require #? (:clj [clojure.test :refer [deftest is testing]]) + #? (:cljs [cljs.test :refer-macros [deftest is testing]]) + [brewtility.precision :as precision] + [brewtility.units.alcohol-content :as sut] + [brewtility.units.options :as options])) + + +(deftest conversion-test + (testing "Ensure various color unit conversions behave as expected" + (is (= 100.0 + (precision/->2dp (sut/convert 100.0 options/abv options/abv)) + (precision/->2dp (sut/convert 100.0 :abv :abv))))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/convert 10.0 :invalid :broken)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/convert 10.0 :invalid :broken)))))) + + +(deftest display-test + (testing "Ensure various color unit conversions behave as expected" + (is (= "15.3% abv" + (sut/display 0.153 :abv) + (sut/display 0.153 options/abv)))) + (testing "Invalid options throw an exception" + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display 10.0 :invalid)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display 10.0 :invalid)))) + #?(:clj (is (thrown-with-msg? Exception #"Unsupported" (sut/display nil :abv)))) + #?(:cljs (is (thrown-with-msg? js/Error #"Unsupported" (sut/display nil :abv)))))) + + +(deftest code-type-tests + (testing "Ensure maps used for options are structurally correct" + (testing "Measurement types" + (is (set? sut/measurements)) + (is (every? keyword? sut/measurements)) + (is (not-empty sut/measurements))) + (testing "Measurement display names" + (is (map? sut/measurements->display-name)) + (is (not-empty sut/measurements->display-name)) + (is (every? keyword? (keys sut/measurements->display-name))) + (is (every? map? (vals sut/measurements->display-name))) + (is (every? #(contains? % options/full) (vals sut/measurements->display-name))) + (is (every? #(contains? % options/short) (vals sut/measurements->display-name)))) + (testing "measurement->abv" + (is (map? sut/measurement->abv)) + (is (not-empty sut/measurement->abv)) + (is (every? keyword? (keys sut/measurement->abv))) + (is (every? ifn? (vals sut/measurement->abv)))) + (testing "abv->measurement" + (is (map? sut/abv->measurement)) + (is (not-empty sut/abv->measurement)) + (is (every? keyword? (keys sut/abv->measurement))) + (is (= (set (keys sut/measurement->abv)) + (set (keys sut/abv->measurement)) + (set (keys sut/measurements->display-name)) + sut/measurements)) + (is (every? ifn? (vals sut/abv->measurement))))))