Repository: go-sprout/sprout
Pull request #59 (2024-08-19 03:22:35)

feat: add sha512sum to checksum registry and add notices
## Description
Introduce the `sha512Sum` function as requested by sprig community and update old functions to new standards (naming convention and notice for deprecation) to `checksum` registry

## Changes
- Add `sha512Sum` function to `checksum` registry
- Add error return to each method of the registry
- Add notice to deprecate old naming `sha1sum` -> `sha1Sum`

## Duplicate of https://github.com/Masterminds/sprig/pull/400, https://github.com/Masterminds/sprig/pull/326

## Checklist
- [x] I have read the **CONTRIBUTING.md** document.
- [x] My code follows the code style of this project.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] I have updated the documentation accordingly.
- [ ] This change requires a change to the documentation on the website.

## Additional Information
Documentation update are embed


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/go-sprout/sprout/pull/59?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout) Report
All modified and coverable lines are covered by tests :white_check_mark:

| [Files](https://app.codecov.io/gh/go-sprout/sprout/pull/59?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout) | Coverage Δ | |
|---|---|---|
| [registry/checksum/checksum.go](https://app.codecov.io/gh/go-sprout/sprout/pull/59?src=pr&el=tree&filepath=registry%2Fchecksum%2Fchecksum.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout#diff-cmVnaXN0cnkvY2hlY2tzdW0vY2hlY2tzdW0uZ28=) | `92.3% <100.0%> (+7.6%)` | :arrow_up: |
| [registry/checksum/functions.go](https://app.codecov.io/gh/go-sprout/sprout/pull/59?src=pr&el=tree&filepath=registry%2Fchecksum%2Ffunctions.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout#diff-cmVnaXN0cnkvY2hlY2tzdW0vZnVuY3Rpb25zLmdv) | `100.0% <100.0%> (ø)` | |

... and [23 files with indirect coverage changes](https://app.codecov.io/gh/go-sprout/sprout/pull/59/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout)

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/go-sprout/sprout/pull/59?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout) Report
All modified and coverable lines are covered by tests :white_check_mark:

| [Files](https://app.codecov.io/gh/go-sprout/sprout/pull/59?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout) | Coverage Δ | |
|---|---|---|
| [registry/checksum/checksum.go](https://app.codecov.io/gh/go-sprout/sprout/pull/59?src=pr&el=tree&filepath=registry%2Fchecksum%2Fchecksum.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout#diff-cmVnaXN0cnkvY2hlY2tzdW0vY2hlY2tzdW0uZ28=) | `92.3% <100.0%> (+7.6%)` | :arrow_up: |
| [registry/checksum/functions.go](https://app.codecov.io/gh/go-sprout/sprout/pull/59?src=pr&el=tree&filepath=registry%2Fchecksum%2Ffunctions.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-sprout#diff-cmVnaXN0cnkvY2hlY2tzdW0vZnVuY3Rpb25zLmdv) | `100.0% <100.0%> (ø)` | |


Patch:
diff --git a/docs/registries/checksum.md b/docs/registries/checksum.md
index 79f8506..9f4176d 100644
--- a/docs/registries/checksum.md
+++ b/docs/registries/checksum.md
@@ -15,24 +15,24 @@ import "github.com/go-sprout/sprout/registry/checksum"
 ```
 {% endhint %}
 
-### <mark style="color:purple;">sha1sum</mark>
+### <mark style="color:purple;">sha1Sum</mark>
 
-Sha1sum calculates the SHA-1 hash of the input string and returns it as a hexadecimal encoded string.
+SHA1sum calculates the SHA-1 hash of the input string and returns it as a hexadecimal encoded string.
 
 <table data-header-hidden><thead><tr><th width="174">Name</th><th>Value</th></tr></thead><tbody><tr><td>Signature</td><td><pre class="language-go"><code class="lang-go">SHA1Sum(input string) string
 </code></pre></td></tr><tr><td>Must version</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>
 
 {% tabs %}
 {% tab title="Template Example" %}
-<pre class="language-go"><code class="lang-go"><strong>{{ sha1sum "" }} // Output: da39a3ee5e6b4b0d3255bfef95601890afd80709
-</strong>{{ sha1sum "Hello, World!" }} // Output: 0a0a9f2a6772942557ab5355d76af442f8f65e01
+<pre class="language-go"><code class="lang-go"><strong>{{ sha1Sum "" }} // Output: da39a3ee5e6b4b0d3255bfef95601890afd80709
+</strong>{{ sha1Sum "Hello, World!" }} // Output: 0a0a9f2a6772942557ab5355d76af442f8f65e01
 </code></pre>
 {% endtab %}
 {% endtabs %}
 
-### <mark style="color:purple;">sha256sum</mark>
+### <mark style="color:purple;">sha256Sum</mark>
 
-Sha256sum calculates the SHA-256 hash of the input string and returns it as a hexadecimal encoded string.
+SHA256sum calculates the SHA-256 hash of the input string and returns it as a hexadecimal encoded string.
 
 <table data-header-hidden><thead><tr><th width="174">Name</th><th>Value</th></tr></thead><tbody><tr><td>Signature</td><td><pre class="language-go"><code class="lang-go">SHA256Sum(input string) string
 </code></pre></td></tr><tr><td>Must version</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>
@@ -40,15 +40,31 @@ Sha256sum calculates the SHA-256 hash of the input string and returns it as a he
 {% tabs %}
 {% tab title="Template Example" %}
 ```go
-{{ sha256sum "" }} // Output: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
-{{ sha256sum "Hello, World!" }} // Output: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f
+{{ sha256Sum "" }} // Output: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+{{ sha256Sum "Hello, World!" }} // Output: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f
 ```
 {% endtab %}
 {% endtabs %}
 
-### <mark style="color:purple;">adler32sum</mark>
+### <mark style="color:purple;">sha512Sum</mark>
 
-Adler32sum calculates the Adler-32 checksum of the input string and returns it as a hexadecimal encoded string.
+SHA512sum calculates the SHA-512 hash of the input string and returns it as a hexadecimal encoded string.
+
+<table data-header-hidden><thead><tr><th width="174">Name</th><th>Value</th></tr></thead><tbody><tr><td>Signature</td><td><pre class="language-go"><code class="lang-go">SHA512Sum(input string) string
+</code></pre></td></tr><tr><td>Must version</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>
+
+{% tabs %}
+{% tab title="Template Example" %}
+```go
+{{ sha512Sum "" }} // Output: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+{{ sha512Sum "Hello, World!" }} // Output: 374d794a95cdcfd8b35993185fef9ba368f160d8daf432d08ba9f1ed1e5abe6cc69291e0fa2fe0006a52570ef18c19def4e617c33ce52ef0a6e5fbe318cb0387
+```
+{% endtab %}
+{% endtabs %}
+
+### <mark style="color:purple;">adler32Sum</mark>
+
+Adler32Sum calculates the Adler-32 checksum of the input string and returns it as a hexadecimal encoded string.
 
 <table data-header-hidden><thead><tr><th width="174">Name</th><th>Value</th></tr></thead><tbody><tr><td>Signature</td><td><pre class="language-go"><code class="lang-go">Adler32Sum(input string) string
 </code></pre></td></tr><tr><td>Must version</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>
@@ -56,15 +72,15 @@ Adler32sum calculates the Adler-32 checksum of the input string and returns it a
 {% tabs %}
 {% tab title="Tempalte Example" %}
 ```go
-{{ adler32sum "" }} // Output: 00000001
-{{ adler32sum "Hello, World!" }} // Output: 1f9e046a
+{{ adler32Sum "" }} // Output: 00000001
+{{ adler32Sum "Hello, World!" }} // Output: 1f9e046a
 ```
 {% endtab %}
 {% endtabs %}
 
-### <mark style="color:purple;">md5sum</mark>
+### <mark style="color:purple;">md5Sum</mark>
 
-Md5sum calculates the MD5 hash of the input string and returns it as a hexadecimal encoded string.
+MD5sum calculates the MD5 hash of the input string and returns it as a hexadecimal encoded string.
 
 <table data-header-hidden><thead><tr><th width="174">Name</th><th>Value</th></tr></thead><tbody><tr><td>Signature</td><td><pre class="language-go"><code class="lang-go">MD5Sum(input string) string
 </code></pre></td></tr><tr><td>Must version</td><td><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span></td></tr></tbody></table>
@@ -72,8 +88,8 @@ Md5sum calculates the MD5 hash of the input string and returns it as a hexadecim
 {% tabs %}
 {% tab title="Template Example" %}
 ```go
-{{ md5sum "" }} // Output: d41d8cd98f00b204e9800998ecf8427e
-{{ md5sum "Hello, World!" }} // Output: 65a8e27d8879283831b664bd8b7f0ad4
+{{ md5Sum "" }} // Output: d41d8cd98f00b204e9800998ecf8427e
+{{ md5Sum "Hello, World!" }} // Output: 65a8e27d8879283831b664bd8b7f0ad4
 ```
 {% endtab %}
 {% endtabs %}
diff --git a/registry/checksum/checksum.go b/registry/checksum/checksum.go
index 10592d5..312645b 100644
--- a/registry/checksum/checksum.go
+++ b/registry/checksum/checksum.go
@@ -24,9 +24,26 @@ func (cr *ChecksumRegistry) LinkHandler(fh sprout.Handler) error {
 
 // RegisterFunctions registers all functions of the registry.
 func (cr *ChecksumRegistry) RegisterFunctions(funcsMap sprout.FunctionMap) error {
-	sprout.AddFunction(funcsMap, "sha1sum", cr.SHA1Sum)
-	sprout.AddFunction(funcsMap, "sha256sum", cr.SHA256Sum)
-	sprout.AddFunction(funcsMap, "adler32sum", cr.Adler32Sum)
-	sprout.AddFunction(funcsMap, "md5sum", cr.MD5Sum)
+	sprout.AddFunction(funcsMap, "sha1Sum", cr.SHA1Sum)
+	sprout.AddFunction(funcsMap, "sha256Sum", cr.SHA256Sum)
+	sprout.AddFunction(funcsMap, "sha512Sum", cr.SHA512Sum)
+	sprout.AddFunction(funcsMap, "adler32Sum", cr.Adler32Sum)
+	sprout.AddFunction(funcsMap, "md5Sum", cr.MD5Sum)
+	return nil
+}
+
+func (cr *ChecksumRegistry) RegisterAliases(aliasMap sprout.FunctionAliasMap) error {
+	sprout.AddAlias(aliasMap, "sha1Sum", "sha1sum")
+	sprout.AddAlias(aliasMap, "sha256Sum", "sha256sum")
+	sprout.AddAlias(aliasMap, "adler32Sum", "adler32sum")
+	sprout.AddAlias(aliasMap, "md5Sum", "md5sum")
+	return nil
+}
+
+func (cr *ChecksumRegistry) RegisterNotices(notices *[]sprout.FunctionNotice) error {
+	sprout.AddNotice(notices, sprout.NewDeprecatedNotice("sha1sum", "use `sha1Sum` instead."))
+	sprout.AddNotice(notices, sprout.NewDeprecatedNotice("sha256sum", "use `sha256Sum` instead."))
+	sprout.AddNotice(notices, sprout.NewDeprecatedNotice("adler32sum", "use `adler32Sum` instead."))
+	sprout.AddNotice(notices, sprout.NewDeprecatedNotice("md5sum", "use `md5Sum` instead."))
 	return nil
 }
diff --git a/registry/checksum/functions.go b/registry/checksum/functions.go
index af99a5a..479c0ab 100644
--- a/registry/checksum/functions.go
+++ b/registry/checksum/functions.go
@@ -4,6 +4,7 @@ import (
 	"crypto/md5"
 	"crypto/sha1"
 	"crypto/sha256"
+	"crypto/sha512"
 	"encoding/hex"
 	"fmt"
 	"hash/adler32"
@@ -20,10 +21,10 @@ import (
 //
 // Example:
 //
-// {{ sha1sum "Hello, World!" }} // Output: 0a0a9f2a6772942557ab5355d76af442f8f65e01
-func (cr *ChecksumRegistry) SHA1Sum(input string) string {
+// {{ sha1Sum "Hello, World!" }} // Output: 0a0a9f2a6772942557ab5355d76af442f8f65e01
+func (cr *ChecksumRegistry) SHA1Sum(input string) (string, error) {
 	hash := sha1.Sum([]byte(input))
-	return hex.EncodeToString(hash[:])
+	return hex.EncodeToString(hash[:]), nil
 }
 
 // SHA256Sum calculates the SHA-256 hash of the input string and returns it as a
@@ -37,10 +38,27 @@ func (cr *ChecksumRegistry) SHA1Sum(input string) string {
 //
 // Example:
 //
-// {{ sha256sum "Hello, World!" }} // Output: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f
-func (cr *ChecksumRegistry) SHA256Sum(input string) string {
+// {{ sha256Sum "Hello, World!" }} // Output: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f
+func (cr *ChecksumRegistry) SHA256Sum(input string) (string, error) {
 	hash := sha256.Sum256([]byte(input))
-	return hex.EncodeToString(hash[:])
+	return hex.EncodeToString(hash[:]), nil
+}
+
+// SHA512Sum calculates the SHA-512 hash of the input string and returns it as a
+// hexadecimal encoded string.
+//
+// Parameters:
+// - input: the string to be hashed.
+//
+// Returns:
+// - the SHA-512 hash of the input string as a hexadecimal encoded string.
+//
+// Example:
+//
+// {{ sha512Sum "Hello, World!" }} // Output: 374d794a95cdcfd8b35993185fef9ba368f160d8daf432d08ba9f1ed1e5abe6cc69291e0fa2fe0006a52570ef18c19def4e617c33ce52ef0a6e5fbe318cb0387
+func (cr *ChecksumRegistry) SHA512Sum(input string) (string, error) {
+	hash := sha512.Sum512([]byte(input))
+	return hex.EncodeToString(hash[:]), nil
 }
 
 // Adler32Sum calculates the Adler-32 checksum of the input string and returns
@@ -54,10 +72,10 @@ func (cr *ChecksumRegistry) SHA256Sum(input string) string {
 //
 // Example:
 //
-// {{ adler32sum "Hello, World!" }} // Output: 1f9e046a
-func (cr *ChecksumRegistry) Adler32Sum(input string) string {
+// {{ adler32Sum "Hello, World!" }} // Output: 1f9e046a
+func (cr *ChecksumRegistry) Adler32Sum(input string) (string, error) {
 	hash := adler32.Checksum([]byte(input))
-	return fmt.Sprint(hash)
+	return fmt.Sprint(hash), nil
 }
 
 // MD5Sum calculates the MD5 hash of the input string and returns it as a
@@ -71,8 +89,8 @@ func (cr *ChecksumRegistry) Adler32Sum(input string) string {
 //
 // Example:
 //
-// {{ md5sum "Hello, World!" }} // Output: 65a8e27d8879283831b664bd8b7f0ad4
-func (cr *ChecksumRegistry) MD5Sum(input string) string {
+// {{ md5Sum "Hello, World!" }} // Output: 65a8e27d8879283831b664bd8b7f0ad4
+func (cr *ChecksumRegistry) MD5Sum(input string) (string, error) {
 	hash := md5.Sum([]byte(input))
-	return hex.EncodeToString(hash[:])
+	return hex.EncodeToString(hash[:]), nil
 }


Test patch:
diff --git a/registry/checksum/functions_test.go b/registry/checksum/functions_test.go
index 8ad9066..796ef0f 100644
--- a/registry/checksum/functions_test.go
+++ b/registry/checksum/functions_test.go
@@ -4,6 +4,7 @@ import (
 	"crypto/md5"
 	"crypto/sha1"
 	"crypto/sha256"
+	"crypto/sha512"
 	"encoding/hex"
 	"fmt"
 	"hash/adler32"
@@ -13,54 +14,67 @@ import (
 	"github.com/go-sprout/sprout/registry/checksum"
 )
 
-func TestSha1sum(t *testing.T) {
+func TestSha1Sum(t *testing.T) {
 	noHash := sha1.Sum([]byte(""))
 	soloHash := sha1.Sum([]byte("a"))
 	multiHash := sha1.Sum([]byte("hello world"))
 
 	var tc = []pesticide.TestCase{
-		{Name: "TestEmptyInput", Input: `{{sha1sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
-		{Name: "TestSingleByteInput", Input: `{{sha1sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
-		{Name: "TestMultiByteInput", Input: `{{sha1sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
+		{Name: "TestEmptyInput", Input: `{{sha1Sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
+		{Name: "TestSingleByteInput", Input: `{{sha1Sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
+		{Name: "TestMultiByteInput", Input: `{{sha1Sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
 	}
 	pesticide.RunTestCases(t, checksum.NewRegistry(), tc)
 }
 
-func TestSha256sum(t *testing.T) {
+func TestSha256Sum(t *testing.T) {
 	noHash := sha256.Sum256([]byte(""))
 	soloHash := sha256.Sum256([]byte("a"))
 	multiHash := sha256.Sum256([]byte("hello world"))
 
 	var tc = []pesticide.TestCase{
-		{Name: "TestEmptyInput", Input: `{{sha256sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
-		{Name: "TestSingleByteInput", Input: `{{sha256sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
-		{Name: "TestMultiByteInput", Input: `{{sha256sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
+		{Name: "TestEmptyInput", Input: `{{sha256Sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
+		{Name: "TestSingleByteInput", Input: `{{sha256Sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
+		{Name: "TestMultiByteInput", Input: `{{sha256Sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
 	}
 	pesticide.RunTestCases(t, checksum.NewRegistry(), tc)
 }
 
-func TestAdler32sum(t *testing.T) {
+func TestSha512sum(t *testing.T) {
+	noHash := sha512.Sum512([]byte(""))
+	soloHash := sha512.Sum512([]byte("a"))
+	multiHash := sha512.Sum512([]byte("hello world"))
+
+	var tc = []pesticide.TestCase{
+		{Name: "TestEmptyInput", Input: `{{sha512Sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
+		{Name: "TestSingleByteInput", Input: `{{sha512Sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
+		{Name: "TestMultiByteInput", Input: `{{sha512Sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
+	}
+	pesticide.RunTestCases(t, checksum.NewRegistry(), tc)
+}
+
+func TestAdler32Sum(t *testing.T) {
 	noHash := adler32.Checksum([]byte(""))
 	soloHash := adler32.Checksum([]byte("a"))
 	multiHash := adler32.Checksum([]byte("hello world"))
 
 	var tc = []pesticide.TestCase{
-		{Name: "TestEmptyInput", Input: `{{adler32sum ""}}`, Expected: fmt.Sprint(noHash)},
-		{Name: "TestSingleByteInput", Input: `{{adler32sum "a"}}`, Expected: fmt.Sprint(soloHash)},
-		{Name: "TestMultiByteInput", Input: `{{adler32sum "hello world"}}`, Expected: fmt.Sprint(multiHash)},
+		{Name: "TestEmptyInput", Input: `{{adler32Sum ""}}`, Expected: fmt.Sprint(noHash)},
+		{Name: "TestSingleByteInput", Input: `{{adler32Sum "a"}}`, Expected: fmt.Sprint(soloHash)},
+		{Name: "TestMultiByteInput", Input: `{{adler32Sum "hello world"}}`, Expected: fmt.Sprint(multiHash)},
 	}
 	pesticide.RunTestCases(t, checksum.NewRegistry(), tc)
 }
 
-func TestMD5sum(t *testing.T) {
+func TestMD5Sum(t *testing.T) {
 	noHash := md5.Sum([]byte(""))
 	soloHash := md5.Sum([]byte("a"))
 	multiHash := md5.Sum([]byte("hello world"))
 
 	var tc = []pesticide.TestCase{
-		{Name: "TestEmptyInput", Input: `{{md5sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
-		{Name: "TestSingleByteInput", Input: `{{md5sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
-		{Name: "TestMultiByteInput", Input: `{{md5sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
+		{Name: "TestEmptyInput", Input: `{{md5Sum ""}}`, Expected: hex.EncodeToString(noHash[:])},
+		{Name: "TestSingleByteInput", Input: `{{md5Sum "a"}}`, Expected: hex.EncodeToString(soloHash[:])},
+		{Name: "TestMultiByteInput", Input: `{{md5Sum "hello world"}}`, Expected: hex.EncodeToString(multiHash[:])},
 	}
 	pesticide.RunTestCases(t, checksum.NewRegistry(), tc)
 }
diff --git a/sprigin/sprig_backward_compatibility_test.go b/sprigin/sprig_backward_compatibility_test.go
index 6cbdcad..ba52735 100644
--- a/sprigin/sprig_backward_compatibility_test.go
+++ b/sprigin/sprig_backward_compatibility_test.go
@@ -51,7 +51,7 @@ func TestSprigHandler(t *testing.T) {
 	handler.Build()
 
 	assert.GreaterOrEqual(t, len(handler.Functions()), sprigFunctionCount)
-	assert.Len(t, handler.Aliases(), 3)
+	assert.Len(t, handler.Aliases(), 7)
 
 	assert.Len(t, handler.registries, 18)