Compare commits

...

51 commits

Author SHA1 Message Date
ba0b5b2e9c
1.2.1-SNAPSHOT 2025-02-25 09:39:08 -08:00
013218f399
Bump bld to version 2.2.1 2025-02-25 09:38:36 -08:00
68d88ea7d3
Bump AssertJ to version 3.27.3 2025-02-25 09:37:49 -08:00
10ea21245b
Bump JUnit to version 5.12.0 2025-02-25 09:37:02 -08:00
9c14794ee8
Version 1.2.0 2025-01-14 12:50:49 -08:00
8383f75ad9
Bumped bld to version 2.2.0 2025-01-14 12:50:32 -08:00
b0f9c5a4ed
Bumped RIFE2 to version 1.9.1 2025-01-14 12:49:24 -08:00
b10826481e
Bumped JUnit to version 5.11.4 2025-01-14 12:48:54 -08:00
2c842bdb6a
Bumped AssertJ to version 3.27.2 2025-01-14 12:47:49 -08:00
a1ab01a7fc
Bumped PMD extension to version 1.1.0 2025-01-14 12:46:09 -08:00
4731afb83b
Bumped Jacoco extension to version 0.9.9 2025-01-14 12:45:47 -08:00
6dc23012cc
1.2.0 SNAPSHOT 2024-11-15 11:48:01 -08:00
99f6afe4fb
Added capitalizeWords renderer 2024-11-15 11:47:40 -08:00
daadd0bc4a
Added missing and cleaned up JavaDocs 2024-10-29 22:59:27 -07:00
97edc07160
Updated dependencies
Bumped JDK to version 23 (GitHub CI Workflow)
Bumped PMD extensions to version 1.1.7
Bumped JUnit to version 5.11.3
2024-10-29 22:39:52 -07:00
911d54c10b
Minor cleanups 2024-09-04 23:47:12 -07:00
5090b8224c
Added soft assertions 2024-09-04 23:46:13 -07:00
5cfb6fa5f8
Bumped bld to version 2.1.0 2024-09-04 23:45:51 -07:00
313121cfcc
Version 1.1.6 2024-07-31 17:17:02 -07:00
957bb694c6
Improved normalizing with support for common separators 2024-07-31 17:10:00 -07:00
c04fa16307
Bumped bld to version 2.0.1 2024-07-29 17:37:50 -07:00
429852371f
Bumped bld to version 2.0.1 2024-07-29 17:30:00 -07:00
0b24f08cb1
Added JDK 22 to CI 2024-03-21 14:00:47 -07:00
48eeada6a9 Fixed Maven Central badge 2024-02-29 20:17:20 -08:00
87f9e90d67 Version 1.1.5 2024-02-28 11:26:06 -08:00
0d14c27032 Added JS escaping for newline, linefeed, return, tab and backspace. Closes #1 2024-02-28 03:29:29 -08:00
a0ebfe2566 Bumped to bld 1.9.0 2024-02-26 13:48:58 -08:00
3f4c2abac1 Bumped bld to 1.8.0 2024-01-31 01:07:29 -08:00
cc30348981 Minor cleanup 2024-01-31 01:04:48 -08:00
4cedb3ab62 Updated copyright 2024-01-31 01:04:38 -08:00
dd614a27de Added rife2 repository badge 2023-10-22 15:53:31 -07:00
8b391830b2 Version 1.1.4 2023-10-22 15:36:50 -07:00
7e0d7ff1f6 Updated extensions 2023-10-22 15:36:34 -07:00
77beb954ce Version 1.1.3 2023-10-22 13:33:45 -07:00
eeb2965a5e Updated dependencies 2023-10-20 21:35:56 -07:00
ab59d559e4 Upgraded to bld 1.7.2 2023-08-20 19:56:05 -07:00
7bbacf7a30 Upgrade to bld 1.7.1 2023-08-18 02:15:27 -07:00
9d2a1d4324
Update bld-wrapper.properties 2023-08-17 12:52:27 -07:00
5a0dbdffed Added bld badge 2023-08-16 14:16:40 -07:00
ca65b86e1d Also publish to rife2's repo 2023-08-12 11:40:04 -07:00
079671626a Added more tests 2023-08-12 11:06:23 -07:00
a57c5afd62 Upgraded to RIFE2 1.7.0 2023-05-12 15:03:19 -07:00
1490b29da5 Fixed sonatype repos 2023-04-15 15:18:08 -07:00
85cf1ee47f Updated test-badges extension 2023-04-15 14:43:02 -07:00
623ecfa7af Added pmd extension with RIFE2 1.5.20 2023-04-15 14:16:08 -07:00
60d15e253e Minor cleanup 2023-04-15 13:53:11 -07:00
25b94487ad Updated to RIFE2 1.5.19 2023-04-10 08:20:42 -04:00
9cd94acfe4
Update publish.yml 2023-04-08 19:33:42 -04:00
b472519c23
Update publish.yml 2023-04-08 19:24:06 -04:00
452bcc3ada
Update publish.yml 2023-04-08 19:21:04 -04:00
5d7c90e25d
Update publish.yml 2023-04-08 19:18:50 -04:00
57 changed files with 817 additions and 211 deletions

View file

@ -1,6 +1,6 @@
name: bld-ci name: bld-ci
on: [ push, pull_request, workflow_dispatch ] on: [push, pull_request, workflow_dispatch]
jobs: jobs:
build-bld-project: build-bld-project:
@ -8,28 +8,25 @@ jobs:
strategy: strategy:
matrix: matrix:
java-version: [ 17, 19, 20 ] java-version: [17, 21, 23]
steps: steps:
- name: Checkout source repository - name: Checkout source repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK ${{ matrix.java-version }} - name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: "zulu"
java-version: ${{ matrix.java-version }} java-version: ${{ matrix.java-version }}
- name: Grant execute permission for bld - name: Download dependencies
run: chmod +x bld
- name: Download the dependencies
run: ./bld download run: ./bld download
- name: Run tests with bld - name: Run tests
run: >- run: >-
./bld compile test ./bld compile test
-DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/rife2-renderers -DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/rife2-renderers
-DtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }} -DtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}

View file

@ -3,7 +3,7 @@ name: javadocs-pages
on: on:
# Runs on pushes targeting the default branch # Runs on pushes targeting the default branch
push: push:
branches: [ "master" ] branches: ["master"]
# Allows you to run this workflow manually from the Actions tab # Allows you to run this workflow manually from the Actions tab
workflow_dispatch: workflow_dispatch:
@ -30,14 +30,14 @@ jobs:
steps: steps:
- name: Checkout source repository - name: Checkout source repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: "zulu"
java-version: 17 java-version: 17
- name: Build Javadocs - name: Build Javadocs
@ -47,11 +47,11 @@ jobs:
uses: actions/configure-pages@v3 uses: actions/configure-pages@v3
- name: Upload artifact - name: Upload artifact
uses: actions/upload-pages-artifact@v1 uses: actions/upload-pages-artifact@v3
with: with:
# Upload generated Javadocs repository # Upload generated Javadocs repository
path: 'build/javadoc/' path: "build/javadoc/"
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@v1 uses: actions/deploy-pages@v4

View file

@ -1,9 +1,9 @@
name: Publish to the Maven Central name: Publish to the Maven Central/Rife2
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
types: [ released ] types: [released]
jobs: jobs:
build-bld-project: build-bld-project:
@ -11,23 +11,23 @@ jobs:
steps: steps:
- name: Checkout source repository - name: Checkout source repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: "temurin"
java-version: 17 java-version: 17
- name: Grant execute permission for bld - name: Download dependencies
run: chmod +x bld
- name: Download the dependencies
run: ./bld download run: ./bld download
- name: Publish with bld - name: Import key
run: echo "${{ secrets.SIGN_SECRET_KEY }}" | gpg --batch --import
- name: Publish
run: >- run: >-
./bld compile test publish ./bld compile test publish
-DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/rife2-renderers -DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/rife2-renderers
@ -38,3 +38,6 @@ jobs:
-DsonatypePassword=${{ secrets.SONATYPE_PASSWORD }} -DsonatypePassword=${{ secrets.SONATYPE_PASSWORD }}
-DsignKey=${{ secrets.SIGN_KEY }} -DsignKey=${{ secrets.SIGN_KEY }}
-DsignPassphrase=${{ secrets.SIGN_PASSPHRASE }} -DsignPassphrase=${{ secrets.SIGN_PASSPHRASE }}
- name: Delete GnuPG data
run: rm -rfv $HOME/.gnupg

6
.idea/bld.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
</state>
</component>

View file

@ -1,6 +1,6 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<copyright> <copyright>
<option name="notice" value=" Copyright &amp;#36;today.year the original author or authors.&#10; &#10; Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10; you may not use this file except in compliance with the License.&#10; You may obtain a copy of the License at&#10; &#10; https://www.apache.org/licenses/LICENSE-2.0&#10; &#10; Unless required by applicable law or agreed to in writing, software&#10; distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10; See the License for the specific language governing permissions and&#10; limitations under the License.&#10; " /> <option name="notice" value=" Copyright 2023-&amp;#36;today.year the original author or authors.&#10; &#10; Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10; you may not use this file except in compliance with the License.&#10; You may obtain a copy of the License at&#10; &#10; https://www.apache.org/licenses/LICENSE-2.0&#10; &#10; Unless required by applicable law or agreed to in writing, software&#10; distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10; See the License for the specific language governing permissions and&#10; limitations under the License.&#10; " />
<option name="myName" value="Apache License" /> <option name="myName" value="Apache License" />
</copyright> </copyright>
</component> </component>

12
.idea/icon.svg generated Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with Vectornator (http://vectornator.io/) -->
<svg height="100%" stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;" version="1.1" viewBox="0 0 50 50" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs/>
<g id="Untitled">
<g opacity="1">
<path d="M31.9421 4.99551C26.8094 7.90585 24.7641 12.0654 24.2025 17.855C23.7876 22.1321 27.3936 27.0983 27.5933 29.9084C27.8096 32.9493 26.063 35.2557 22.623 35.8686C20.4949 36.2477 17.8742 36.0139 14.6092 33.2624C14.6678 38.0258 16.7542 42.433 21.5076 44.1302C26.4211 45.8835 31.2671 44.9143 34.6016 41.9865C39.1593 38.2111 40.2692 32.4953 36.786 26.6511C33.0398 20.3619 29.6701 15.5562 31.9421 4.99551" fill="#fa9052" fill-rule="nonzero" opacity="1" stroke="none"/>
<path d="M17.349 14.5478C17.3497 14.5395 17.349 14.5478 17.349 14.5478C17.1626 14.8365 16.9754 15.1245 16.7869 15.4119C15.8906 16.7783 14.949 18.1004 13.9706 19.4087C12.6688 21.1498 10.9828 23.3556 11.1816 25.6096C11.3531 26.7195 12.0143 27.6556 12.9129 28.3061C13.6009 28.7369 14.38 28.9871 15.1883 29.0868C16.1147 29.2013 17.0209 29.1429 17.9083 28.834C19.257 28.1671 19.8037 27.4604 20.0005 26.4317C20.0649 26.1834 20.0437 25.8312 20.0437 25.8312C20.0343 25.73 20.0272 25.6537 20.0152 25.5528C19.9908 25.3475 19.9566 25.1434 19.9147 24.9411C19.8678 24.7142 19.8113 24.4896 19.7476 24.2671C19.7361 24.2271 19.6483 23.9399 19.6927 24.0786C19.6573 23.9677 19.6198 23.8574 19.5812 23.7477C19.4341 23.3294 19.2669 22.9183 19.0904 22.5114C19.0904 22.5114 18.2023 20.4746 17.8867 19.4599C17.3927 17.8737 17.1809 16.2048 17.349 14.5478Z" fill="#2392ff" fill-rule="nonzero" opacity="1" stroke="none"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

204
.idea/intellij-javadocs-4.0.1.xml generated Normal file
View file

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaDocConfiguration">
<GENERAL>
<MODE>UPDATE</MODE>
<OVERRIDDEN_METHODS>false</OVERRIDDEN_METHODS>
<SPLITTED_CLASS_NAME>true</SPLITTED_CLASS_NAME>
<LEVELS>
<LEVEL>TYPE</LEVEL>
<LEVEL>FIELD</LEVEL>
<LEVEL>METHOD</LEVEL>
</LEVELS>
<VISIBILITIES>
<VISIBILITY>DEFAULT</VISIBILITY>
<VISIBILITY>PROTECTED</VISIBILITY>
<VISIBILITY>PUBLIC</VISIBILITY>
</VISIBILITIES>
</GENERAL>
<TEMPLATES>
<CLASSES>
<CLASS>
<KEY>^.*(public|protected|private)*.+interface\s+\w+.*</KEY>
<VALUE>/**\n
* The interface ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+enum\s+\w+.*</KEY>
<VALUE>/**\n
* The enum ${name}.\n
*/</VALUE>
</CLASS>
<CLASS>
<KEY>^.*(public|protected|private)*.+class\s+\w+.*</KEY>
<VALUE>/**\n
* The type ${name}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
*/</VALUE>
</CLASS>
<CLASS>
<KEY>.+</KEY>
<VALUE>/**\n
* The type ${name}.\n
*/</VALUE>
</CLASS>
</CLASSES>
<CONSTRUCTORS>
<CONSTRUCTOR>
<KEY>.+</KEY>
<VALUE>/**\n
* Instantiates a new ${name}.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</CONSTRUCTOR>
</CONSTRUCTORS>
<METHODS>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(\w(\s*&lt;.+&gt;)*)+\s+get\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Gets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*(public|protected|private)*\s*.*(void|\w(\s*&lt;.+&gt;)*)+\s+set\w+\s*\(.*\).+</KEY>
<VALUE>/**\n
* Sets ${partName}.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${partName}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>^.*((public\s+static)|(static\s+public))\s+void\s+main\s*\(\s*String\s*(\[\s*\]|\.\.\.)\s+\w+\s*\).+</KEY>
<VALUE>/**\n
* The entry point of application.\n
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
* @param ${element.parameterList.parameters[0].name} the input arguments\n
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
<METHOD>
<KEY>.+</KEY>
<VALUE>/**\n
* ${name}&lt;#if isNotVoid&gt; ${return}&lt;/#if&gt;.\n
&lt;#if element.typeParameters?has_content&gt; * \n
&lt;/#if&gt;
&lt;#list element.typeParameters as typeParameter&gt;
* @param &lt;${typeParameter.name}&gt; the type parameter\n
&lt;/#list&gt;
&lt;#if element.parameterList.parameters?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.parameterList.parameters as parameter&gt;
* @param ${parameter.name} the ${paramNames[parameter.name]}\n
&lt;/#list&gt;
&lt;#if isNotVoid&gt;
*\n
* @return the ${return}\n
&lt;/#if&gt;
&lt;#if element.throwsList.referenceElements?has_content&gt;
*\n
&lt;/#if&gt;
&lt;#list element.throwsList.referenceElements as exception&gt;
* @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
&lt;/#list&gt;
*/</VALUE>
</METHOD>
</METHODS>
<FIELDS>
<FIELD>
<KEY>^.*(public|protected|private)*.+static.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
* The constant ${element.getName()}.\n
*/</VALUE>
</FIELD>
<FIELD>
<KEY>^.*(public|protected|private)*.*(\w\s\w)+.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isInterface()&gt;
* The constant ${element.getName()}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt; */</VALUE>
</FIELD>
<FIELD>
<KEY>.+</KEY>
<VALUE>/**\n
&lt;#if element.parent.isEnum()&gt;
*${name} ${typeName}.\n
&lt;#else&gt;
* The ${name}.\n
&lt;/#if&gt;*/</VALUE>
</FIELD>
</FIELDS>
</TEMPLATES>
</component>
</project>

View file

@ -2,11 +2,12 @@
<library name="bld"> <library name="bld">
<CLASSES> <CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" /> <root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.18.jar!/" /> <root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.5.18-sources.jar!/" /> <root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES> </SOURCES>
<excluded> <excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" /> <root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
@ -14,4 +15,4 @@
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" />
</library> </library>
</component> </component>

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" /> <root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" /> <root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" /> <root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

16
.idea/misc.xml generated
View file

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="EntryPointsManager">
<pattern value="rife.render.TemplateRenderersBuild" method="jacoco" />
<pattern value="rife.render.TemplateRenderersBuild" method="pmd" />
<pattern value="rife.render.ValueBean" method="setValue" />
</component>
<component name="PDMPlugin"> <component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\semver\config\pmd.xml" />
<option value="$PROJECT_DIR$/../bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-testng/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-generated-version/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-pitest/config/pmd.xml" />
</list>
</option>
<option name="skipTestSources" value="false" /> <option name="skipTestSources" value="false" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">

10
.vscode/settings.json vendored
View file

@ -3,13 +3,13 @@
"src/main/java", "src/main/java",
"src/main/resources", "src/main/resources",
"src/test/java", "src/test/java",
"src/bld/java" "src/test/resources",
"src/bld/java",
"src/bld/resources"
], ],
"java.configuration.updateBuildConfiguration": "automatic", "java.configuration.updateBuildConfiguration": "automatic",
"java.project.referencedLibraries": [ "java.project.referencedLibraries": [
"${HOME}/.rife2/dist/rife2-1.5.18.jar", "${HOME}/.bld/dist/bld-2.2.1.jar",
"lib/compile/*.jar", "lib/**/*.jar"
"lib/runtime/*.jar",
"lib/test/*.jar"
] ]
} }

View file

@ -1,7 +1,9 @@
[![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
[![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/rife2/rife2-template-renderers)](https://github.com/rife2/rife2-template-renderers/releases/latest) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/rife2/rife2-template-renderers)](https://github.com/rife2/rife2-template-renderers/releases/latest)
[![Maven Central](https://img.shields.io/maven-central/v/com.uwyn.rife2/rife2-renderers)](https://central.sonatype.com/artifact/com.uwyn.rife2/rife2-renderers/1.1.0) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/rife2-renderers/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/rife2-renderers)
[![Maven Central](https://img.shields.io/maven-central/v/com.uwyn.rife2/rife2-renderers)](https://central.sonatype.com/artifact/com.uwyn.rife2/rife2-renderers/)
[![Nexus Snapshot](https://img.shields.io/nexus/s/com.uwyn.rife2/rife2-renderers?server=https%3A%2F%2Fs01.oss.sonatype.org%2F)](https://s01.oss.sonatype.org/content/repositories/snapshots/com/uwyn/rife2/rife2-renderers/) [![Nexus Snapshot](https://img.shields.io/nexus/s/com.uwyn.rife2/rife2-renderers?server=https%3A%2F%2Fs01.oss.sonatype.org%2F)](https://s01.oss.sonatype.org/content/repositories/snapshots/com/uwyn/rife2/rife2-renderers/)
[![GitHub CI](https://github.com/rife2/rife2-template-renderers/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/rife2-template-renderers/actions/workflows/bld.yml) [![GitHub CI](https://github.com/rife2/rife2-template-renderers/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/rife2-template-renderers/actions/workflows/bld.yml)
[![Tests](https://rife2.com/tests-badge/badge/com.uwyn.rife2/rife2-renderers)](https://github.com/rife2/rife2-template-renderers/actions/workflows/gradle.yml) [![Tests](https://rife2.com/tests-badge/badge/com.uwyn.rife2/rife2-renderers)](https://github.com/rife2/rife2-template-renderers/actions/workflows/gradle.yml)
@ -49,16 +51,17 @@ This project provides a collection of useful template renderers.
## Text Renderers ## Text Renderers
| Renderer | Description | | Renderer | Description |
|:------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------| |:------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------|
| [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value | | [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value |
| [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase | | [rife.render.CapitalizeWords](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.CapitalizeWords) | Capitalizes words of a template value |
| [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 | | [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase |
| [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swap case of a template value | | [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 |
| [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value | | [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swaps case of a template value |
| [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value | | [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value |
| [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase | | [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value |
| [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase |
## Documentation ## Documentation
Read more in the [documenation](https://github.com/rife2/rife2-template-renderers/wiki). Read more in the [documentation](https://github.com/rife2/rife2-template-renderers/wiki).

View file

@ -7,8 +7,9 @@
<!-- BEST PRACTICES --> <!-- BEST PRACTICES -->
<rule ref="category/java/bestpractices.xml"> <rule ref="category/java/bestpractices.xml">
<exclude name="AvoidPrintStackTrace"/> <exclude name="AvoidPrintStackTrace"/>
<exclude name="JUnit4TestShouldUseTestAnnotation"/> <exclude name="GuardLogStatement"/>
<exclude name="JUnitTestContainsTooManyAsserts"/> <exclude name="UnitTestContainsTooManyAsserts"/>
<exclude name="UnitTestShouldUseTestAnnotation"/>
</rule> </rule>
<rule ref="category/java/bestpractices.xml/MissingOverride"> <rule ref="category/java/bestpractices.xml/MissingOverride">
@ -25,7 +26,6 @@
<exclude name="ClassNamingConventions"/> <exclude name="ClassNamingConventions"/>
<exclude name="CommentDefaultAccessModifier"/> <exclude name="CommentDefaultAccessModifier"/>
<exclude name="ConfusingTernary"/> <exclude name="ConfusingTernary"/>
<exclude name="DefaultPackage"/>
<exclude name="FieldNamingConventions"/> <exclude name="FieldNamingConventions"/>
<exclude name="LocalVariableCouldBeFinal"/> <exclude name="LocalVariableCouldBeFinal"/>
<exclude name="LongVariable"/> <exclude name="LongVariable"/>
@ -35,8 +35,15 @@
<exclude name="ShortClassName"/> <exclude name="ShortClassName"/>
<exclude name="ShortMethodName"/> <exclude name="ShortMethodName"/>
<exclude name="ShortVariable"/> <exclude name="ShortVariable"/>
<exclude name="UselessParentheses"/> <exclude name="UseExplicitTypes"/>
<exclude name="UseUnderscoresInNumericLiterals"/> <exclude name="UseUnderscoresInNumericLiterals"/>
<exclude name="UselessParentheses"/>
</rule>
<rule ref="category/java/codestyle.xml/UnnecessaryImport">
<properties>
<property name="violationSuppressRegex" value="Unused (static|.*\.\*).*"/>
</properties>
</rule> </rule>
<!-- DESIGN --> <!-- DESIGN -->
@ -46,8 +53,6 @@
<exclude name="AvoidUncheckedExceptionsInSignatures"/> <exclude name="AvoidUncheckedExceptionsInSignatures"/>
<exclude name="CognitiveComplexity"/> <exclude name="CognitiveComplexity"/>
<exclude name="CyclomaticComplexity"/> <exclude name="CyclomaticComplexity"/>
<exclude name="ExcessiveClassLength"/>
<exclude name="ExcessiveMethodLength"/>
<exclude name="ExcessiveParameterList"/> <exclude name="ExcessiveParameterList"/>
<exclude name="ExcessivePublicCount"/> <exclude name="ExcessivePublicCount"/>
<exclude name="GodClass"/> <exclude name="GodClass"/>
@ -74,7 +79,6 @@
<exclude name="AvoidFieldNameMatchingMethodName"/> <exclude name="AvoidFieldNameMatchingMethodName"/>
<exclude name="AvoidFieldNameMatchingTypeName"/> <exclude name="AvoidFieldNameMatchingTypeName"/>
<exclude name="AvoidLiteralsInIfCondition"/> <exclude name="AvoidLiteralsInIfCondition"/>
<exclude name="EmptyCatchBlock"/>
<exclude name="NullAssignment"/> <exclude name="NullAssignment"/>
</rule> </rule>
@ -90,13 +94,6 @@
<property name="skipAnnotations" value="true"/> <property name="skipAnnotations" value="true"/>
</properties> </properties>
</rule> </rule>
<rule ref="category/java/errorprone.xml/EmptyCatchBlock">
<properties>
<property name="allowExceptionNameRegex">
<value>^ignore$</value>
</property>
</properties>
</rule>
<!-- MULTITHREADING --> <!-- MULTITHREADING -->
<rule ref="category/java/multithreading.xml"> <rule ref="category/java/multithreading.xml">

Binary file not shown.

View file

@ -1,6 +1,8 @@
bld.downloadExtensionJavadoc=false bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true bld.downloadExtensionSources=true
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.1.0 bld.downloadLocation=
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.9
rife2.downloadLocation= bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.2.0
rife2.version=1.5.18 bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.4.6
bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.version=2.2.1

View file

@ -1,6 +1,26 @@
/*
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package rife.render; package rife.render;
import rife.bld.BuildCommand;
import rife.bld.Project; import rife.bld.Project;
import rife.bld.extension.JacocoReportOperation;
import rife.bld.extension.PmdOperation;
import rife.bld.extension.TestsBadgeOperation; import rife.bld.extension.TestsBadgeOperation;
import rife.bld.publish.PublishDeveloper; import rife.bld.publish.PublishDeveloper;
import rife.bld.publish.PublishInfo; import rife.bld.publish.PublishInfo;
@ -10,7 +30,8 @@ import rife.bld.publish.PublishScm;
import java.util.List; import java.util.List;
import static rife.bld.dependencies.Repository.*; import static rife.bld.dependencies.Repository.*;
import static rife.bld.dependencies.Scope.*; import static rife.bld.dependencies.Scope.compile;
import static rife.bld.dependencies.Scope.test;
import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING; import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING;
public class TemplateRenderersBuild extends Project { public class TemplateRenderersBuild extends Project {
@ -19,64 +40,86 @@ public class TemplateRenderersBuild extends Project {
public TemplateRenderersBuild() { public TemplateRenderersBuild() {
pkg = "rife.render"; pkg = "rife.render";
name = "rife2-template-renderers"; name = "rife2-template-renderers";
version = version(1, 1, 1); version = version(1, 2, 1, "SNAPSHOT");
javaRelease = 17;
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
scope(compile)
.include(dependency("com.uwyn.rife2", "rife2", version(1, 9, 1)));
scope(test)
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 0)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 0)))
.include(dependency("org.assertj", "assertj-core", version(3, 27, 3)));
javadocOperation().javadocOptions() javadocOperation().javadocOptions()
.docTitle("<a href=\"https://rife2.com\">RIFE2</a> Template Renderers") .docTitle("<a href=\"https://rife2.com\">RIFE2</a> Template Renderers")
.author()
.docLint(NO_MISSING) .docLint(NO_MISSING)
.link("https://rife2.github.io/rife2/"); .link("https://rife2.github.io/rife2/");
publishOperation() publishOperation()
.repository(version.isSnapshot() ? repository(RIFE2_SNAPSHOTS.location()) .repository(version.isSnapshot() ? SONATYPE_SNAPSHOTS
.withCredentials(property("rife2Username"), property("rife2Password")) .withCredentials(property("sonatypeUser"), property("sonatypePassword"))
: repository(RIFE2_RELEASES.location()) : SONATYPE_RELEASES
.withCredentials(property("rife2Username"), property("rife2Password")))
.repository(repository(SONATYPE_RELEASES.location())
.withCredentials(property("sonatypeUser"), property("sonatypePassword"))) .withCredentials(property("sonatypeUser"), property("sonatypePassword")))
.repository(version.isSnapshot() ? RIFE2_SNAPSHOTS
.withCredentials(property("rife2Username"), property("rife2Password"))
: RIFE2_RELEASES
.withCredentials(property("rife2Username"), property("rife2Password")))
.info(new PublishInfo() .info(new PublishInfo()
.groupId("com.uwyn.rife2") .groupId("com.uwyn.rife2")
.artifactId("rife2-renderers") .artifactId("rife2-renderers")
.name("RIFE2 Template Renderers") .name("RIFE2 Template Renderers")
.description("Template Renderers for the RIFE2 web framework") .description("Template Renderers for the RIFE2 web framework")
.url("https://github.com/rife2/rife2-template-renderers") .url("https://github.com/rife2/rife2-template-renderers")
.developer(new PublishDeveloper().id("ethauvin").name("Erik C. Thauvin").email("erik@thauvin.net") .developer(new PublishDeveloper()
.id("ethauvin")
.name("Erik C. Thauvin")
.email("erik@thauvin.net")
.url("https://erik.thauvin.net/")) .url("https://erik.thauvin.net/"))
.developer(new PublishDeveloper().id("gbevin").name("Geert Bevin").email("gbevin@uwyn.com") .developer(new PublishDeveloper()
.id("gbevin")
.name("Geert Bevin")
.email("gbevin@uwyn.com")
.url("https://github.com/gbevin")) .url("https://github.com/gbevin"))
.license(new PublishLicense().name("The Apache License, Version 2.0") .license(new PublishLicense()
.url("http://www.apache.org/licenses/LICENSE-2.0.txt")) .name("The Apache License, Version 2.0")
.scm(new PublishScm().connection("scm:git:https://github.com/rife2/rife2-template-renderers.git") .url("https://www.apache.org/licenses/LICENSE-2.0.txt"))
.scm(new PublishScm()
.connection("scm:git:https://github.com/rife2/rife2-template-renderers.git")
.developerConnection("scm:git:git@github.com:rife2/rife2-template-renderers.git") .developerConnection("scm:git:git@github.com:rife2/rife2-template-renderers.git")
.url("https://github.com/rife2/rife2-template-renderers")) .url("https://github.com/rife2/rife2-template-renderers"))
.signKey(property("signKey")) .signKey(property("signKey"))
.signPassphrase(property("signPassphrase"))); .signPassphrase(property("signPassphrase")));
javaRelease = 17;
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS);
scope(compile)
.include(dependency("com.uwyn.rife2", "rife2", version(1, 5, 18)));
scope(test)
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 9, 2)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 9, 2)))
.include(dependency("org.assertj:assertj-core:3.24.2"));
} }
public static void main(String[] args) { public static void main(String[] args) {
new TemplateRenderersBuild().start(args); new TemplateRenderersBuild().start(args);
} }
@BuildCommand(summary = "Generates JaCoCo Reports")
public void jacoco() throws Exception {
new JacocoReportOperation()
.fromProject(this)
.execute();
}
@BuildCommand(summary = "Runs PMD analysis")
public void pmd() throws Exception {
new PmdOperation()
.fromProject(this)
.failOnViolation(true)
.ruleSets("config/pmd.xml")
.execute();
}
public void test() throws Exception { public void test() throws Exception {
testsBadgeOperation.executeOnce(() -> testsBadgeOperation testsBadgeOperation.executeOnce(() -> testsBadgeOperation
.url(property("testsBadgeUrl")) .url(property("testsBadgeUrl"))
.apiKey(property("testsBadgeApiKey")) .apiKey(property("testsBadgeApiKey"))
.fromProject(this)); .fromProject(this));
} }
}
@Override
public void precompile() throws Exception {
// TODO remove when fixed in bld
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ import rife.template.Template;
import rife.template.ValueRenderer; import rife.template.ValueRenderer;
/** /**
* <p>Abbreviate a template value with ellipses.</p> * <p>Abbreviates a template value with ellipses.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -36,7 +36,18 @@ import rife.template.ValueRenderer;
*/ */
public class Abbreviate implements ValueRenderer { public class Abbreviate implements ValueRenderer {
/** /**
* {@inheritDoc} * <p>Returns the template value abbreviated with ellipses.</p>
*
* <p>Two parameters can be specified:</p>
* <ul>
* <li><code>mark</code>: the string that will be used to abbreviate the value. Default is <code>...</code></li>
* <li><code>max</code>: the maximum number of characters to render. Default is <code>-1</code> (no abbreviation).</li>
* </ul>
*
* @param template the template that contains the value
* @param valueId the id of the value to render
* @param differentiator a generic string that can be used to differentiate the rendering
* @return the abbreviated value, or the original value if no abbreviation is necessary
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class BeatTime implements ValueRenderer { public class BeatTime implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current time in Swatch Internet (.beat) Time format.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the rendered value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,7 +37,12 @@ import rife.tools.StringUtils;
*/ */
public class Capitalize implements ValueRenderer { public class Capitalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value by capitalizing it.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the capitalized and encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -0,0 +1,50 @@
/*
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package rife.render;
import rife.template.Template;
import rife.template.ValueRenderer;
/**
* <p>Capitalizes words of a template value.</p>
*
* <p>Usage:</p>
*
* <pre>
* &lt;!--v render:rife.render.CapitalizeWords:valueId/--&gt;
* {{v render:rife.render.CapitalizeWords:valueId/}}
* </pre>
*
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @see <a href="https://github.com/rife2/rife2-template-renderers/wiki/rife.render.CapitalizeWords">rife.render.CapitalizeWords</a>
* @since 1.2
*/
public class CapitalizeWords implements ValueRenderer {
/**
* Returns the template value by capitalizing it.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the capitalized and encoded value
*/
@Override
public String render(Template template, String valueId, String differentiator) {
return template.getEncoder().encode(RenderUtils.capitalizeWords(template.getValueOrAttribute(differentiator)));
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date in ISO 8601 format.</p> * <p>Renders the current date in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class DateIso implements ValueRenderer { public class DateIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current date in ISO 8601 format, encoded according to the template's encoding rules.
*
* @param template the template that is currently being rendered
* @param valueId the value id that triggers the rendering of this value renderer
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current date in ISO 8601 format, encoded according to the template's encoding rules
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,7 +24,7 @@ import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date and time in ISO 8601 format.</p> * <p>Renders the current date and time in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -39,7 +39,15 @@ import java.time.ZonedDateTime;
*/ */
public class DateTimeIso implements ValueRenderer { public class DateTimeIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the current date and time in ISO 8601 format.
*
* <p>Additionally, it allows specifying a time zone through the template's default value properties with the key
* {@code tz}. If no time zone is specified, the system default time zone is used.</p>
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to be rendered
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current date and time in ISO 8601 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date and time in RFC 2822 format.</p> * <p>Renders the current date and time in RFC 2822 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class DateTimeRfc2822 implements ValueRenderer { public class DateTimeRfc2822 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current date and time in RFC 2822 format.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the current date and time in RFC 2822 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,7 +40,12 @@ import java.nio.charset.StandardCharsets;
*/ */
public class EncodeBase64 implements ValueRenderer { public class EncodeBase64 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to Base64.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the Base64-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeHtml implements ValueRenderer { public class EncodeHtml implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to HTML.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the HTML-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class EncodeHtmlEntities implements ValueRenderer { public class EncodeHtmlEntities implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to HTML decimal entities.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeJs implements ValueRenderer { public class EncodeJs implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to JavaScript/ECMAScript.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the JavaScript/ECMAScript-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeJson implements ValueRenderer { public class EncodeJson implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to JSON.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the JSON-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeUnicode implements ValueRenderer { public class EncodeUnicode implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to Unicode escape codes.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the Unicode escape codes-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeUrl implements ValueRenderer { public class EncodeUrl implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to URL.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the URL-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeXml implements ValueRenderer { public class EncodeXml implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to XML.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the XML-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class FormatCreditCard implements ValueRenderer { public class FormatCreditCard implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the last 4 digits of the template credit number value.
*
* @param template the {@link Template}
* @param valueId the value id
* @param differentiator the differentiator
* @return the formatted value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,7 +37,12 @@ import rife.tools.Localization;
*/ */
public class Lowercase implements ValueRenderer { public class Lowercase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value converted to lowercase.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the lowercase value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,8 +35,30 @@ import rife.template.ValueRenderer;
* @since 1.0 * @since 1.0
*/ */
public class Mask implements ValueRenderer { public class Mask implements ValueRenderer {
/** /**
* {@inheritDoc} * <p>Renders a template value with characters of the value masked using the specified mask.</p>
*
* <p>The mask is specified as a template default value with the following syntax:</p>
*
* <pre>
* mask=&lt;mask&gt;[,unmasked=&lt;unmasked&gt;][,fromStart=&lt;fromStart&gt;]
* </pre>
*
* <p>Where:</p>
*
* <ul>
* <li><var>mask</var> is the character to use for masking, defaulting to <code>*</code></li>
* <li><var>unmasked</var> is the number of characters at the beginning of the value that should be left unmasked,
* defaulting to <code>0</code></li>
* <li><var>fromStart</var> is a boolean indicating whether the <var>unmasked</var> value should be counted from
* the start of the value, defaulting to <code>false</code></li>
* </ul>
*
* @param template the template to render the value in
* @param valueId the ID of the value to render
* @param differentiator the differentiator of the value to render
* @return the rendered value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {
@ -49,7 +71,7 @@ public class Mask implements ValueRenderer {
mask = properties.getProperty("mask", mask); mask = properties.getProperty("mask", mask);
try { try {
unmasked = Integer.parseInt(properties.getProperty("unmasked", "0")); unmasked = Integer.parseInt(properties.getProperty("unmasked", "0"));
} catch (NumberFormatException ignore) { } catch (NumberFormatException ignored) {
// do nothing // do nothing
} }
fromStart = "true".equalsIgnoreCase(properties.getProperty("fromStart", "false")); fromStart = "true".equalsIgnoreCase(properties.getProperty("fromStart", "false"));

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Normalize implements ValueRenderer { public class Normalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value normalized for inclusion in a URL path.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the normalized value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class QrCode implements ValueRenderer { public class QrCode implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded as an SVG QR Code.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the SVG QR Code
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,7 +30,6 @@ import java.text.Normalizer;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
@ -84,7 +83,7 @@ public final class RenderUtils {
DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss zzz").withLocale(Localization.getLocale()); DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss zzz").withLocale(Localization.getLocale());
private static final String DEFAULT_USER_AGENT = private static final String DEFAULT_USER_AGENT =
"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0"; "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0";
private final static Logger LOGGER = Logger.getLogger(RenderUtils.class.getName()); private static final Logger LOGGER = Logger.getLogger(RenderUtils.class.getName());
private RenderUtils() { private RenderUtils() {
// no-op // no-op
@ -120,11 +119,43 @@ public final class RenderUtils {
*/ */
public static String beatTime(ZonedDateTime zonedDateTime) { public static String beatTime(ZonedDateTime zonedDateTime) {
var zdt = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC+01:00")); var zdt = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC+01:00"));
var beats = (int) ((zdt.get(ChronoField.SECOND_OF_MINUTE) + (zdt.get(ChronoField.MINUTE_OF_HOUR) * 60) + var beats = (int) ((zdt.getSecond() + (zdt.getMinute() * 60) +
(zdt.get(ChronoField.HOUR_OF_DAY) * 3600)) / 86.4); (zdt.getHour() * 3600)) / 86.4);
return String.format("@%03d", beats); return String.format("@%03d", beats);
} }
/**
* Returns a {@code String} with the first letter of each word capitalized.
*
* @param src the source {@code String}
* @return the capitalized {@code String}
*/
public static String capitalizeWords(String src) {
if (src == null || src.isBlank()) {
return src;
}
var result = new StringBuilder();
var capitalizeNext = true;
for (var i = 0; i < src.length(); i++) {
var c = src.charAt(i);
if (Character.isWhitespace(c)) {
capitalizeNext = true;
result.append(c);
} else {
if (capitalizeNext) {
result.append(Character.toUpperCase(c));
} else {
result.append(Character.toLowerCase(c));
}
capitalizeNext = false;
}
}
return result.toString();
}
/** /**
* <p>Encodes the source {@code String} to the specified encoding.</p> * <p>Encodes the source {@code String} to the specified encoding.</p>
* *
@ -154,7 +185,7 @@ public final class RenderUtils {
return StringUtils.encodeHtml(src); return StringUtils.encodeHtml(src);
} }
case "js" -> { case "js" -> {
return RenderUtils.encodeJs(src); return encodeJs(src);
} }
case "json" -> { case "json" -> {
return StringUtils.encodeJson(src); return StringUtils.encodeJson(src);
@ -196,6 +227,11 @@ public final class RenderUtils {
case '"' -> sb.append("\\\""); case '"' -> sb.append("\\\"");
case '\\' -> sb.append("\\\\"); case '\\' -> sb.append("\\\\");
case '/' -> sb.append("\\/"); case '/' -> sb.append("\\/");
case '\b' -> sb.append("\\b");
case '\n' -> sb.append(("\\n"));
case '\t' -> sb.append("\\t");
case '\f' -> sb.append("\\f");
case '\r' -> sb.append("\\r");
default -> sb.append(c); default -> sb.append(c);
} }
} }
@ -212,8 +248,9 @@ public final class RenderUtils {
public static String fetchUrl(String url, String defaultContent) { public static String fetchUrl(String url, String defaultContent) {
try { try {
var fetchUrl = new URL(url); var fetchUrl = new URL(url);
HttpURLConnection connection = null;
try { try {
var connection = (HttpURLConnection) fetchUrl.openConnection(); connection = (HttpURLConnection) fetchUrl.openConnection();
connection.setRequestProperty("User-Agent", DEFAULT_USER_AGENT); connection.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
var code = connection.getResponseCode(); var code = connection.getResponseCode();
if (code >= 200 && code <= 399) { if (code >= 200 && code <= 399) {
@ -229,10 +266,15 @@ public final class RenderUtils {
if (LOGGER.isLoggable(Level.WARNING)) { if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, "An IO error occurred while connecting to " + fetchUrl.getHost(), ioe); LOGGER.log(Level.WARNING, "An IO error occurred while connecting to " + fetchUrl.getHost(), ioe);
} }
} finally {
if (connection != null) {
connection.disconnect();
}
} }
} catch (MalformedURLException ignore) { } catch (MalformedURLException ignored) {
// do nothing // do nothing
} }
return defaultContent; return defaultContent;
} }
@ -330,21 +372,20 @@ public final class RenderUtils {
return src; return src;
} }
var normalized = Normalizer.normalize(src.trim(), Normalizer.Form.NFD); var normalized = Normalizer.normalize(src.trim(), Normalizer.Form.NFD).toCharArray();
var sb = new StringBuilder(normalized.length());
boolean space = false; var sb = new StringBuilder(normalized.length);
for (var c : normalized.toCharArray()) { for (var i = 0; i < normalized.length; i++) {
if (c <= '\u007F') { // ascii only var c = normalized[i];
if (!space && c == ' ') { if (c <= '\u007F') { // ASCII only
space = true; if (" &()-_=[{]}\\|;:,<.>/".indexOf(c) != -1) { // common separators
sb.append('-'); if (!sb.isEmpty() && i != normalized.length - 1 && sb.charAt(sb.length() - 1) != '-') {
} else { sb.append('-');
space = false;
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')) {
sb.append(c);
} else if (c >= 'A' && c <= 'Z') {
sb.append((char) (c + 32)); // lowercase
} }
} else if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z') { // letters & digits
sb.append(c);
} else if (c >= 'A' && c <= 'Z') { // uppercase letters
sb.append((char) (c + 32)); // make lowercase
} }
} }
} }
@ -362,7 +403,7 @@ public final class RenderUtils {
if (src != null && !src.isBlank()) { if (src != null && !src.isBlank()) {
try { try {
properties.load(new StringReader(src)); properties.load(new StringReader(src));
} catch (IOException ignore) { } catch (IOException ignored) {
// ignore // ignore
} }
} }
@ -419,7 +460,7 @@ public final class RenderUtils {
for (var i = 0; i < len; i++) { for (var i = 0; i < len; i++) {
var inChar = src.charAt(i); var inChar = src.charAt(i);
if ((inChar >= 'A') && (inChar <= 'Z')) { if (inChar >= 'A' && inChar <= 'Z') {
inChar += (char) 13; inChar += (char) 13;
if (inChar > 'Z') { if (inChar > 'Z') {
@ -427,7 +468,7 @@ public final class RenderUtils {
} }
} }
if ((inChar >= 'a') && (inChar <= 'z')) { if (inChar >= 'a' && inChar <= 'z') {
inChar += (char) 13; inChar += (char) 13;
if (inChar > 'z') { if (inChar > 'z') {
@ -593,7 +634,7 @@ public final class RenderUtils {
return true; return true;
} }
} }
} catch (NumberFormatException ignore) { } catch (NumberFormatException ignored) {
// do nothing // do nothing
} }
return false; return false;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Rot13 implements ValueRenderer { public class Rot13 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value translated to/from ROT13.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the ROT13 value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import rife.template.ValueRenderer;
*/ */
public class ShortenUrl implements ValueRenderer { public class ShortenUrl implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value shortened using <a href="https://is.gd/">is.gid</a>.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the template shortened value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ import rife.template.Template;
import rife.template.ValueRenderer; import rife.template.ValueRenderer;
/** /**
* <p>Swap case of a template value.</p> * <p>Swaps case of a template value.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -35,9 +35,13 @@ import rife.template.ValueRenderer;
* @since 1.0 * @since 1.0
*/ */
public class SwapCase implements ValueRenderer { public class SwapCase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value with swapped case.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the swapped case value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current time in ISO 8601 format.</p> * <p>Renders the current time in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class TimeIso implements ValueRenderer { public class TimeIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current time in ISO 8601 format.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to be rendered
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current time in ISO 8601 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Trim implements ValueRenderer { public class Trim implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the template value by removing leading and trailing whitespace.
*
* @param template the template instance
* @param valueId the id of the value to render
* @param differentiator an optional differentiator to use for cache invalidation
* @return the trimmed value, or the original value if it is {@code null} or empty
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,7 +37,12 @@ import rife.tools.StringUtils;
*/ */
public class Uncapitalize implements ValueRenderer { public class Uncapitalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the un-capitalized template value.
*
* @param template the template to render
* @param valueId the id of the value to render
* @param differentiator the differentiator to use for the value lookup
* @return the un-capitalized value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import rife.template.ValueRenderer;
import rife.tools.Localization; import rife.tools.Localization;
/** /**
* <p>Convert a template value to uppercase.</p> * <p>Converts a template value to uppercase.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -37,7 +37,12 @@ import rife.tools.Localization;
*/ */
public class Uppercase implements ValueRenderer { public class Uppercase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value converted to uppercase.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the uppercased value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -38,7 +38,12 @@ import java.lang.management.ManagementFactory;
*/ */
public class Uptime implements ValueRenderer { public class Uptime implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the server uptime.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to render
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the server uptime
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,9 +37,13 @@ import java.time.ZonedDateTime;
* @since 1.0 * @since 1.0
*/ */
public class Year implements ValueRenderer { public class Year implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the current year.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to render
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current year
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,7 +30,7 @@ import java.lang.annotation.Target;
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a> * @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.0 * @since 1.0
*/ */
@Target({ ElementType.TYPE, ElementType.METHOD }) @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisableOnCiCondition.class) @ExtendWith(DisableOnCiCondition.class)
public @interface DisabledOnCi { public @interface DisabledOnCi {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,6 +40,9 @@ class TestCase {
var bean = new ValueBean("this IS a TEST."); var bean = new ValueBean("this IS a TEST.");
t.setBean(bean); t.setBean(bean);
assertThat(t.getContent()).isEqualTo(bean.getValue() + ": this is a test."); assertThat(t.getContent()).isEqualTo(bean.getValue() + ": this is a test.");
bean = new ValueBean("");
t.setBean(bean);
assertThat(t.getContent()).isEqualTo(bean.getValue() + ": ");
} }
@Test @Test
@ -54,6 +57,8 @@ class TestCase {
var t = TemplateFactory.TXT.get("trim"); var t = TemplateFactory.TXT.get("trim");
t.setAttribute(FOO, "\t" + SAMPLE_TEXT + " \n"); t.setAttribute(FOO, "\t" + SAMPLE_TEXT + " \n");
assertThat(t.getContent()).isEqualTo(SAMPLE_TEXT); assertThat(t.getContent()).isEqualTo(SAMPLE_TEXT);
t.setAttribute(FOO, "");
assertThat(t.getContent()).isEmpty();
} }
@Test @Test
@ -68,5 +73,7 @@ class TestCase {
var t = TemplateFactory.TXT.get("uppercase"); var t = TemplateFactory.TXT.get("uppercase");
t.setAttribute("bar", SAMPLE_TEXT); t.setAttribute("bar", SAMPLE_TEXT);
assertThat(t.getContent()).isEqualTo(SAMPLE_TEXT.toUpperCase(Localization.getLocale())); assertThat(t.getContent()).isEqualTo(SAMPLE_TEXT.toUpperCase(Localization.getLocale()));
t.setAttribute("bar", "");
assertThat(t.getContent()).isEmpty();
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,6 +55,10 @@ class TestEncode {
t.setAttribute(TestCase.FOO, "'\"\\/"); t.setAttribute(TestCase.FOO, "'\"\\/");
assertThat(t.getContent()).isEqualTo("\\'\\\"\\\\\\/"); assertThat(t.getContent()).isEqualTo("\\'\\\"\\\\\\/");
t = TemplateFactory.TXT.get("encodeJs");
t.setAttribute(TestCase.FOO, "This is\f\b a\r\n\ttest");
assertThat(t.getContent()).isEqualTo("This is\\f\\b a\\r\\n\\ttest");
t = TemplateFactory.HTML.get("encodeJs"); t = TemplateFactory.HTML.get("encodeJs");
t.setAttribute(TestCase.FOO, '"' + TestCase.SAMPLE_TEXT + '"'); t.setAttribute(TestCase.FOO, '"' + TestCase.SAMPLE_TEXT + '"');
assertThat(t.getContent()).as("with unicode") assertThat(t.getContent()).as("with unicode")

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@
package rife.render; package rife.render;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import rife.template.TemplateFactory; import rife.template.TemplateFactory;
@ -45,7 +44,9 @@ class TestFormat {
t.setAttribute(TestCase.FOO, "374380141731053"); t.setAttribute(TestCase.FOO, "374380141731053");
assertThat(t.getContent()).as("UK AMEX").isEqualTo("1053"); assertThat(t.getContent()).as("UK AMEX").isEqualTo("1053");
t.setAttribute(TestCase.FOO, "000000000000001"); t.setAttribute(TestCase.FOO, "000000000000001");
assertThat(t.getContent()).isEmpty(); assertThat(t.getContent()).as("000000000000001").isEmpty();
t.setAttribute(TestCase.FOO, "");
assertThat(t.getContent()).as("").isEmpty();
} }
@Test @Test

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package rife.render; package rife.render;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Properties; import java.util.Properties;
@ -35,11 +36,28 @@ class TestRenderUtils {
assertThat(RenderUtils.abbreviate(TestCase.SAMPLE_TEXT, -1, "")).as("max=-1") assertThat(RenderUtils.abbreviate(TestCase.SAMPLE_TEXT, -1, "")).as("max=-1")
.isEqualTo(TestCase.SAMPLE_TEXT); .isEqualTo(TestCase.SAMPLE_TEXT);
assertThat(RenderUtils.abbreviate("", 10, "")).as("").isEmpty();
}
@Test
void testCapitalizeWords() {
assertThat(RenderUtils.capitalizeWords("hello world")).isEqualTo("Hello World");
assertThat(RenderUtils.capitalizeWords("java programming")).isEqualTo("Java Programming");
assertThat(RenderUtils.capitalizeWords("TEST")).isEqualTo("Test");
assertThat(RenderUtils.capitalizeWords("multiple spaces")).isEqualTo("Multiple Spaces");
assertThat(RenderUtils.capitalizeWords("white\t\fspaces")).isEqualTo("White\t\fSpaces");
assertThat(RenderUtils.capitalizeWords("")).isEmpty();
assertThat(RenderUtils.capitalizeWords(null)).isNull();
} }
@Test @Test
void testEncode() { void testEncode() {
var p = new Properties(); var p = new Properties();
p.put(RenderUtils.ENCODING_PROPERTY, "blah");
assertThat(RenderUtils.encode(TestCase.SAMPLE_TEXT, p)).as("invalid encoding").isEqualTo(TestCase.SAMPLE_TEXT);
p.put(RenderUtils.ENCODING_PROPERTY, "json");
assertThat(RenderUtils.encode("This is a \"•test\"", p)).as("json").isEqualTo("This is a \\\"\\u2022test\\\"");
p.put(RenderUtils.ENCODING_PROPERTY, "html"); p.put(RenderUtils.ENCODING_PROPERTY, "html");
assertThat(RenderUtils.encode("<a test &>", p)).as("html").isEqualTo("&lt;a test &amp;&gt;"); assertThat(RenderUtils.encode("<a test &>", p)).as("html").isEqualTo("&lt;a test &amp;&gt;");
p.put(RenderUtils.ENCODING_PROPERTY, "js"); p.put(RenderUtils.ENCODING_PROPERTY, "js");
@ -52,8 +70,22 @@ class TestRenderUtils {
assertThat(RenderUtils.encode("Joe's Café & Bar", p)).as("xml").isEqualTo("Joe&apos;s Café &amp; Bar"); assertThat(RenderUtils.encode("Joe's Café & Bar", p)).as("xml").isEqualTo("Joe&apos;s Café &amp; Bar");
} }
@Test
void testEncodeJs() {
assertThat(RenderUtils.encodeJs("")).isEmpty();
}
@Test
void testFetchUrl() {
var s = "default";
assertThat(RenderUtils.fetchUrl("blah", s)).isEqualTo(s);
assertThat(RenderUtils.fetchUrl("https://www.google.com/404", s)).isEqualTo(s);
assertThat(RenderUtils.fetchUrl("https://www.notreallythere.com/", s)).isEqualTo(s);
}
@Test @Test
void testHtmlEntities() { void testHtmlEntities() {
assertThat(RenderUtils.htmlEntities("")).isEmpty();
assertThat(RenderUtils.htmlEntities(SAMPLE_GERMAN)) assertThat(RenderUtils.htmlEntities(SAMPLE_GERMAN))
.isEqualTo("&#77;&#246;&#99;&#104;&#116;&#101;&#110;&#32;&#83;&#105;&#101;&#32;&#101;&#105;&#110;&#32;&#112;&#97;&#97;&#114;&#32;&#196;&#112;&#102;&#101;&#108;&#63;"); .isEqualTo("&#77;&#246;&#99;&#104;&#116;&#101;&#110;&#32;&#83;&#105;&#101;&#32;&#101;&#105;&#110;&#32;&#112;&#97;&#97;&#114;&#32;&#196;&#112;&#102;&#101;&#108;&#63;");
} }
@ -62,6 +94,8 @@ class TestRenderUtils {
void testMask() { void testMask() {
var foo = "4342256562440179"; var foo = "4342256562440179";
assertThat(RenderUtils.mask("", " ", 2, false)).isEmpty();
assertThat(RenderUtils.mask(foo, "?", 4, false)).as("mask=?") assertThat(RenderUtils.mask(foo, "?", 4, false)).as("mask=?")
.isEqualTo("????????????0179"); .isEqualTo("????????????0179");
@ -74,27 +108,43 @@ class TestRenderUtils {
@Test @Test
void testNormalize() { void testNormalize() {
assertThat(RenderUtils.normalize(SAMPLE_GERMAN)).isEqualTo("mochten-sie-ein-paar-apfel"); assertThat(RenderUtils.normalize("")).as("empty").isEmpty();
assertThat(RenderUtils.normalize(" &()-_=[{]}\\|;:,<.>/")).as("blank").isEmpty();
assertThat(RenderUtils.normalize(SAMPLE_GERMAN)).as("greman").isEqualTo("mochten-sie-ein-paar-apfel");
assertThat(RenderUtils.normalize("foo bar, <foo-bar>,foo:bar,foo;(bar), {foo} & bar=foo.bar[foo|bar]"))
.as("foo-bar")
.isEqualTo("foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar");
assertThat(RenderUtils.normalize("News for January 6, 2023 (Paris)")).as("docs example")
.isEqualTo("news-for-january-6-2023-paris");
}
@Test
void testQrCode() {
assertThat(RenderUtils.qrCode("", "12")).isEmpty();
} }
@Test @Test
void testRot13() { void testRot13() {
var encoded = "Zöpugra Fvr rva cnne Äcsry?"; var encoded = "Zöpugra Fvr rva cnne Äcsry?";
assertThat(RenderUtils.rot13("")).isEmpty();
assertThat(RenderUtils.rot13(SAMPLE_GERMAN)).as("encode").isEqualTo(encoded); assertThat(RenderUtils.rot13(SAMPLE_GERMAN)).as("encode").isEqualTo(encoded);
assertThat(RenderUtils.rot13(encoded)).as("decode").isEqualTo(SAMPLE_GERMAN); assertThat(RenderUtils.rot13(encoded)).as("decode").isEqualTo(SAMPLE_GERMAN);
} }
@Test @Test
void testSwapCase() { void testSwapCase() {
assertThat(RenderUtils.swapCase("")).isEmpty();
assertThat(RenderUtils.swapCase(SAMPLE_GERMAN)).isEqualTo("mÖCHTEN sIE EIN PAAR äPFEL?"); assertThat(RenderUtils.swapCase(SAMPLE_GERMAN)).isEqualTo("mÖCHTEN sIE EIN PAAR äPFEL?");
} }
@Test @Test
void testValidateCreditCard() { void testValidateCreditCard() {
assertThat(RenderUtils.validateCreditCard("4505 4672 3366 6430")).as("visa").isTrue(); try (var softly = new AutoCloseableSoftAssertions()) {
assertThat(RenderUtils.validateCreditCard("5189-5923-3915-0425")).as("mastercard").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("4505 4672 3366 6430")).as("visa").isTrue();
assertThat(RenderUtils.validateCreditCard("3433634926643302")).as("amex").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("5189-5923-3915-0425")).as("mastercard").isTrue();
assertThat(RenderUtils.validateCreditCard("6011 1076-8252 0629")).as("discover").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("3433634926643302")).as("amex").isTrue();
assertThat(RenderUtils.validateCreditCard("0123456789012345")).as("invalid").isFalse(); softly.assertThat(RenderUtils.validateCreditCard("6011 1076-8252 0629")).as("discover").isTrue();
softly.assertThat(RenderUtils.validateCreditCard("0123456789012345")).as("invalid").isFalse();
}
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2023 the original author or authors. * Copyright 2023-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.