From 91c0f8f6ed1b705c97bfb5c56cf7ae4a943fec46 Mon Sep 17 00:00:00 2001 From: Jon Clausen Date: Tue, 23 Jul 2024 08:40:34 -0600 Subject: [PATCH] Initial commit --- .cfconfig.json | 26 ++ .cfformat.json | 63 +++ .cflintrc | 59 +++ .editorconfig | 20 + .env.template | 7 + .gitattributes | 22 + .github/CODE_OF_CONDUCT.MD | 3 + .github/FUNDING.YML | 1 + .github/ISSUE_TEMPLATE/BUG_REPORT.md | 33 ++ .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 18 + .github/PULL_REQUEST_TEMPLATE.md | 29 ++ .github/SECURITY.md | 3 + .github/SUPPORT.md | 3 + .github/workflows/pr.yml | 30 ++ .github/workflows/release.yml | 175 ++++++++ .github/workflows/snapshot.yml | 48 +++ .github/workflows/tests.yml | 129 ++++++ .gitignore | 21 + .markdownlint.json | 16 + .vscode/settings.json | 14 + .vscode/tasks.json | 33 ++ CONTRIBUTING.md | 108 +++++ ModuleConfig.cfc | 47 +++ box.json | 54 +++ build/Build.cfc | 309 ++++++++++++++ build/SetupTemplate.cfc | 70 ++++ build/release.boxr | 14 + changelog.md | 14 + readme.md | 101 +++++ server-adobe@2018.json | 23 ++ server-adobe@2021.json | 29 ++ server-adobe@2023.json | 29 ++ server-lucee@5.json | 23 ++ server-lucee@6.json | 23 ++ test-harness/.cflintrc | 1 + test-harness/Application.cfc | 103 +++++ test-harness/box.json | 20 + test-harness/config/Application.cfc | 7 + test-harness/config/Coldbox.cfc | 87 ++++ test-harness/config/Router.cfc | 9 + test-harness/config/WireBox.cfc | 46 +++ test-harness/handlers/Main.cfc | 11 + test-harness/index.cfm | 9 + test-harness/layouts/Main.cfm | 6 + test-harness/tests/Application.cfc | 85 ++++ test-harness/tests/index.cfm | 119 ++++++ test-harness/tests/resources/coolblog.sql | 473 ++++++++++++++++++++++ test-harness/tests/runner.cfm | 13 + test-harness/tests/specs/ModuleSpec.cfc | 24 ++ test-harness/views/main/index.cfm | 3 + 50 files changed, 2613 insertions(+) create mode 100644 .cfconfig.json create mode 100644 .cfformat.json create mode 100644 .cflintrc create mode 100644 .editorconfig create mode 100644 .env.template create mode 100755 .gitattributes create mode 100644 .github/CODE_OF_CONDUCT.MD create mode 100644 .github/FUNDING.YML create mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/SECURITY.md create mode 100644 .github/SUPPORT.md create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/snapshot.yml create mode 100644 .github/workflows/tests.yml create mode 100644 .gitignore create mode 100644 .markdownlint.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 CONTRIBUTING.md create mode 100644 ModuleConfig.cfc create mode 100644 box.json create mode 100644 build/Build.cfc create mode 100644 build/SetupTemplate.cfc create mode 100755 build/release.boxr create mode 100644 changelog.md create mode 100644 readme.md create mode 100644 server-adobe@2018.json create mode 100644 server-adobe@2021.json create mode 100644 server-adobe@2023.json create mode 100644 server-lucee@5.json create mode 100644 server-lucee@6.json create mode 100644 test-harness/.cflintrc create mode 100644 test-harness/Application.cfc create mode 100644 test-harness/box.json create mode 100644 test-harness/config/Application.cfc create mode 100644 test-harness/config/Coldbox.cfc create mode 100755 test-harness/config/Router.cfc create mode 100644 test-harness/config/WireBox.cfc create mode 100644 test-harness/handlers/Main.cfc create mode 100644 test-harness/index.cfm create mode 100644 test-harness/layouts/Main.cfm create mode 100644 test-harness/tests/Application.cfc create mode 100644 test-harness/tests/index.cfm create mode 100644 test-harness/tests/resources/coolblog.sql create mode 100644 test-harness/tests/runner.cfm create mode 100644 test-harness/tests/specs/ModuleSpec.cfc create mode 100644 test-harness/views/main/index.cfm diff --git a/.cfconfig.json b/.cfconfig.json new file mode 100644 index 0000000..f9b3828 --- /dev/null +++ b/.cfconfig.json @@ -0,0 +1,26 @@ +{ + "adminPassword" : "coldbox", + "debuggingEnabled":true, + "debuggingReportExecutionTimes":false, + "disableInternalCFJavaComponents":false, + "inspectTemplate":"always", + "requestTimeout":"0,0,0,90", + "robustExceptionEnabled":true, + "datasources": { + "coolblog": { + "class":"${DB_CLASS}", + "dbdriver": "MySQL", + "dsn":"jdbc:mysql://{host}:{port}/{database}", + "custom":"useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC&useLegacyDatetimeCode=true&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true", + "host":"${DB_HOST:127.0.0.1}", + "username": "${DB_USER:root}", + "password": "${DB_PASSWORD}", + "database": "coolblog", + "port": "${DB_PORT:3306}", + "storage":"false", + "bundleName": "${DB_BUNDLENAME}", + "bundleVersion": "${DB_BUNDLEVERSION}", + "validate":"false" + } + } +} diff --git a/.cfformat.json b/.cfformat.json new file mode 100644 index 0000000..443ef67 --- /dev/null +++ b/.cfformat.json @@ -0,0 +1,63 @@ +{ + "array.empty_padding": false, + "array.padding": true, + "array.multiline.min_length": 50, + "array.multiline.element_count": 2, + "array.multiline.leading_comma.padding": true, + "array.multiline.leading_comma": false, + "alignment.consecutive.assignments": true, + "alignment.consecutive.properties": true, + "alignment.consecutive.params": true, + "alignment.doc_comments" : true, + "brackets.padding": true, + "comment.asterisks": "align", + "binary_operators.padding": true, + "for_loop_semicolons.padding": true, + "function_call.empty_padding": false, + "function_call.padding": true, + "function_call.multiline.leading_comma.padding": true, + "function_call.casing.builtin": "cfdocs", + "function_call.casing.userdefined": "camel", + "function_call.multiline.element_count": 3, + "function_call.multiline.leading_comma": false, + "function_call.multiline.min_length": 50, + "function_declaration.padding": true, + "function_declaration.empty_padding": false, + "function_declaration.multiline.leading_comma": false, + "function_declaration.multiline.leading_comma.padding": true, + "function_declaration.multiline.element_count": 3, + "function_declaration.multiline.min_length": 50, + "function_declaration.group_to_block_spacing": "compact", + "function_anonymous.empty_padding": false, + "function_anonymous.group_to_block_spacing": "compact", + "function_anonymous.multiline.element_count": 3, + "function_anonymous.multiline.leading_comma": false, + "function_anonymous.multiline.leading_comma.padding": true, + "function_anonymous.multiline.min_length": 50, + "function_anonymous.padding": true, + "indent_size": 4, + "keywords.block_to_keyword_spacing": "spaced", + "keywords.group_to_block_spacing": "spaced", + "keywords.padding_inside_group": true, + "keywords.spacing_to_block": "spaced", + "keywords.spacing_to_group": true, + "keywords.empty_group_spacing": false, + "max_columns": 115, + "metadata.multiline.element_count": 3, + "metadata.multiline.min_length": 50, + "method_call.chain.multiline" : 3, + "newline":"\n", + "property.multiline.element_count": 3, + "property.multiline.min_length": 30, + "parentheses.padding": true, + "strings.quote": "double", + "strings.attributes.quote": "double", + "struct.separator": " : ", + "struct.padding": true, + "struct.empty_padding": false, + "struct.multiline.leading_comma": false, + "struct.multiline.leading_comma.padding": true, + "struct.multiline.element_count": 2, + "struct.multiline.min_length": 60, + "tab_indent": true +} diff --git a/.cflintrc b/.cflintrc new file mode 100644 index 0000000..a3e8368 --- /dev/null +++ b/.cflintrc @@ -0,0 +1,59 @@ +{ + "rule": [], + "includes": [ + { "code": "AVOID_USING_CFINCLUDE_TAG" }, + { "code": "AVOID_USING_CFABORT_TAG" }, + { "code": "AVOID_USING_CFEXECUTE_TAG" }, + { "code": "AVOID_USING_DEBUG_ATTR" }, + { "code": "AVOID_USING_ABORT" }, + { "code": "AVOID_USING_ISDATE" }, + { "code": "AVOID_USING_ISDEBUGMODE" }, + { "code": "AVOID_USING_CFINSERT_TAG" }, + { "code": "AVOID_USING_CFUPDATE_TAG" }, + { "code": "ARG_VAR_CONFLICT" }, + { "code": "ARG_HINT_MISSING" }, + { "code": "ARG_HINT_MISSING_SCRIPT" }, + { "code" : "ARGUMENT_INVALID_NAME" }, + { "code" : "ARGUMENT_ALLCAPS_NAME" }, + { "code" : "ARGUMENT_TOO_WORDY" }, + { "code" : "ARGUMENT_IS_TEMPORARY" }, + { "code": "CFQUERYPARAM_REQ" }, + { "code": "COMPARE_INSTEAD_OF_ASSIGN" }, + { "code": "COMPONENT_HINT_MISSING" }, + { "code" : "COMPONENT_INVALID_NAME" }, + { "code" : "COMPONENT_ALLCAPS_NAME" }, + { "code" : "COMPONENT_TOO_SHORT" }, + { "code" : "COMPONENT_TOO_LONG" }, + { "code" : "COMPONENT_TOO_WORDY" }, + { "code" : "COMPONENT_IS_TEMPORARY" }, + { "code" : "COMPONENT_HAS_PREFIX_OR_POSTFIX" }, + { "code": "COMPLEX_BOOLEAN_CHECK" }, + { "code": "EXCESSIVE_ARGUMENTS" }, + { "code": "EXCESSIVE_FUNCTIONS" }, + { "code": "EXPLICIT_BOOLEAN_CHECK" }, + { "code": "FUNCTION_TOO_COMPLEX" }, + { "code": "FUNCTION_HINT_MISSING" }, + { "code": "FILE_SHOULD_START_WITH_LOWERCASE" }, + { "code": "LOCAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "MISSING_VAR" }, + { "code" : "METHOD_INVALID_NAME" }, + { "code" : "METHOD_ALLCAPS_NAME" }, + { "code" : "METHOD_IS_TEMPORARY" }, + { "code": "NESTED_CFOUTPUT" }, + { "code": "NEVER_USE_QUERY_IN_CFM" }, + { "code": "OUTPUT_ATTR" }, + { "code" : "QUERYPARAM_REQ" }, + { "code": "UNUSED_LOCAL_VARIABLE" }, + { "code": "UNUSED_METHOD_ARGUMENT" }, + { "code": "SQL_SELECT_STAR" }, + { "code": "SCOPE_ALLCAPS_NAME" }, + { "code": "VAR_ALLCAPS_NAME" }, + { "code": "VAR_INVALID_NAME" }, + { "code": "VAR_TOO_WORDY" } + ], + "inheritParent": false, + "parameters": { + "TooManyFunctionsChecker.maximum" : 50 + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a2c8081 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# http://editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false +indent_style = tab +indent_size = 4 +tab_width = 4 + +[*.yml] +indent_style = space +indent_size = 2 + +[*.{md,markdown}] +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..c50097f --- /dev/null +++ b/.env.template @@ -0,0 +1,7 @@ +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_USER=root +DB_PASSWORD=mysql +DB_CLASS=com.mysql.cj.jdbc.Driver +DB_BUNDLEVERSION=8.0.19 +DB_BUNDLENAME=com.mysql.cj \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000..6846c75 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.github/CODE_OF_CONDUCT.MD b/.github/CODE_OF_CONDUCT.MD new file mode 100644 index 0000000..12507ab --- /dev/null +++ b/.github/CODE_OF_CONDUCT.MD @@ -0,0 +1,3 @@ +# Code of Conduct + +Please see it in our [Contributing Guidelines](../CONTRIBUTING.md#code-of-conduct). diff --git a/.github/FUNDING.YML b/.github/FUNDING.YML new file mode 100644 index 0000000..7e59d13 --- /dev/null +++ b/.github/FUNDING.YML @@ -0,0 +1 @@ +patreon: ortussolutions diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..300232e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +--- + + + +## What are the steps to reproduce this issue? + +1. … +2. … +3. … + +## What happens? + +… + +## What were you expecting to happen? + +… + +## Any logs, error output, etc? + +… + +## Any other comments? + +… + +## What versions are you using? + +**Operating System:** … +**Package Version:** … diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..c10946f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,18 @@ +--- +name: Feature Request +about: Request a new feature or enhancement +--- + + + +## Summary + + + +## Detailed Description + + + +## Possible Implementation Ideas + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..e8bd9f9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ +# Description + +Please include a summary of the changes and which issue(s) is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +**Please note that all PRs must have tests attached to them** + +IMPORTANT: Please review the [CONTRIBUTING.md](../CONTRIBUTING.md) file for detailed contributing guidelines. + +## Issues + +All PRs must have an accompanied issue. Please make sure you created it and linked it here. + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug Fix +- [ ] Improvement +- [ ] New Feature +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +## Checklist + +- [ ] My code follows the style guidelines of this project [cfformat](../.cfformat.json) +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..f057099 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,3 @@ +# Security Policy + +Please see it in our [Contributing Guidelines](../CONTRIBUTING.md#security-vulnerabilities). diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..3bb8adb --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,3 @@ +# Support & Help + +Please see it in our [Contributing Guidelines](../CONTRIBUTING.md#support-questions). diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..a4ed296 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,30 @@ +name: Pull Requests + +on: + push: + branches-ignore: + - "main" + - "master" + - "development" + - "releases/v*" + pull_request: + branches: + - "releases/v*" + - development + +jobs: + tests: + uses: ./.github/workflows/tests.yml + secrets: inherit + + # Format PR + format_check: + name: Checks Source Code Formatting + runs-on: ubuntu-20.04 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - uses: Ortus-Solutions/commandbox-action@v1.0.2 + with: + cmd: run-script format:check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..35214ae --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,175 @@ +name: Build a Release + +on: + # If you push to master|main this will trigger a stable release + push: + branches: + - master + - main + + # Reusable workflow : Usually called by a `snapshot` workflow + workflow_call: + inputs: + snapshot: + description: 'Is this a snapshot build?' + required: false + default: false + type: boolean + +env: + MODULE_ID: @MODULE_SLUG@ + SNAPSHOT: ${{ inputs.snapshot || false }} + +jobs: + ########################################################################################## + # Build & Publish + ########################################################################################## + build: + name: Build & Publish + runs-on: ubuntu-20.04 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup CommandBox + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + with: + forgeboxAPIKey: ${{ secrets.FORGEBOX_TOKEN }} + + - name: "Setup Environment Variables For Build Process" + id: current_version + run: | + echo "VERSION=`cat box.json | jq '.version' -r`" >> $GITHUB_ENV + box package set version=@build.version@+@build.number@ + # master or snapshot + echo "Github Ref is $GITHUB_REF" + echo "BRANCH=master" >> $GITHUB_ENV + if [ $GITHUB_REF == 'refs/heads/development' ] + then + echo "BRANCH=development" >> $GITHUB_ENV + fi + + - name: Update changelog [unreleased] with latest version + uses: thomaseizinger/keep-a-changelog-new-release@1.3.0 + if: env.SNAPSHOT == 'false' + with: + changelogPath: ./changelog.md + tag: v${{ env.VERSION }} + + - name: Build ${{ env.MODULE_ID }} + run: | + npm install -g markdownlint-cli + markdownlint changelog.md --fix + box install commandbox-docbox + box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ github.run_number }} :branch=${{ env.BRANCH }} + + - name: Commit Changelog To Master + uses: EndBug/add-and-commit@v9.1.4 + if: env.SNAPSHOT == 'false' + with: + author_name: Github Actions + author_email: info@ortussolutions.com + message: 'Finalized changelog for v${{ env.VERSION }}' + add: changelog.md + + - name: Tag Version + uses: rickstaa/action-create-tag@v1.7.2 + if: env.SNAPSHOT == 'false' + with: + tag: "v${{ env.VERSION }}" + force_push_tag: true + message: "Latest Release v${{ env.VERSION }}" + + - name: Upload Build Artifacts + if: success() + uses: actions/upload-artifact@v4 + with: + name: ${{ env.MODULE_ID }} + path: | + .artifacts/**/* + changelog.md + + - name: Upload Binaries to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: "downloads.ortussolutions.com" + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCESS_SECRET }} + SOURCE_DIR: ".artifacts/${{ env.MODULE_ID }}" + DEST_DIR: "ortussolutions/coldbox-modules/${{ env.MODULE_ID }}" + + - name: Upload API Docs to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: "apidocs.ortussolutions.com" + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCESS_SECRET }} + SOURCE_DIR: ".tmp/apidocs" + DEST_DIR: "coldbox-modules/${{ env.MODULE_ID }}/${{ env.VERSION }}" + + - name: Publish To ForgeBox + run: | + cd .tmp/${{ env.MODULE_ID }} + cat box.json + box forgebox publish --force + + - name: Create Github Release + uses: taiki-e/create-gh-release-action@v1.8.0 + continue-on-error: true + if: env.SNAPSHOT == 'false' + with: + title: ${{ env.VERSION }} + changelog: changelog.md + token: ${{ secrets.GITHUB_TOKEN }} + ref: refs/tags/v${{ env.VERSION }} + + ########################################################################################## + # Prep Next Release + ########################################################################################## + prep_next_release: + name: Prep Next Release + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + runs-on: ubuntu-20.04 + needs: [ build ] + steps: + # Checkout development + - name: Checkout Repository + uses: actions/checkout@v4 + with: + ref: development + + - name: Setup CommandBox + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + with: + forgeboxAPIKey: ${{ secrets.FORGEBOX_TOKEN }} + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ env.MODULE_ID }} + path: .tmp + + # Copy the changelog to the development branch + - name: Copy Changelog + run: | + cp .tmp/changelog.md changelog.md + + # Bump to next version + - name: Bump Version + run: | + box bump --minor --!TagVersion + + # Commit it back to development + - name: Commit Version Bump + uses: EndBug/add-and-commit@v9.1.4 + with: + author_name: Github Actions + author_email: info@ortussolutions.com + message: 'Version bump' + add: | + box.json + changelog.md diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml new file mode 100644 index 0000000..98cef2e --- /dev/null +++ b/.github/workflows/snapshot.yml @@ -0,0 +1,48 @@ +name: Build Snapshot + +on: + push: + branches: + - 'development' + +# Unique group name per workflow-branch/tag combo +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ########################################################################################## + # Module Tests + ########################################################################################## + tests: + secrets: inherit + uses: ./.github/workflows/tests.yml + + ########################################################################################## + # Format Source Code + ########################################################################################## + format: + name: Code Auto-Formatting + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + + - name: Auto-format + uses: Ortus-Solutions/commandbox-action@v1.0.2 + with: + cmd: run-script format + + - name: Commit Format Changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Apply cfformat changes + + ########################################################################################## + # Release it + ########################################################################################## + release: + uses: ./.github/workflows/release.yml + needs: [ tests, format ] + secrets: inherit + with: + snapshot: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..bbb8ed5 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,129 @@ +name: Test Suites + +# We are a reusable Workflow only +on: + workflow_call: + secrets: + SLACK_WEBHOOK_URL: + required: false + +jobs: + tests: + name: Tests + runs-on: ubuntu-20.04 + env: + DB_USER: root + DB_PASSWORD: root + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + cfengine: [ "lucee@5", "adobe@2018", "adobe@2021", "adobe@2023" ] + coldboxVersion: [ "^6.0.0", "^7.0.0" ] + experimental: [ false ] + # Here we tests all engines against ColdBox@BE + include: + - coldboxVersion: "be" + cfengine: "lucee@5" + experimental: true + - coldboxVersion: "be" + cfengine: "lucee@6" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2021" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2023" + experimental: true + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + # - name: Setup Database and Fixtures + # run: | + # sudo systemctl start mysql.service + # mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} -e 'CREATE DATABASE mementifier;' + # mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} < test-harness/tests/resources/coolblog.sql + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "11" + + - name: Setup CommandBox CLI + uses: Ortus-Solutions/setup-commandbox@v2.0.1 + + # Not Needed in this module + #- name: Setup Environment For Testing Process + # run: | + # # Setup .env + # touch .env + # # ENV + # printf "DB_HOST=localhost\n" >> .env + # printf "DB_DATABASE=mydatabase\n" >> .env + # printf "DB_DRIVER=MySQL\n" >> .env + # printf "DB_USER=${{ env.DB_USER }}\n" >> .env + # printf "DB_PASSWORD=${{ env.DB_PASSWORD }}\n" >> .env + # printf "DB_CLASS=com.mysql.cj.jdbc.Driver\n" >> .env + # printf "DB_BUNDLEVERSION=8.0.19\n" >> .env + # printf "DB_BUNDLENAME=com.mysql.cj\n" >> .env + + - name: Install Test Harness with ColdBox ${{ matrix.coldboxVersion }} + run: | + box install + cd test-harness + box package set dependencies.coldbox=${{ matrix.coldboxVersion }} + box install + + - name: Start ${{ matrix.cfengine }} Server + run: | + box server start serverConfigFile="server-${{ matrix.cfengine }}.json" --noSaveSettings --debug + curl http://127.0.0.1:60299 + + - name: Run Tests + run: | + mkdir -p test-harness/tests/results + box testbox run --verbose outputFile=test-harness/tests/results/test-results outputFormats=json,antjunit + + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + junit_files: test-harness/tests/results/**/*.xml + check_name: "${{ matrix.cfengine }} ColdBox ${{ matrix.coldboxVersion }} Test Results" + + - name: Upload Test Results to Artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.cfengine }}-${{ matrix.coldboxVersion }} + path: | + test-harness/tests/results/**/* + + - name: Show Server Log On Failures + if: ${{ failure() }} + run: | + box server log serverConfigFile="server-${{ matrix.cfengine }}.json" + + - name: Upload Debug Logs To Artifacts + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: Failure Debugging Info - ${{ matrix.cfengine }} - ${{ matrix.coldboxVersion }} + path: | + .engine/**/logs/* + .engine/**/WEB-INF/cfusion/logs/* + + - name: Slack Notifications + # Only on failures and NOT in pull requests + if: ${{ failure() && !startsWith( 'pull_request', github.event_name ) }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: coding + SLACK_COLOR: ${{ job.status }} # or a specific color like 'green' or '#ff00ff' + SLACK_ICON_EMOJI: ":bell:" + SLACK_MESSAGE: '${{ github.repository }} tests failed :cry:' + SLACK_TITLE: ${{ github.repository }} Tests For ${{ matrix.cfengine }} with ColdBox ${{ matrix.coldboxVersion }} failed + SLACK_USERNAME: CI + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34d1a10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Artifacts and temp folders +.artifacts/** +.tmp/** +.DS_Store + +# Engine + Secrets +.env +.engine/** + +# Dependencies +test-harness/coldbox/** +test-harness/docbox/** +test-harness/testbox/** +test-harness/logs/** +test-harness/modules/** + +# modules +modules/** + +# log files +logs/** diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..21bc843 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,16 @@ +{ + "line-length": false, + "single-h1": false, + "no-hard-tabs" : false, + "fenced-code-language" : false, + "no-bare-urls" : false, + "first-line-h1": false, + "no-multiple-blanks": { + "maximum": 2 + }, + "no-duplicate-header" : { + "siblings_only" : true + }, + "no-duplicate-heading" : false, + "no-inline-html" : false +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2506a17 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "cfml.mappings": [ + { + "logicalPath": "/coldbox", + "directoryPath": "./test-harness/coldbox", + "isPhysicalDirectoryPath": false + }, + { + "logicalPath": "/testbox", + "directoryPath": "./test-harness/testbox", + "isPhysicalDirectoryPath": false + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6092c9d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,33 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Run CommandBox Task", + "type": "shell", + "command": "box task run ${relativeFile}", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Run TestBox Bundle", + "type": "shell", + "command": "box testbox run bundles=${relativeFile} --!recurse", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..46c40a6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,108 @@ +# Contributing Guide + +Hola amigo! I'm really excited that you are interested in contributing to @MODULE_NAME@. Before submitting your contribution, please make sure to take a moment and read through the following guidelines: + +- [Code Of Conduct](#code-of-conduct) +- [Bug Reporting](#bug-reporting) +- [Support Questions](#support-questions) +- [Pull Request Guidelines](#pull-request-guidelines) +- [Security Vulnerabilities](#security-vulnerabilities) +- [Development Setup](#development-setup) +- [Language Compatibility](#language-compatibility) +- [Coding Styles \& Formatting](#coding-styles--formatting) +- [CFC Docs With DocBox](#cfc-docs-with-docbox) +- [Financial Contributions](#financial-contributions) +- [Contributors](#contributors) + +## Code Of Conduct + +This project is open source, and as such, the maintainers give their free time to build and maintain the source code held within. They make the code freely available in the hope that it will be of use to other developers and/or businesses. Please be considerate towards maintainers when raising issues or presenting pull requests. **We all follow the Golden Rule: Do to others as you want them to do to you.** + +- As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. +- Participants will be tolerant of opposing views. +- Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. +- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. +- When interpreting the words and actions of others, participants should always assume good intentions. Emotions cannot be derived from textual representations. +- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + + +## Bug Reporting + +Please make sure also that if you submit a pull request, you link it to the appropriate issue(s). + +If you file a bug report, your issue should contain a title, a clear description of the issue, a way to replicate the issue, and any support files that we might need to replicate your issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix for it. All issues that do not contain a way to replicate will not be addressed. + +## Support Questions + +If you have any questions on usage, professional support or just ideas to bounce off the maintainers, please do not create an issue. Leverage our support channels first. + +- Ortus Community Discourse: https://community.ortussolutions.com +- Box Slack Team: http://boxteam.ortussolutions.com/ +- Professional Support: https://www.ortussolutions.com/services/support + +## Pull Request Guidelines + +- The `(master|main)` branch is just a snapshot of the latest stable release. All development should be done in dedicated branches. Do not submit PRs against the master branch. They will be closed. +- All pull requests should be sent to the `development` branch or the appropriate LTS branch (`releases/v{version}`). +- It's OK to have multiple small commits as you work on the PR - GitHub will automatically squash it before merging. +- Make sure all local tests pass before submitting the merge. +- Please make sure all your pull requests have companion tests. +- Please link the Jira issue in your PR title when sending the final PR + +## Security Vulnerabilities + +If you discover a security vulnerability, please send an email to the Ortus security team at [security@ortussolutions.com](mailto:security@ortussolutions.com?subject=security) and make sure you report it to the `#security` channel in our Box Team Slack Channel. All security vulnerabilities will be promptly addressed. + +## Development Setup + +1. Fork and Star our project. +2. Make sure you have CommandBox installed: https://www.ortussolutions.com/products/commandbox#download +3. Start a CommandBox shell in the root of the project: `box` +4. Install the development dependencies: `run-script install:dependencies` +5. Hack away! Create tests under `/test-harness/specs` or wherever they are set in the project and run the tests! + +## Language Compatibility + +Please make sure your code runs on the following CFML Engines: + +- Lucee 5+ +- Adobe ColdFusion 2018+ + +## Coding Styles & Formatting + +We are big on coding styles and have included a `.cfformat.json` in the root of the project so that you can run the formatting tools and CommandBox scripts: + +```bash +# Format everything +box run-script format + +# Start a watcher, type away, save and auto-format for you +box run-script format:watch +``` + +We recommend that anytime you hack on the core you start the formatter watcher (`box run-script format:watch`). This will monitor your changes and auto-format your code for you. + +You can also see the Ortus Coding Standards you must follow here: https://github.com/Ortus-Solutions/coding-standards. + +## CFC Docs With DocBox + +All CFCs are self-documenting and we leverage [DocBox](https://docbox.ortusbooks.com/) to document the entire software. All functions must be properly documented using the DocBox syntax: https://docbox.ortusbooks.com/getting-started/annotating-your-code + + +## Financial Contributions + +You can support ColdBox and all of our Open Source initiatives at Ortus Solutions by becoming a patreon. You can also get lots of goodies and services depending on the level of contributions. + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/ortussolutions) +- [One-time donations via PayPal](https://www.paypal.com/paypalme/ortussolutions) + +## Contributors + +Thank you to all the people who have already contributed to @MODULE_NAME@! We :heart: :heart: :heart: love you! + + + + + + +Made with [contributors-img](https://contrib.rocks) diff --git a/ModuleConfig.cfc b/ModuleConfig.cfc new file mode 100644 index 0000000..92257e3 --- /dev/null +++ b/ModuleConfig.cfc @@ -0,0 +1,47 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + */ +component { + + // Module Properties + this.title = "@MODULE_NAME@"; + this.author = "Ortus Solutions"; + this.webURL = "https://www.ortussolutions.com"; + this.description = "@MODULE_DESCRIPTION@"; + this.version = "@build.version@+@build.number@"; + + // Model Namespace + this.modelNamespace = "@MODULE_SLUG@"; + + // CF Mapping + this.cfmapping = "@MODULE_SLUG@"; + + // Dependencies + this.dependencies = []; + + /** + * Configure Module + */ + function configure(){ + settings = { + + }; + } + + /** + * Fired when the module is registered and activated. + */ + function onLoad(){ + + } + + /** + * Fired when the module is unregistered and unloaded + */ + function onUnload(){ + + } + +} diff --git a/box.json b/box.json new file mode 100644 index 0000000..47146f3 --- /dev/null +++ b/box.json @@ -0,0 +1,54 @@ +{ + "name" : "@MODULE_NAME@", + "version" : "1.0.0", + "location" : "https://downloads.ortussolutions.com/ortussolutions/coldbox-modules/@MODULE_SLUG@/@build.version@/@MODULE_SLUG@-@build.version@.zip", + "author" : "Ortus Solutions ", + "homepage" : "https://github.com/coldbox-modules/@MODULE_SLUG@", + "documentation" : "https://github.com/coldbox-modules/@MODULE_SLUG@", + "repository" : { "type" : "git", "url" : "https://github.com/coldbox-modules/@MODULE_SLUG@" }, + "bugs" : "https://github.com/coldbox-modules/@MODULE_SLUG@", + "shortDescription" : "Description goes here", + "slug" : "@MODULE_SLUG@", + "type" : "modules", + "keywords":"", + "license" : [ + { "type" : "Apache2", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } + ], + "contributors" : [ + ], + "dependencies" :{ + }, + "devDependencies" :{ + "commandbox-cfformat":"*", + "commandbox-docbox":"*", + "commandbox-dotenv":"*", + "commandbox-cfconfig":"*" + }, + "ignore":[ + "**/.*", + "test-harness", + "/server*.json" + ], + "scripts":{ + "setupTemplate": "task run taskFile=build/SetupTemplate.cfc", + "build:module":"task run taskFile=build/Build.cfc :projectName=`package show slug` :version=`package show version`", + "build:docs":"task run taskFile=build/Build.cfc target=docs :projectName=`package show slug` :version=`package show version`", + "install:dependencies":"install && cd test-harness && install", + "release":"recipe build/release.boxr", + "format":"cfformat run helpers,models,test-harness/tests/,ModuleConfig.cfc --overwrite", + "format:watch":"cfformat watch helpers,models,test-harness/tests/,ModuleConfig.cfc ./.cfformat.json", + "format:check":"cfformat check helpers,models,test-harness/tests/,ModuleConfig.cfc ./.cfformat.json", + "start:lucee" : "server start serverConfigFile=server-lucee@5.json", + "start:2018" : "server start serverConfigFile=server-adobe@2018.json", + "start:2021" : "server start serverConfigFile=server-adobe@2021.json", + "stop:lucee" : "server stop serverConfigFile=server-lucee@5.json", + "stop:2018" : "server stop serverConfigFile=server-adobe@2018.json", + "stop:2021" : "server stop serverConfigFile=server-adobe@2021.json", + "logs:lucee" : "server log serverConfigFile=server-lucee@5.json --follow", + "logs:2018" : "server log serverConfigFile=server-adobe@2018.json --follow", + "logs:2021" : "server log serverConfigFile=server-adobe@2021.json --follow" + }, + "testbox":{ + "runner":"http://localhost:60299/tests/runner.cfm" + } +} diff --git a/build/Build.cfc b/build/Build.cfc new file mode 100644 index 0000000..b15a671 --- /dev/null +++ b/build/Build.cfc @@ -0,0 +1,309 @@ +/** + * Build process for ColdBox Modules + * Adapt to your needs. + */ +component { + + /** + * Constructor + */ + function init(){ + // Setup Pathing + variables.cwd = getCWD().reReplace( "\.$", "" ); + variables.artifactsDir = cwd & "/.artifacts"; + variables.buildDir = cwd & "/.tmp"; + variables.apidDocsDir = variables.buildDir & "/apidocs"; + variables.apiDocsURL = "http://localhost:60299/apidocs/"; + variables.testRunner = "http://localhost:60299/tests/runner.cfm"; + + // Source Excludes Not Added to final binary + variables.excludes = [ + "build", + "node-modules", + "resources", + "test-harness", + "(package|package-lock).json", + "webpack.config.js", + "server-.*\.json", + "docker-compose.yml", + "^\..*" + ]; + + // Cleanup + Init Build Directories + [ + variables.buildDir, + variables.artifactsDir, + variables.apidDocsDir + ].each( function( item ){ + if ( directoryExists( item ) ) { + directoryDelete( item, true ); + } + // Create directories + directoryCreate( item, true, true ); + } ); + + // Create Mappings + fileSystemUtil.createMapping( + "coldbox", + variables.cwd & "test-harness/coldbox" + ); + + return this; + } + + /** + * Run the build process: test, build source, docs, checksums + * + * @projectName The project name used for resources and slugs + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building + */ + function run( + required projectName, + version = "1.0.0", + buildID = createUUID(), + branch = "development" + ){ + // Create project mapping + fileSystemUtil.createMapping( arguments.projectName, variables.cwd ); + + // Build the source + buildSource( argumentCollection = arguments ); + + // Build Docs + arguments.outputDir = variables.buildDir & "/apidocs"; + docs( argumentCollection = arguments ); + + // checksums + buildChecksums(); + + // Finalize Message + print + .line() + .boldMagentaLine( "Build Process is done! Enjoy your build!" ) + .toConsole(); + } + + /** + * Run the test suites + */ + function runTests(){ + // Tests First, if they fail then exit + print.blueLine( "Testing the package, please wait..." ).toConsole(); + + command( "testbox run" ) + .params( + runner = variables.testRunner, + verbose = true, + outputFile = "#variables.cwd#/test-harness/results/test-results", + outputFormats="json,antjunit" + ) + .run(); + + // Check Exit Code? + if ( shell.getExitCode() ) { + return error( "Cannot continue building, tests failed!" ); + } + } + + /** + * Build the source + * + * @projectName The project name used for resources and slugs + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building + */ + function buildSource( + required projectName, + version = "1.0.0", + buildID = createUUID(), + branch = "development" + ){ + // Build Notice ID + print + .line() + .boldMagentaLine( + "Building #arguments.projectName# v#arguments.version#+#arguments.buildID# from #cwd# using the #arguments.branch# branch." + ) + .toConsole(); + + ensureExportDir( argumentCollection = arguments ); + + // Project Build Dir + variables.projectBuildDir = variables.buildDir & "/#projectName#"; + directoryCreate( + variables.projectBuildDir, + true, + true + ); + + // Copy source + print.blueLine( "Copying source to build folder..." ).toConsole(); + copy( + variables.cwd, + variables.projectBuildDir + ); + + // Create build ID + fileWrite( + "#variables.projectBuildDir#/#projectName#-#version#+#buildID#", + "Built with love on #dateTimeFormat( now(), "full" )#" + ); + + // Updating Placeholders + print.greenLine( "Updating version identifier to #arguments.version#" ).toConsole(); + command( "tokenReplace" ) + .params( + path = "/#variables.projectBuildDir#/**", + token = "@build.version@", + replacement = arguments.version + ) + .run(); + + print.greenLine( "Updating build identifier to #arguments.buildID#" ).toConsole(); + command( "tokenReplace" ) + .params( + path = "/#variables.projectBuildDir#/**", + token = ( arguments.branch == "master" ? "@build.number@" : "+@build.number@" ), + replacement = ( arguments.branch == "master" ? arguments.buildID : "-snapshot" ) + ) + .run(); + + // zip up source + var destination = "#variables.exportsDir#/#projectName#-#version#.zip"; + print.greenLine( "Zipping code to #destination#" ).toConsole(); + cfzip( + action = "zip", + file = "#destination#", + source = "#variables.projectBuildDir#", + overwrite = true, + recurse = true + ); + + // Copy box.json for convenience + fileCopy( + "#variables.projectBuildDir#/box.json", + variables.exportsDir + ); + } + + /** + * Produce the API Docs + */ + function docs( + required projectName, + version = "1.0.0", + outputDir = ".tmp/apidocs" + ){ + ensureExportDir( argumentCollection = arguments ); + + // Create project mapping + fileSystemUtil.createMapping( arguments.projectName, variables.cwd ); + // Generate Docs + print.greenLine( "Generating API Docs, please wait..." ).toConsole(); + + command( "docbox generate" ) + .params( + "source" = "models", + "mapping" = "models", + "strategy-projectTitle" = "#arguments.projectName# v#arguments.version#", + "strategy-outputDir" = arguments.outputDir + ) + .run(); + + print.greenLine( "API Docs produced at #arguments.outputDir#" ).toConsole(); + + var destination = "#variables.exportsDir#/#projectName#-docs-#version#.zip"; + print.greenLine( "Zipping apidocs to #destination#" ).toConsole(); + cfzip( + action = "zip", + file = "#destination#", + source = "#arguments.outputDir#", + overwrite = true, + recurse = true + ); + } + + /********************************************* PRIVATE HELPERS *********************************************/ + + /** + * Build Checksums + */ + private function buildChecksums(){ + print.greenLine( "Building checksums" ).toConsole(); + command( "checksum" ) + .params( + path = "#variables.exportsDir#/*.zip", + algorithm = "SHA-512", + extension = "sha512", + write = true + ) + .run(); + command( "checksum" ) + .params( + path = "#variables.exportsDir#/*.zip", + algorithm = "md5", + extension = "md5", + write = true + ) + .run(); + } + + /** + * DirectoryCopy is broken in lucee + */ + private function copy( src, target, recurse = true ){ + // process paths with excludes + directoryList( + src, + false, + "path", + function( path ){ + var isExcluded = false; + variables.excludes.each( function( item ){ + if ( path.replaceNoCase( variables.cwd, "", "all" ).reFindNoCase( item ) ) { + isExcluded = true; + } + } ); + return !isExcluded; + } + ).each( function( item ){ + // Copy to target + if ( fileExists( item ) ) { + print.blueLine( "Copying #item#" ).toConsole(); + fileCopy( item, target ); + } else { + print.greenLine( "Copying directory #item#" ).toConsole(); + directoryCopy( + item, + target & "/" & item.replace( src, "" ), + true + ); + } + } ); + } + + /** + * Gets the last Exit code to be used + **/ + private function getExitCode(){ + return ( createObject( "java", "java.lang.System" ).getProperty( "cfml.cli.exitCode" ) ?: 0 ); + } + + /** + * Ensure the export directory exists at artifacts/NAME/VERSION/ + */ + private function ensureExportDir( + required projectName, + version = "1.0.0" + ){ + if ( structKeyExists( variables, "exportsDir" ) && directoryExists( variables.exportsDir ) ){ + return; + } + // Prepare exports directory + variables.exportsDir = variables.artifactsDir & "/#projectName#/#arguments.version#"; + directoryCreate( variables.exportsDir, true, true ); + } +} diff --git a/build/SetupTemplate.cfc b/build/SetupTemplate.cfc new file mode 100644 index 0000000..ca18f24 --- /dev/null +++ b/build/SetupTemplate.cfc @@ -0,0 +1,70 @@ +/** + * Setup the Module Template according to your needs + */ +component { + + /** + * Constructor + */ + function init(){ + // Setup Pathing + variables.cwd = getCWD().reReplace( "\.$", "" ); + return this; + } + + /** + * Setup the module template + */ + function run(){ + + // remove old .git + //directoryDelete( variables.cwd & ".git", true ); + + // Create new git repo + //command( "!git init" ).run(); + + var moduleName = ask( "What is the human readable name of your module?" ); + if( !len( moduleName ) ){ + error( "Module Name is required" ); + } + var moduleSlug = ask( "What is the slug for your module?" ); + if( !len( moduleSlug ) ){ + error( "Module Slug is required" ); + } + var moduleDescription = ask( "Short description of your module?" ); + if( !len( moduleDescription ) ){ + error( "Module Description is required" ); + } + + command( "tokenReplace" ) + .params( + path = "/#variables.cwd#/**", + token = "@MODULE_NAME@", + replacement = moduleName + ) + .run(); + + command( "tokenReplace" ) + .params( + path = "/#variables.cwd#/**", + token = "@MODULE_SLUG@", + replacement = moduleSlug + ) + .run(); + + command( "tokenReplace" ) + .params( + path = "/#variables.cwd#/**", + token = "@MODULE_DESCRIPTION@", + replacement = moduleDescription + ) + .run(); + + // Finalize Message + print + .line() + .boldMagentaLine( "Your module template is now ready for development! Just add the github origin, commit some code and Go rock it!" ) + .toConsole(); + } + +} diff --git a/build/release.boxr b/build/release.boxr new file mode 100755 index 0000000..a63f2cc --- /dev/null +++ b/build/release.boxr @@ -0,0 +1,14 @@ +# This recipe signifies a new release of the module by doing merges and bumps accordingly + +# Check out master and update it locally +!git checkout -f master +!git pull origin master + +# Merge development into it for release +!git merge --no-ff development + +# Push all branches back out to github +!git push origin --all + +# Check development again +!git checkout -f development diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..46f833a --- /dev/null +++ b/changelog.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +---- + +## [Unreleased] + +## [1.0.0] => 2021-JAN-01 + +* First iteration of this module diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..152ac4e --- /dev/null +++ b/readme.md @@ -0,0 +1,101 @@ +

+ +
+ + + +

+ +

+ Copyright Since 2005 ColdBox Platform by Luis Majano and Ortus Solutions, Corp +
+ www.coldbox.org | + www.ortussolutions.com +

+ +---- + +# Ortus ColdBox Module Template + +This template can be used to create Ortus based ColdBox Modules. To use, just click the `Use this Template` button in the github repository: https://github.com/coldbox-modules/module-template and run the setup task from where you cloned it. + +```bash +box task run taskFile=build/SetupTemplate +``` + +The `SetupTemplate` task will ask you for your module name, id and description and configure the template for you! Enjoy! + +## Directory Structure + +The root of the module is the root of the repository. Add all the necessary files your module will need. + +* `.github/workflows` - These are the github actions to test and build the module via CI +* `build` - This is the CommandBox task that builds the project. Only modify if needed. Most modules will never modify it. (Modify if needed) +* `test-harness` - This is a ColdBox testing application, where you will add your testing files, specs etc. +* `.cfformat.json` - A CFFormat using the Ortus Standards +* `.cflintrc` - A CFLint configuration file according to Ortus Standards +* `.editorconfig` - Smooth consistency between editors +* `.gitattributes` - Git attributes +* `.gitignore` - Basic ignores. Modify as needed. +* `.markdownlint.json` - A linting file for markdown docs +* `box.json` - The box.json for YOUR module. Modify as needed. +* `changelog.md` - A nice changelog tracking file +* `ModuleConfig.cfc` - Your module's configuration. Modify as needed. +* `readme.md` - Your module's readme. Modify as needed. +* `server-xx@x.json` - A set of json files to configure the major engines your modules supports. + +## Test Harness + +The test harness is created to bootstrap your working module into the application `afterAspectsLoad`. This is done in the `config/ColdBox.cfc`. It includes some key features: + +* `config` - Modify as needed +* `tests` - All your testing specs should go here. Please notice the commented out ORM fixtures. Enable them if your module requires ORM +* `.cfconfig.json` - A prepared cfconfig json file so your engine data is consistent. Modify as needed. +* `.env.sample` - An environment property file sample. Copy and create a `.env` if your app requires it. + + +## API Docs + +The build task will take care of building API Docs using DocBox for you but **ONLY** for the `models` folder in your module. If you want to document more then make sure you modify the `build/Build.cfc` task. + +## Github Actions Automation + +The github actions will clone, test, package, deploy your module to ForgeBox and the Ortus S3 accounts for API Docs and Artifacts. So please make sure the following environment variables are set in your repository. ** Please note that most of them are already defined at the org level ** + +* `FORGEBOX_TOKEN` - The Ortus ForgeBox API Token +* `AWS_ACCESS_KEY` - The travis user S3 account +* `AWS_ACCESS_SECRET` - The travis secret S3 + +> Please contact the admins in the `#infrastructure` channel for these credentials if needed + +## Welcome to ColdBox + +ColdBox *Hierarchical* MVC is the de-facto enterprise-level [HMVC](https://en.wikipedia.org/wiki/Hierarchical_model%E2%80%93view%E2%80%93controller) framework for ColdFusion (CFML) developers. It's professionally backed, conventions-based, modular, highly extensible, and productive. Getting started with ColdBox is quick and painless. ColdBox takes the pain out of development by giving you a standardized methodology for modern ColdFusion (CFML) development with features such as: + +* [Conventions instead of configuration](https://coldbox.ortusbooks.com/getting-started/conventions) +* [Modern URL routing](https://coldbox.ortusbooks.com/the-basics/routing) +* [RESTFul APIs](https://coldbox.ortusbooks.com/the-basics/event-handlers/rendering-data) +* [A hierarchical approach to MVC using ColdBox Modules](https://coldbox.ortusbooks.com/hmvc/modules) +* [Event-driven programming](https://coldbox.ortusbooks.com/digging-deeper/interceptors) +* [Async and Parallel programming constructs](https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming) +* [Integration & Unit Testing](https://coldbox.ortusbooks.com/testing/testing-coldbox-applications) +* [Included dependency injection](https://wirebox.ortusbooks.com) +* [Caching engine and API](https://cachebox.ortusbooks.com) +* [Logging engine](https://logbox.ortusbooks.com) +* [An extensive eco-system](https://forgebox.io) +* Much More + +## Learning ColdBox + +ColdBox is the defacto standard for building modern ColdFusion (CFML) applications. It has the most extensive [documentation](https://coldbox.ortusbooks.com) of all modern web application frameworks. + + +If you don't like reading so much, then you can try our video learning platform: [CFCasts (www.cfcasts.com)](https://www.cfcasts.com) + +## Ortus Sponsors + +ColdBox is a professional open-source project and it is completely funded by the [community](https://patreon.com/ortussolutions) and [Ortus Solutions, Corp](https://www.ortussolutions.com). Ortus Patreons get many benefits like a cfcasts account, a FORGEBOX Pro account and so much more. If you are interested in becoming a sponsor, please visit our patronage page: [https://patreon.com/ortussolutions](https://patreon.com/ortussolutions) + +### THE DAILY BREAD + + > "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12 diff --git a/server-adobe@2018.json b/server-adobe@2018.json new file mode 100644 index 0000000..8c13686 --- /dev/null +++ b/server-adobe@2018.json @@ -0,0 +1,23 @@ +{ + "name":"@MODULE_NAME@-adobe@2018", + "app":{ + "serverHomeDirectory":".engine/adobe2018", + "cfengine":"adobe@2018" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + } +} diff --git a/server-adobe@2021.json b/server-adobe@2021.json new file mode 100644 index 0000000..d0630be --- /dev/null +++ b/server-adobe@2021.json @@ -0,0 +1,29 @@ +{ + "name":"@MODULE_NAME@-adobe@2021", + "app":{ + "serverHomeDirectory":".engine/adobe2021", + "cfengine":"adobe@2021" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "jvm":{ + "heapSize":"1024" + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + }, + "scripts" : { + "onServerInstall":"cfpm install zip,debugger" + } +} diff --git a/server-adobe@2023.json b/server-adobe@2023.json new file mode 100644 index 0000000..ef303ae --- /dev/null +++ b/server-adobe@2023.json @@ -0,0 +1,29 @@ +{ + "name":"@MODULE_NAME@-adobe@2023", + "app":{ + "serverHomeDirectory":".engine/adobe2023", + "cfengine":"adobe@2023" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "jvm":{ + "heapSize":"1024" + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + }, + "scripts" : { + "onServerInstall":"cfpm install zip,debugger" + } +} diff --git a/server-lucee@5.json b/server-lucee@5.json new file mode 100644 index 0000000..6423ca7 --- /dev/null +++ b/server-lucee@5.json @@ -0,0 +1,23 @@ +{ + "name":"@MODULE_NAME@-lucee@5", + "app":{ + "serverHomeDirectory":".engine/lucee5", + "cfengine":"lucee@5" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + } +} diff --git a/server-lucee@6.json b/server-lucee@6.json new file mode 100644 index 0000000..c3b490e --- /dev/null +++ b/server-lucee@6.json @@ -0,0 +1,23 @@ +{ + "name":"@MODULE_NAME@-lucee@6", + "app":{ + "serverHomeDirectory":".engine/lucee6", + "cfengine":"lucee@6" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + } +} diff --git a/test-harness/.cflintrc b/test-harness/.cflintrc new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test-harness/.cflintrc @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test-harness/Application.cfc b/test-harness/Application.cfc new file mode 100644 index 0000000..0fcffde --- /dev/null +++ b/test-harness/Application.cfc @@ -0,0 +1,103 @@ +/** +******************************************************************************** +Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +www.ortussolutions.com +******************************************************************************** +*/ +component{ + + // UPDATE THE NAME OF THE MODULE IN TESTING BELOW + request.MODULE_NAME = "@MODULE_NAME@"; + + // Application properties + this.name = hash( getCurrentTemplatePath() ); + this.sessionManagement = true; + this.sessionTimeout = createTimeSpan(0,0,15,0); + this.setClientCookies = true; + + /************************************** + LUCEE Specific Settings + **************************************/ + // buffer the output of a tag/function body to output in case of a exception + this.bufferOutput = true; + // Activate Gzip Compression + this.compression = false; + // Turn on/off white space managemetn + this.whiteSpaceManagement = "smart"; + // Turn on/off remote cfc content whitespace + this.suppressRemoteComponentContent = false; + + // COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP + COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); + // The web server mapping to this application. Used for remote purposes or static purposes + COLDBOX_APP_MAPPING = ""; + // COLDBOX PROPERTIES + COLDBOX_CONFIG_FILE = ""; + // COLDBOX APPLICATION KEY OVERRIDE + COLDBOX_APP_KEY = ""; + + // Mappings + this.mappings[ "/root" ] = COLDBOX_APP_ROOT_PATH; + + // Map back to its root + moduleRootPath = REReplaceNoCase( this.mappings[ "/root" ], "#request.MODULE_NAME#(\\|/)test-harness(\\|/)", "" ); + modulePath = REReplaceNoCase( this.mappings[ "/root" ], "test-harness(\\|/)", "" ); + + // Module Root + Path Mappings + this.mappings[ "/moduleroot" ] = moduleRootPath; + this.mappings[ "/#request.MODULE_NAME#" ] = modulePath; + + // ORM definitions: ENABLE IF NEEDED + //this.datasource = "coolblog"; + //this.ormEnabled = "true"; + /** + this.ormSettings = { + cfclocation = [ "models" ], + logSQL = true, + dbcreate = "update", + secondarycacheenabled = false, + cacheProvider = "ehcache", + flushAtRequestEnd = false, + eventhandling = true, + eventHandler = "cborm.models.EventHandler", + skipcfcWithError = true + }; + **/ + + // application start + public boolean function onApplicationStart(){ + application.cbBootstrap = new coldbox.system.Bootstrap( COLDBOX_CONFIG_FILE, COLDBOX_APP_ROOT_PATH, COLDBOX_APP_KEY, COLDBOX_APP_MAPPING ); + application.cbBootstrap.loadColdbox(); + return true; + } + + // request start + public boolean function onRequestStart(String targetPage){ + + if( url.keyExists( "fwreinit" ) ){ + if( server.keyExists( "lucee" ) ){ + pagePoolClear(); + } + // ORM reload: ENABLE IF NEEDED + // ormReload(); + } + + // Process ColdBox Request + application.cbBootstrap.onRequestStart( arguments.targetPage ); + + return true; + } + + public void function onSessionStart(){ + application.cbBootStrap.onSessionStart(); + } + + public void function onSessionEnd( struct sessionScope, struct appScope ){ + arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection=arguments ); + } + + public boolean function onMissingTemplate( template ){ + return application.cbBootstrap.onMissingTemplate( argumentCollection=arguments ); + } + +} diff --git a/test-harness/box.json b/test-harness/box.json new file mode 100644 index 0000000..e8f47b1 --- /dev/null +++ b/test-harness/box.json @@ -0,0 +1,20 @@ +{ + "name":"Tester", + "version":"0.0.0", + "slug":"tester", + "private":true, + "description":"", + "dependencies":{ + "coldbox":"^6.0.0" + }, + "devDependencies":{ + "testbox":"*" + }, + "installPaths":{ + "coldbox":"coldbox", + "testbox":"testbox" + }, + "testbox":{ + "runner":"http://localhost:60299/tests/runner.cfm" + } +} diff --git a/test-harness/config/Application.cfc b/test-harness/config/Application.cfc new file mode 100644 index 0000000..23c5ad0 --- /dev/null +++ b/test-harness/config/Application.cfc @@ -0,0 +1,7 @@ +/** +* This is a protection Application cfm for the config file. You do not +* need to modify this file +*/ +component{ + abort; +} \ No newline at end of file diff --git a/test-harness/config/Coldbox.cfc b/test-harness/config/Coldbox.cfc new file mode 100644 index 0000000..d35b065 --- /dev/null +++ b/test-harness/config/Coldbox.cfc @@ -0,0 +1,87 @@ +component{ + + // Configure ColdBox Application + function configure(){ + + // coldbox directives + coldbox = { + //Application Setup + appName = "Module Tester", + + //Development Settings + reinitPassword = "", + handlersIndexAutoReload = true, + modulesExternalLocation = [], + + //Implicit Events + defaultEvent = "", + requestStartHandler = "", + requestEndHandler = "", + applicationStartHandler = "", + applicationEndHandler = "", + sessionStartHandler = "", + sessionEndHandler = "", + missingTemplateHandler = "", + + //Error/Exception Handling + exceptionHandler = "", + onInvalidEvent = "", + customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm", + + //Application Aspects + handlerCaching = false, + eventCaching = false + }; + + // environment settings, create a detectEnvironment() method to detect it yourself. + // create a function with the name of the environment so it can be executed if that environment is detected + // the value of the environment is a list of regex patterns to match the cgi.http_host. + environments = { + development = "localhost,127\.0\.0\.1" + }; + + // Module Directives + modules = { + // An array of modules names to load, empty means all of them + include = [], + // An array of modules names to NOT load, empty means none + exclude = [] + }; + + //Register interceptors as an array, we need order + interceptors = [ + ]; + + //LogBox DSL + logBox = { + // Define Appenders + appenders = { + myConsole : { class : "ConsoleAppender" }, + files : { + class="RollingFileAppender", + properties = { + filename = "tester", filePath="/#appMapping#/logs" + } + } + }, + // Root Logger + root = { levelmax="DEBUG", appenders="*" }, + // Implicit Level Categories + info = [ "coldbox.system" ] + }; + + } + + /** + * Load the Module you are testing + */ + function afterAspectsLoad( event, interceptData, rc, prc ){ + + controller.getModuleService() + .registerAndActivateModule( + moduleName = request.MODULE_NAME, + invocationPath = "moduleroot" + ); + } + +} diff --git a/test-harness/config/Router.cfc b/test-harness/config/Router.cfc new file mode 100755 index 0000000..81aefde --- /dev/null +++ b/test-harness/config/Router.cfc @@ -0,0 +1,9 @@ +component{ + + function configure(){ + setFullRewrites( true ); + + route( ":handler/:action?" ).end(); + } + +} \ No newline at end of file diff --git a/test-harness/config/WireBox.cfc b/test-harness/config/WireBox.cfc new file mode 100644 index 0000000..693565a --- /dev/null +++ b/test-harness/config/WireBox.cfc @@ -0,0 +1,46 @@ +component extends="coldbox.system.ioc.config.Binder"{ + + /** + * Configure WireBox, that's it! + */ + function configure(){ + + // The WireBox configuration structure DSL + wireBox = { + // Scope registration, automatically register a wirebox injector instance on any CF scope + // By default it registeres itself on application scope + scopeRegistration = { + enabled = true, + scope = "application", // server, cluster, session, application + key = "wireBox" + }, + + // DSL Namespace registrations + customDSL = { + // namespace = "mapping name" + }, + + // Custom Storage Scopes + customScopes = { + // annotationName = "mapping name" + }, + + // Package scan locations + scanLocations = [], + + // Stop Recursions + stopRecursions = [], + + // Parent Injector to assign to the configured injector, this must be an object reference + parentInjector = "", + + // Register all event listeners here, they are created in the specified order + listeners = [ + // { class="", name="", properties={} } + ] + }; + + // Map Bindings below + } + +} \ No newline at end of file diff --git a/test-harness/handlers/Main.cfc b/test-harness/handlers/Main.cfc new file mode 100644 index 0000000..f049324 --- /dev/null +++ b/test-harness/handlers/Main.cfc @@ -0,0 +1,11 @@ +/** +* My Event Handler Hint +*/ +component{ + + // Index + any function index( event,rc, prc ){ + event.setView( "main/index" ); + } + +} \ No newline at end of file diff --git a/test-harness/index.cfm b/test-harness/index.cfm new file mode 100644 index 0000000..7331009 --- /dev/null +++ b/test-harness/index.cfm @@ -0,0 +1,9 @@ + + + diff --git a/test-harness/layouts/Main.cfm b/test-harness/layouts/Main.cfm new file mode 100644 index 0000000..b50f9ab --- /dev/null +++ b/test-harness/layouts/Main.cfm @@ -0,0 +1,6 @@ + +

Module Tester

+
+ #view()# +
+
diff --git a/test-harness/tests/Application.cfc b/test-harness/tests/Application.cfc new file mode 100644 index 0000000..9da19bf --- /dev/null +++ b/test-harness/tests/Application.cfc @@ -0,0 +1,85 @@ +/** +* Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +* www.ortussolutions.com +* --- +*/ +component{ + + // The name of the module used in cfmappings ,etc + request.MODULE_NAME = "@MODULE_NAME@"; + // The directory name of the module on disk. Usually, it's the same as the module name + request.MODULE_PATH = "@MODULE_NAME@"; + + // APPLICATION CFC PROPERTIES + this.name = "#request.MODULE_NAME# Testing Suite"; + this.sessionManagement = true; + this.sessionTimeout = createTimeSpan( 0, 0, 15, 0 ); + this.applicationTimeout = createTimeSpan( 0, 0, 15, 0 ); + this.setClientCookies = true; + // Turn on/off white space management + this.whiteSpaceManagement = "smart"; + this.enableNullSupport = shouldEnableFullNullSupport(); + + // Create testing mapping + this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); + + // The application root + rootPath = REReplaceNoCase( this.mappings[ "/tests" ], "tests(\\|/)", "" ); + this.mappings[ "/root" ] = rootPath; + + // The module root path + moduleRootPath = REReplaceNoCase( rootPath, "#request.MODULE_PATH#(\\|/)test-harness(\\|/)", "" ); + this.mappings[ "/moduleroot" ] = moduleRootPath; + this.mappings[ "/#request.MODULE_NAME#" ] = moduleRootPath & "#request.MODULE_PATH#"; + + // ORM Definitions + /** + this.datasource = "coolblog"; + this.ormEnabled = "true"; + this.ormSettings = { + cfclocation = [ "/root/models" ], + logSQL = true, + dbcreate = "update", + secondarycacheenabled = false, + cacheProvider = "ehcache", + flushAtRequestEnd = false, + eventhandling = true, + eventHandler = "cborm.models.EventHandler", + skipcfcWithError = false + }; + **/ + + function onRequestStart( required targetPage ){ + + // Set a high timeout for long running tests + setting requestTimeout="9999"; + // New ColdBox Virtual Application Starter + request.coldBoxVirtualApp = new coldbox.system.testing.VirtualApp( appMapping = "/root" ); + + // If hitting the runner or specs, prep our virtual app + if ( getBaseTemplatePath().replace( expandPath( "/tests" ), "" ).reFindNoCase( "(runner|specs)" ) ) { + request.coldBoxVirtualApp.startup(); + } + + // ORM Reload for fresh results + if( structKeyExists( url, "fwreinit" ) ){ + if( structKeyExists( server, "lucee" ) ){ + pagePoolClear(); + } + // ormReload(); + request.coldBoxVirtualApp.restart(); + } + + return true; + } + + public void function onRequestEnd( required targetPage ) { + request.coldBoxVirtualApp.shutdown(); + } + + private boolean function shouldEnableFullNullSupport() { + var system = createObject( "java", "java.lang.System" ); + var value = system.getEnv( "FULL_NULL" ); + return isNull( value ) ? false : !!value; + } +} diff --git a/test-harness/tests/index.cfm b/test-harness/tests/index.cfm new file mode 100644 index 0000000..8ae931e --- /dev/null +++ b/test-harness/tests/index.cfm @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #testbox.init( directory=rootMapping & url.path ).run()# + +

Invalid incoming directory: #rootMapping & url.path#

+
+ + +
+ + + + + + + + + + + + + + + + + + + TestBox Browser + + + + + + + + + + + + + + +
+
+
+ +
+ v#testbox.getVersion()# +
+ +
+
+
+
+
+ +

TestBox Test Browser:

+

+ Below is a listing of the files and folders starting from your root #rootPath#. You can click on individual tests in order to execute them + or click on the Run All button on your left and it will execute a directory runner from the visible folder. +

+ +
+ Contents: #executePath# + +

+
+ + + + + + + + #qResults.name#
+ + target="_blank"
>#qResults.name#
+ + target="_blank">#qResults.name#
+ + #qResults.name#
+ + +
+
+
+
+
+
+ + + +
diff --git a/test-harness/tests/resources/coolblog.sql b/test-harness/tests/resources/coolblog.sql new file mode 100644 index 0000000..d1af264 --- /dev/null +++ b/test-harness/tests/resources/coolblog.sql @@ -0,0 +1,473 @@ +# ************************************************************ +# Sequel Pro SQL dump +# Version 4529 +# +# http://www.sequelpro.com/ +# https://github.com/sequelpro/sequelpro +# +# Host: Localhost (MySQL 5.6.21) +# Database: coolblog +# Generation Time: 2016-02-27 23:03:57 +0000 +# ************************************************************ + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + + +# Dump of table blogEntries +# ------------------------------------------------------------ +USE `coolblog`; + +DROP TABLE IF EXISTS `blogEntries`; + +CREATE TABLE `blogEntries` ( + `blogEntriesID` int(11) NOT NULL AUTO_INCREMENT, + `blogEntriesLink` longtext NOT NULL, + `blogEntriesTitle` longtext NOT NULL, + `blogEntriesDescription` longtext NOT NULL, + `blogEntriesDatePosted` datetime NOT NULL, + `blogEntriesdateUpdated` datetime NOT NULL, + `blogEntriesIsActive` bit(1) NOT NULL, + `blogsID` int(11) DEFAULT NULL, + PRIMARY KEY (`blogEntriesID`), + KEY `FK2828728E45296FD` (`blogsID`), + CONSTRAINT `FK2828728E45296FD` FOREIGN KEY (`blogsID`) REFERENCES `blogs` (`blogsID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `blogEntries` WRITE; +/*!40000 ALTER TABLE `blogEntries` DISABLE KEYS */; + +INSERT INTO `blogEntries` (`blogEntriesID`, `blogEntriesLink`, `blogEntriesTitle`, `blogEntriesDescription`, `blogEntriesDatePosted`, `blogEntriesdateUpdated`, `blogEntriesIsActive`, `blogsID`) +VALUES + (1,'http://blog.coldbox.org/post.cfm/coldbox-wiki-docs-skins-shared','ColdBox Wiki Docs Skins Shared','Since we love collaboration and giving back to the community, we have just opened our Wiki Docs Skins github repository so you can check out how we build out our wiki docs skins for CodexWiki and hopefully you guys can send us your skins and we can use them on the wiki docs site :)','2011-04-06 11:13:52','2011-04-06 11:13:52',b'1',1), + (2,'http://blog.coldbox.org/post.cfm/new-coldbox-wiki-docs','New ColdBox Wiki Docs','We have been wanting to update all our sites for a long time and the docs where first. Yesterday we updated our codex skins for the coldbox wiki docs and also started our documentation revisions and updates. You will see that it is now much much better organized and our new quick index feature enables you to get to content even faster. Hopefully in the coming weeks we will have all our documentation updated and running. Thank you for your support and feedback.','2011-04-06 10:57:17','2011-04-06 10:57:17',b'1',1), + (3,'http://blog.coldbox.org/post.cfm/modules-contest-ends-this-friday','Modules Contest Ends This Friday','Just a quick reminder that our Modules Contest ends this Friday! So get to it, build some apps! Modules Contest URL: http://blog.coldbox.org/post.cfm/coldbox-modules-contest-extended','2011-04-04 11:22:19','2011-04-04 11:22:19',b'1',1), + (4,'http://blog.coldbox.org/post.cfm/coldbox-connection-recording-coldbox-3-0-0','ColdBox Connection Recording: ColdBox 3.0.0','Thanks for attending our 3rd ColdBox Connection webinar today!  This webinar focused on ColdBox 3.0.0 release and goodies.  Here is the recording for the show!','2011-03-30 15:42:16','2011-03-30 15:42:16',b'1',1), + (5,'http://blog.coldbox.org/post.cfm/coldbox-platform-3-0-0-released','ColdBox Platform 3.0.0 Released','\n \n \nI am so happy to finally announce ColdBox Platform 3.0.0 today on March 3.0, 2011. It has been over a year of research, testing, development, coding, long long nights, 1 beautiful baby girl, lots of headaches, lots of smiles, inspiration, blessings, new contributors, new team members, new company, new hopes, and ambitions. Overall, what an incredible year for ColdFusion and ColdBox development. I can finally say that this release has been the most ambitious release and project I have tackled in my entire professional life. I am so happy of the results and its incredible community response and involvement. So thank you so much Team ColdBox and all the community for the support and long hours of testing, ideas and development.\nColdBox 3 has been on a journey of 6 defined milestones and 2 release candidates in a spawn of over a year of development. Our vision was revamping the engine into discrete and isolated parts:\n\nCore\nLogBox : Enterprise Logging Library\nWireBox : Enterprise Dependency Injection and AOP framework\nCacheBox : Enterprise Caching Engine & Cache Aggregator\nMockBox : Mocking/Stubbing Framework\n\nAll of these parts are now standalone and can be used with any ColdFusion application or ColdFusion framework. We believe we build great tools and would like everybody to have access to them even though they might not even use ColdBox MVC. Apart from the incredible amount of enhancements, we also ventured into several incredible new features:\n\nWhat\'s New\nColdBox Modules : Bringing Modular Architecture to ANY ColdBox application\nProgrammatic configuration, no more XML\nIncredible caching enhancements and integrations\nExtensible and enterprise dependency injection\nAspect oriented programming\nIntegration testing, mocking, stubbing and incredible amount of tools for testing and verification\nCustomizable Flash RAM and future web flows\nColdFusion ORM and Hibernate Services\nRESTful web services enhancement and easy creations\nTons more\n\n \nThe What\'s New page can say it all! An incredible more than 700 issue tickets closed and ColdBox 3.1 is already in full planning phases. So apart from all this work culminating, we can also say we have transitioned into a complete professional open source software offering an incredible amount of professional services and backup to any enterprise or company running ColdBox or any of our supporting products (Relax, CodexWiki, ForumMan, DataBoss, Messaging, ...):\n\nSupport & Mentoring Plans\nArchitecture & Design\nOver 4 professional training courses\nServer Setup, Tuning and Optimizations\nCustom Consulting and','2011-03-29 23:30:18','2011-03-29 23:30:18',b'1',1), + (6,'http://blog.coldbox.org/post.cfm/cachebox-1-2-released','CacheBox 1.2 Released','\n \n In the spirit of more releases, here is: CacheBox 1.2.0.  CacheBox is an enterprise caching engine, aggregator and API for ColdFusion applications. It is part of the ColdBox 3.0.0 Platform but it can also function on its own as a standalone framework and use it in any ColdFusion application and in any ColdFusion framework. \nThe milestone page for this release can be found in our Assembla Code Tracker. Here is a synopsis of the tickets closed:\n \n\n \n\n1179 new cachebox store: BlackholeStore used for optimization and testing\n1180 cf store does not use createTimeSpan to create minute timespans for puts\n1181 railo store does not use createTimeSpan to create minute timespans for puts\n1182 updates to make it coldbox 3.0 compatible\n1192 store locking mechanisms updated to improve locking and concurrency\n\nSo have fun playing with our new CacheBox release:\n\nDownload\nCheatsheet\nSource Code\nDocumentation\n\n ','2011-03-29 23:26:09','2011-03-29 23:26:09',b'1',1), + (7,'http://blog.coldbox.org/post.cfm/wirebox-1-1-1-released','WireBox 1.1.1 Released!','I am happy to announce WireBox 1.1.1 to the ColdFusion community. This release sports 3 critical fixes that will make your WireBox injectors run smoother and happier, especially for those doing java integration, this will help you some more.\n\n\nDownload\nCheatsheet\nSource Code\nDocumentation\nOur primer: Getting Jiggy Wit It!\n\n Issues Fixed\n\n1184 changed way providers accessed scoped injectors via scope registration structure instead of injector references to avoid memory leaks\n 1188 updated the java builder to ignore empty init arguments.\n 1189 updated the java builder to do noInit() as it was ignoring it\n','2011-03-29 23:20:32','2011-03-29 23:20:32',b'1',1), + (8,'http://blog.coldbox.org/post.cfm/module-lifecycles-explained','Module Lifecycles Explained','In this short entry I just wanted to lay out a few new diagrams that explain the lifecycle of ColdBox modules.  As always, all our documentation reflects these changes as well.  This might help some of you developers getting ready to win that ColdBox Modules contest and get some cash and beer!\n\nModule Service\nThe beauty of ColdBox Modules is that you have an internal module service that you can tap to in order to dynamically interact with the ColdBox Modules. This service is available by talking to the main ColdBox controller and calling its getModuleService() method: \n// get module service from handlers, plugins, layouts, interceptors or views.\nms = controller.getModuleService();\n\n// You can also inject it via our autowire DSL\nproperty name=\"moduleService\" inject=\"coldbox:moduleService\";\n\n \nModule Lifecycle\n\n \n\nHowever, before we start reviewing the module service methods let\'s review how modules get loaded in a ColdBox application. Below is a simple bullet point of what happens in your application when it starts up and you can also look at the diagram above: \n\nColdBox main application and configuration loads \nColdBox Cache, Logging and WireBox are created \nModule Service calls on registerAllModules() to read all the modules in the modules locations (with include/excludes) and start registering their configurations one by one. If the module had parent settings, interception points, datasoures or webservices, these are registered here. \nAll main application interceptors are loaded and configured \nColdBox is marked as initialized \nModule service calls on activateAllModules() so it begins activating only the registered modules one by one. This registers the module\'s SES URL Mappings, model objects, etc \nafterConfigurationLoad interceptors are fired \nColdBox aspects such as i18n, javaloader, ColdSpring/LightWire factories are loaded \nafterAspectsLoad interceptors are fired \n\nThe most common methods that you can use to control the modules in your application are the following: \n\nreloadAll() : Reload all modules in the application. This clears out all module settings, re-registers from disk, re-configures them and activates them \nreload(module) : Target a module reload by name \nunloadAll() : Unload all modules \nunload(module) : Target a module unload by name \nregisterAllModules() : Registers all module configurations \nregisterModule(module) : Target a module configuration registration \nactivateAllModules() : Activate all registered modules \nactivateModule(module) : Target activate a module that has been registered already \ngetLoadedModules() : Get an array of loaded module names \nrebuildModuleRegistry() : Rescan all the module lcoations for newly installed modules and rebuild the registry so these modules can be registered and activated. \nregisterAndActivateModule(module) : Registe','2011-03-29 11:42:49','2011-03-29 11:42:49',b'1',1), + (9,'http://blog.coldbox.org/post.cfm/coldbox-connection-show-wednesday','ColdBox Connection Show Wednesday','Just a reminder that this March 3.0.0, 2011 we will be holding a special ColdBox Open Forum Connection at 9 AM PST.  You can find more information below:Location:  http://experts.adobeconnect.com/coldbox-connection/ColdBox Connection Shows: http://www.coldbox.org/media/connectionWatch out!! Something is coming!!','2011-03-28 20:59:29','2011-03-28 20:59:29',b'1',1), + (10,'http://blog.coldbox.org/post.cfm/coldbox-modules-contest-extended','ColdBox Modules Contest Extended','We are extending our Modules Contest to allow for more time for entries to trickle in and of course to leverage ColdBox 3 coming this week.\nDeadline: Module entries must be submitted by March 29th EXTENDED: April 8th, 2011 no later than 12PM PST to contests@ortussolutions.com\nWinners Announced on March 30th EXTENDED: April 14th, 2011 The ColdBox Connection show at 9AM PST\nColdBox 3.0 Modules ContestCreate a ColdBox 3.0.0 module that is a fully functional application that can be portable for any ColdBox 3.0 application. Here are some guidelines the ColdBox team will be evaluating the module on\n\nDownload ColdBox\n\nThe code must reside on either github or a public repository so it is publicly accessible\n\nThe user must create a forgebox entry and submit the module code to it: http://coldbox.org/forgebox\n\nThe more internal libraries it uses the more points it gets: LogBox, MockBox, WireBox, CacheBox\n\nThe module should do something productive, no say hello modules accepted\n\nBest practices on MVC separation of concerns\n\nPortability\n\nDocumentation (You had that one coming!!) as it might need DB setup or DSN setup\n\nBe creative!\n\nMake sure it works!\n\n\n1st Prize\n\nAn Adobe ColdFusion 9 Standard License\n\n$100 Amazon Gift Card\n\nSix pack of \"BrewFather\" beer\n\n\n2nd Prize\n\nA ColdBox Book\n\nA ColdBox T-Shirt\n\n$25 Amazon Gift Card\n\nSix pack of \"BrewFather\" beer\n','2011-03-27 20:29:07','2011-03-27 20:29:07',b'1',1), + (11,'http://blog.coldbox.org/post.cfm/coldbox-3-release-training-special-discounts','ColdBox 3 Release Training Special Discounts','\n We are currently holding a special promotion that starts today March 27, 2011 until April 3rd, 2011\n at 3:00 PM PST. Take advantage of this insane $300 off any training of your choice in honor \n of our ColdBox 3.0.0 release this week.  Just use our discount code \n viva3 in our training registration pages or follow our links below and get this discount. \n Hurry as the code expires on April 3rd, 2011 at 3PM PST.\n \n \nCalifornia Ontario/Los Angeles Training - April 27 to May 1, 2011\n\nDiscount Link: http://coldbox.eventbrite.com/?discount=viva3 \nCBOX-101 ColdBox Core on April 27 - April 29, 2011\nCBOX-203 ColdBox Modules on April 30 - May 1, 2011\n\nPre-CFObjective Minneapolis Training - May 10-11, 2011\n\nDiscount Link: http://coldbox-cfobjective.eventbrite.com/?discount=viva3 \nCBOX-100 ColdBox Core on May 10-11, 2011\nCBOX-202 WireBox Dependency Injection on May 10-11, 2011\n\nHouston, Texas Training - April 27 to May 1, 2011\n\nDiscount Link: http://coldbox-texas.eventbrite.com/?discount=viva3 \nCBOX-101 ColdBox Core on July 6-8, 2011\nCBOX-203 ColdBox Modules on July 7-8, 2011\n','2011-03-27 20:18:44','2011-03-27 20:18:44',b'1',1), + (12,'http://blog.coldbox.org/post.cfm/coldbox-connection-recordings-page','ColdBox Connection Recordings Page','We just created our new recordings page for the ColdBox Connection today, so you can get in one location all of the recordings.  Hopefully in the near future we will expand it with tags and search.','2011-03-25 11:36:08','2011-03-25 11:36:08',b'1',1), + (13,'http://blog.coldbox.org/post.cfm/coldbox-connection-recording-coldbox-modules','ColdBox Connection Recording: ColdBox Modules','Thanks for attending our 2nd ColdBox Connection webinar today!  This webinar focused on ColdBox modules, modularity and architecture.  Thanks go to Curt Gratz for presenting such excellent topic.  Here is the recording for the show and also please note that we will have another show March 3.0!','2011-03-24 11:41:53','2011-03-24 11:41:53',b'1',1), + (14,'http://blog.coldbox.org/post.cfm/coldbox-connection-thursday-modules','ColdBox Connection Thursday: Modules','Just a reminder that our ColdBox Connection Show continues this Thursday at 9 AM PST! Curt Gratz will be presenting on ColdBox Modules and of course we will all be there for questions and help. See you there!Location: http://experts.adobeconnect.com/coldbox-connection/Our full calendar of events can be found here: http://coldbox.org/about/eventscalendar','2011-03-22 08:48:10','2011-03-22 08:48:10',b'1',1), + (15,'http://blog.coldbox.org/post.cfm/coldbox-relax-v1-4-released','ColdBox Relax v1.4 released!','Here is a cool new update for ColdBox Relax - RESTful Tools For Lazy Experts!  This update fixes a few issues reported and also enhances the Relaxer console and updates its ability to support definitions for multiple tiers and much more. So download it now!\nHere are the closed issues for this release:\n\n #14 api_logs direct usage reference removed fixes\n #15 basic http authentication added to relaxer console so you can easily hit resources that require basic auth\n #10 entry points can now be a structure of name value pairs for multiple tiers\n #16 new browser results tab window to show how the results are rendered by a browser\n #17 addition http proxy as advanced settings to relaxer console so you can proxy your relaxed requests\n #11 Route Auto Generation - Method security fixes so implicit structures are generated alongside json structures\n\nHere is also a nice screencast showcasing version 1.4 capabilities:\n \n\n\n\n \nWhat is Relax? ColdBox Relax is a set of RESTful tools for lazy experts. We pride ourselves in helping developers work smarter and of course document more in less time by providing them the necessary tools to automagically document and test. ColdBox Relax is a way to describe RESTful web services, test RESTful web services, monitor RESTful web services and document RESTful web services. The following introductory video will explain it better than words!\n \n\n\n\nSo what are you waiting for? Get Relax Now!\n\n Source Code\n Download\n Documentation\n\n \n','2011-03-21 16:51:09','2011-03-21 16:51:09',b'1',1); + +/*!40000 ALTER TABLE `blogEntries` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table blogs +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `blogs`; + +CREATE TABLE `blogs` ( + `blogsID` int(11) NOT NULL AUTO_INCREMENT, + `blogsURL` longtext NOT NULL, + `blogsWebsiteurl` longtext NOT NULL, + `blogslanguage` varchar(10) NOT NULL, + `blogsTitle` longtext NOT NULL, + `blogsDescription` longtext NOT NULL, + `blogsdateBuilt` datetime NOT NULL, + `blogsdateSumitted` datetime NOT NULL, + `blogsIsActive` bit(1) NOT NULL, + `blogsAuthorname` varchar(200) DEFAULT NULL, + `blogsauthorEmail` varchar(200) DEFAULT NULL, + `blogsauthorURL` longtext, + PRIMARY KEY (`blogsID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `blogs` WRITE; +/*!40000 ALTER TABLE `blogs` DISABLE KEYS */; + +INSERT INTO `blogs` (`blogsID`, `blogsURL`, `blogsWebsiteurl`, `blogslanguage`, `blogsTitle`, `blogsDescription`, `blogsdateBuilt`, `blogsdateSumitted`, `blogsIsActive`, `blogsAuthorname`, `blogsauthorEmail`, `blogsauthorURL`) +VALUES + (1,'http://blog.coldbox.org/feeds/rss.cfm','http://blog.coldbox.org/','','ColdBox Platform','The official ColdBox Blog','2011-04-08 15:19:13','2011-04-08 15:19:13',b'1',NULL,NULL,NULL); + +/*!40000 ALTER TABLE `blogs` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table cacheBox +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `cacheBox`; + +CREATE TABLE `cacheBox` ( + `id` varchar(100) NOT NULL, + `objectKey` varchar(255) NOT NULL, + `objectValue` longtext NOT NULL, + `hits` int(11) NOT NULL DEFAULT '1', + `timeout` int(11) NOT NULL, + `lastAccessTimeout` int(11) NOT NULL, + `created` datetime NOT NULL, + `lastAccessed` datetime NOT NULL, + `isExpired` tinyint(4) NOT NULL DEFAULT '1', + `isSimple` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +LOCK TABLES `cacheBox` WRITE; +/*!40000 ALTER TABLE `cacheBox` DISABLE KEYS */; + +INSERT INTO `cacheBox` (`id`, `objectKey`, `objectValue`, `hits`, `timeout`, `lastAccessTimeout`, `created`, `lastAccessed`, `isExpired`, `isSimple`) +VALUES + ('DF658A103F07DC012AB905014C32D4C7','myKey','hello',1,0,0,'2016-02-25 16:34:00','2016-02-25 16:34:00',1,1); + +/*!40000 ALTER TABLE `cacheBox` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table categories +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `categories`; + +CREATE TABLE `categories` ( + `category_id` varchar(50) NOT NULL, + `category` varchar(100) NOT NULL, + `description` varchar(100) NOT NULL, + `modifydate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `testValue` varchar(100) DEFAULT NULL, + PRIMARY KEY (`category_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `categories` WRITE; +/*!40000 ALTER TABLE `categories` DISABLE KEYS */; + +INSERT INTO `categories` (`category_id`, `category`, `description`, `modifydate`, `testValue`) +VALUES + ('3A2C516C-41CE-41D3-A9224EA690ED1128','Presentations','

Presso

','2011-02-18 00:00:00',NULL), + ('40288110380cda3301382644c7f90008','LM','LM
','2012-06-10 23:00:00',NULL), + ('402881882814615e012826481061000c','Marc','This is marcs category
','2010-04-21 22:00:00',NULL), + ('402881882814615e01282bb047fd001e','Cool Wow','A cool wow category
','2010-04-22 22:00:00',NULL), + ('402881882b89b49b012b9201bda80002','PascalNews','PascalNews','2010-10-09 00:00:00',NULL), + ('402881a144f57bfd0144fa47bf040007','ads','asdf','2014-01-25 00:00:00',NULL), + ('5898F818-A9B6-4F5D-96FE70A31EBB78AC','Release','

Releases

','2009-04-18 11:48:53',NULL), + ('88B689EA-B1C0-8EEF-143A84813ACADA35','general','A general category','2010-03-31 12:53:21',NULL), + ('88B689EA-B1C0-8EEF-143A84813BCADA35','general','A second test general category','2010-03-31 12:53:21',NULL), + ('88B6C087-F37E-7432-A13A84D45A0F703B','News','A news cateogyr','2009-04-18 11:48:53',NULL), + ('99fc94fd3b98c834013b98c9b2140002','Fancy','Fancy Editor
','2012-12-14 00:00:00',NULL), + ('99fc94fd3b9a459d013b9db89c060002','Markus','Hello Markus
','2012-12-14 15:00:00',NULL), + ('A13C0DB0-0CBC-4D85-A5261F2E3FCBEF91','Training','unittest','2014-05-07 19:05:21',NULL), + ('ff80808128c9fa8b0128cc3af5d90007','Geeky Stuff','Geeky Stuff','2010-05-25 16:00:00',NULL), + ('ff80808128c9fa8b0128cc3b20bf0008','ColdBox','ColdBox','2010-05-23 16:00:00',NULL), + ('ff80808128c9fa8b0128cc3b7cdd000a','ColdFusion','ColdFusion','2010-05-23 16:00:00',NULL); + +/*!40000 ALTER TABLE `categories` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table comments +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `comments`; + +CREATE TABLE `comments` ( + `comment_id` varchar(50) NOT NULL, + `FKentry_id` varchar(50) NOT NULL, + `comment` text NOT NULL, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`comment_id`), + KEY `FK_comments_1` (`FKentry_id`), + KEY `FKentry_id` (`FKentry_id`), + CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`FKentry_id`) REFERENCES `entries` (`entry_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `comments` WRITE; +/*!40000 ALTER TABLE `comments` DISABLE KEYS */; + +INSERT INTO `comments` (`comment_id`, `FKentry_id`, `comment`, `time`) +VALUES + ('40288110380cda330138265bf9c4000a','8a64b3712e3a0a5e012e3a11a2cf0004','tt','2012-06-12 23:00:00'), + ('40288110380cda3301382c7fe50d0012','88B82629-B264-B33E-D1A144F97641614E','Test','2012-06-06 23:00:00'), + ('402881882814615e01282b13bbc20013','88B82629-B264-B33E-D1A144F97641614E','This entire blog post really offended me, I hate you','2010-04-22 22:00:00'), + ('402881882814615e01282b13fb290014','88B82629-B264-B33E-D1A144F97641614E','Why are you so hurtful man!','2010-04-22 22:00:00'), + ('402881882814615e01282b142cc60015','88B82629-B264-B33E-D1A144F97641614E','La realidad, que barbaro!','2010-04-22 22:00:00'), + ('88B8C6C7-DFB7-0F34-C2B0EFA4E5D7DA4C','88B82629-B264-B33E-D1A144F97641614E','this blog sucks.','2010-09-02 11:39:04'), + ('8a64b3712e3a0a5e012e3a10321d0002','402881882814615e01282b14964d0016','Vlad is awesome!','2011-02-18 00:00:00'), + ('8a64b3712e3a0a5e012e3a12b1d10005','8a64b3712e3a0a5e012e3a11a2cf0004','Vlad is awesome!','2011-02-18 00:00:00'); + +/*!40000 ALTER TABLE `comments` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table contact +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `contact`; + +CREATE TABLE `contact` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `firstName` varchar(255) DEFAULT NULL, + `lastName` varchar(255) DEFAULT NULL, + `email` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `contact` WRITE; +/*!40000 ALTER TABLE `contact` DISABLE KEYS */; + +INSERT INTO `contact` (`id`, `firstName`, `lastName`, `email`) +VALUES + (1,'Luis','Majano','lmajano@ortussolutions.com'), + (2,'Jorge','Reyes','lmajano@gmail.com'), + (3,'','',''); + +/*!40000 ALTER TABLE `contact` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table entries +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `entries`; + +CREATE TABLE `entries` ( + `entry_id` varchar(50) NOT NULL, + `entryBody` text NOT NULL, + `title` varchar(50) NOT NULL, + `postedDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `FKuser_id` varchar(36) NOT NULL, + PRIMARY KEY (`entry_id`), + KEY `FKuser_id` (`FKuser_id`), + CONSTRAINT `entries_ibfk_1` FOREIGN KEY (`FKuser_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 9216 kB; (`FKuser_id`) REFER `coolblog/users`(`'; + +LOCK TABLES `entries` WRITE; +/*!40000 ALTER TABLE `entries` DISABLE KEYS */; + +INSERT INTO `entries` (`entry_id`, `entryBody`, `title`, `postedDate`, `FKuser_id`) +VALUES + ('402881882814615e01282b14964d0016','Wow, welcome to my new blog, enjoy your stay
','My awesome post','2010-04-22 22:00:00','88B73A03-FEFA-935D-AD8036E1B7954B76'), + ('88B82629-B264-B33E-D1A144F97641614E','A first cool blog,hope it does not crash','A cool blog first posting','2009-04-08 00:00:00','88B73A03-FEFA-935D-AD8036E1B7954B76'), + ('8a64b3712e3a0a5e012e3a11a2cf0004','ContentBox is a professional open source modular content management engine that allows you to easily build websites adfsadf adfsadf asfddasfddasfddasfdd','My First Awesome Post My First Awesome Post','2013-04-16 22:00:00','88B73A03-FEFA-935D-AD8036E1B7954B76'), + ('8aee965b3cfff278013d0007d9540002','Mobile browsing popularity is skyrocketing.  According to a new Pew Internet Project report, 25% of Americans use smartphones instead of computers for the majority of their web browsing.\r\nMissing out on the mobile marketing trend is\r\n likely to translate into loss of market share and decreased sales. \r\nThat’s not to say that it’s right for every business, but you at least \r\nneed to consider your target market persona before simply dismissing \r\nmobile as a fad.\r\nOne simple step you can take in the mobile direction is to learn how to add Apple icons to your website.\r\n

What Are Apple Icons & Why Use Them?

\r\n\"GuavaBoxApple\r\n Icons are simply the graphics you’ve chosen to represent your site when\r\n a user saves your page to their home screen in iOS.\r\nIf you don’t have Apple Icons created for your site, iOS grabs a \r\ncompressed thumbnail of your website and displays it as the icon.  The \r\nresult is typically indistinguishable and unappealing.\r\nApple Icons are an awesome branding opportunity and give you the chance to g
','Test','2013-04-23 00:00:00','402884cc310b1ae901311be89381000a'), + ('99fc94fd3ba7f266013bad4a8a3b0004','This is my first blog post from Bern!
','This is my first blog post from Bern!','2012-12-17 15:00:00','99fc94fd3ba7f266013bad49e3c50003'); + +/*!40000 ALTER TABLE `entries` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table entry_categories +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `entry_categories`; + +CREATE TABLE `entry_categories` ( + `FKcategory_id` varchar(50) NOT NULL, + `FKentry_id` varchar(50) NOT NULL, + KEY `FKcategory_id` (`FKcategory_id`), + KEY `FKentry_id` (`FKentry_id`), + CONSTRAINT `entry_categories_ibfk_1` FOREIGN KEY (`FKcategory_id`) REFERENCES `categories` (`category_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `entry_categories_ibfk_2` FOREIGN KEY (`FKentry_id`) REFERENCES `entries` (`entry_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `entry_categories` WRITE; +/*!40000 ALTER TABLE `entry_categories` DISABLE KEYS */; + +INSERT INTO `entry_categories` (`FKcategory_id`, `FKentry_id`) +VALUES + ('88B689EA-B1C0-8EEF-143A84813ACADA35','88B82629-B264-B33E-D1A144F97641614E'), + ('88B6C087-F37E-7432-A13A84D45A0F703B','88B82629-B264-B33E-D1A144F97641614E'), + ('3A2C516C-41CE-41D3-A9224EA690ED1128','99fc94fd3ba7f266013bad4a8a3b0004'), + ('5898F818-A9B6-4F5D-96FE70A31EBB78AC','99fc94fd3ba7f266013bad4a8a3b0004'), + ('99fc94fd3b98c834013b98c9b2140002','99fc94fd3ba7f266013bad4a8a3b0004'), + ('5898F818-A9B6-4F5D-96FE70A31EBB78AC','402881882814615e01282b14964d0016'), + ('40288110380cda3301382644c7f90008','402881882814615e01282b14964d0016'), + ('3A2C516C-41CE-41D3-A9224EA690ED1128','402881882814615e01282b14964d0016'), + ('402881882b89b49b012b9201bda80002','402881882814615e01282b14964d0016'), + ('99fc94fd3b98c834013b98c9b2140002','402881882814615e01282b14964d0016'), + ('5898F818-A9B6-4F5D-96FE70A31EBB78AC','8a64b3712e3a0a5e012e3a11a2cf0004'), + ('A13C0DB0-0CBC-4D85-A5261F2E3FCBEF91','8a64b3712e3a0a5e012e3a11a2cf0004'), + ('3A2C516C-41CE-41D3-A9224EA690ED1128','8a64b3712e3a0a5e012e3a11a2cf0004'); + +/*!40000 ALTER TABLE `entry_categories` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table logs +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `logs`; + +CREATE TABLE `logs` ( + `id` varchar(36) NOT NULL, + `severity` varchar(10) NOT NULL, + `category` varchar(100) NOT NULL, + `logdate` datetime NOT NULL, + `appendername` varchar(100) NOT NULL, + `message` text, + `extrainfo` text, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + + +# Dump of table relax_logs +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `relax_logs`; + +CREATE TABLE `relax_logs` ( + `id` varchar(36) NOT NULL, + `severity` varchar(10) NOT NULL, + `category` varchar(100) NOT NULL, + `logdate` datetime NOT NULL, + `appendername` varchar(100) NOT NULL, + `message` longtext, + `extrainfo` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + + +# Dump of table roles +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `roles`; + +CREATE TABLE `roles` ( + `roleID` int(11) NOT NULL AUTO_INCREMENT, + `role` varchar(100) DEFAULT NULL, + PRIMARY KEY (`roleID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `roles` WRITE; +/*!40000 ALTER TABLE `roles` DISABLE KEYS */; + +INSERT INTO `roles` (`roleID`, `role`) +VALUES + (1,'Administrator'), + (2,'Moderator'), + (3,'Anonymous'), + (4,'Super User'), + (5,'Editor'); + +/*!40000 ALTER TABLE `roles` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table todo +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `todo`; + +CREATE TABLE `todo` ( + `blogsID` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) DEFAULT NULL, + PRIMARY KEY (`blogsID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +LOCK TABLES `todo` WRITE; +/*!40000 ALTER TABLE `todo` DISABLE KEYS */; + +INSERT INTO `todo` (`blogsID`, `name`) +VALUES + (1,'AL-{ts \'2011-04-07 11:15:55\'}'), + (2,'AL-{ts \'2011-04-07 11:16:22\'}'), + (3,'AL-{ts \'2011-04-07 11:17:06\'}'), + (4,'AL-{ts \'2011-04-07 11:21:52\'}'), + (5,'AL-{ts \'2011-04-07 11:23:06\'}'), + (6,'AL-{ts \'2011-04-07 11:23:08\'}'), + (7,'AL-{ts \'2011-04-18 17:23:59\'}'), + (8,'AL-{ts \'2011-04-18 17:37:15\'}'), + (9,'AL-{ts \'2011-04-18 17:37:20\'}'), + (10,'AL-{ts \'2011-04-18 17:38:06\'}'), + (11,'AL-{ts \'2011-04-18 17:38:08\'}'), + (12,'AL-{ts \'2011-04-18 17:38:09\'}'), + (13,'AL-{ts \'2011-04-18 17:38:10\'}'), + (14,'AL-{ts \'2011-04-18 17:38:11\'}'), + (15,'AL-{ts \'2011-04-18 17:38:12\'}'), + (16,'AL-{ts \'2011-04-18 17:38:14\'}'), + (17,'AL-{ts \'2011-04-18 17:38:15\'}'), + (18,'AL-{ts \'2011-04-18 17:38:16\'}'), + (19,'AL-{ts \'2011-04-18 17:38:17\'}'), + (20,'AL-{ts \'2011-04-18 17:38:18\'}'), + (21,'AL-{ts \'2011-04-18 17:38:19\'}'), + (22,'AL-{ts \'2011-04-18 17:38:20\'}'), + (23,'AL-{ts \'2011-04-18 17:38:21\'}'), + (24,'AL-{ts \'2011-04-18 17:40:41\'}'), + (25,'AL-{ts \'2011-04-18 17:40:44\'}'), + (26,'AL-{ts \'2011-04-18 17:40:47\'}'), + (27,'AL-{ts \'2011-04-18 17:41:38\'}'), + (28,'AL-{ts \'2011-04-18 17:44:15\'}'), + (29,'AL-{ts \'2011-04-18 17:44:25\'}'), + (30,'AL-{ts \'2011-04-18 17:44:39\'}'), + (31,'AL-{ts \'2011-04-18 17:49:44\'}'), + (32,'AL-{ts \'2011-04-18 17:50:10\'}'), + (33,'AL-{ts \'2011-04-18 17:51:07\'}'), + (34,'AL-{ts \'2011-04-18 17:57:44\'}'), + (35,'AL-{ts \'2011-04-18 18:03:33\'}'), + (36,'AL-{ts \'2011-04-18 19:32:04\'}'), + (37,'AL-{ts \'2011-04-18 19:32:08\'}'), + (38,'AL-{ts \'2011-04-18 19:32:31\'}'), + (39,'AL-{ts \'2011-04-18 19:32:51\'}'), + (40,'AL-{ts \'2011-04-18 20:02:55\'}'), + (41,'AL-{ts \'2011-04-18 20:03:52\'}'), + (42,'AL-{ts \'2011-04-18 20:04:10\'}'), + (43,'AL-{ts \'2011-04-18 20:12:52\'}'), + (44,'AL-{ts \'2011-04-19 15:43:36\'}'), + (45,'AL-{ts \'2011-04-19 15:44:20\'}'), + (46,'AL-{ts \'2011-04-19 15:48:26\'}'), + (47,'AL-{ts \'2011-04-19 15:50:59\'}'), + (48,'AL-{ts \'2011-04-19 15:51:08\'}'), + (49,'AL-{ts \'2011-04-19 15:51:15\'}'), + (50,'AL-{ts \'2011-04-23 12:58:04\'}'); + +/*!40000 ALTER TABLE `todo` ENABLE KEYS */; +UNLOCK TABLES; + + +# Dump of table users +# ------------------------------------------------------------ + +DROP TABLE IF EXISTS `users`; + +CREATE TABLE `users` ( + `user_id` varchar(50) NOT NULL, + `firstName` varchar(50) NOT NULL, + `lastName` varchar(50) NOT NULL, + `userName` varchar(50) NOT NULL, + `password` varchar(50) NOT NULL, + `lastLogin` datetime DEFAULT NULL, + `FKRoleID` int(11) DEFAULT NULL, + `isActive` bit(1) DEFAULT b'1', + PRIMARY KEY (`user_id`), + KEY `FKRoleID` (`FKRoleID`), + CONSTRAINT `users_ibfk_1` FOREIGN KEY (`FKRoleID`) REFERENCES `roles` (`roleID`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +LOCK TABLES `users` WRITE; +/*!40000 ALTER TABLE `users` DISABLE KEYS */; + +INSERT INTO `users` (`user_id`, `firstName`, `lastName`, `userName`, `password`, `lastLogin`, `FKRoleID`, `isActive`) +VALUES + ('4028818e2fb6c893012fe637c5db00a7','George','Form Injector','george','george',NULL,2,b'1'), + ('402884cc310b1ae901311be89381000a','ken','Advanced Guru','kenneth','smith','2014-03-25 00:00:00',2,b'1'), + ('4A386F4D-DCF4-6587-7B89B3BD57C97155','Joe','Fernando','joe','joe','2009-05-15 00:00:00',1,b'1'), + ('88B73A03-FEFA-935D-AD8036E1B7954B76','Luis','Majano','lui','lmajano','2009-04-08 00:00:00',1,b'1'), + ('8a64b3712e3a0a5e012e3a110fab0003','Vladymir','Ugryumov','vlad','vlad','2011-02-18 00:00:00',1,b'1'), + ('99fc94fd3b98c834013b98c928120001','Juerg','Anderegg','juerg','juerg','2012-12-14 00:00:00',NULL,b'1'), + ('99fc94fd3ba7f266013bad49e3c50003','Tanja','Zogg','tanja','tanja','2012-12-18 00:00:00',NULL,b'1'); + +/*!40000 ALTER TABLE `users` ENABLE KEYS */; +UNLOCK TABLES; + + + +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/test-harness/tests/runner.cfm b/test-harness/tests/runner.cfm new file mode 100644 index 0000000..f5ec955 --- /dev/null +++ b/test-harness/tests/runner.cfm @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test-harness/tests/specs/ModuleSpec.cfc b/test-harness/tests/specs/ModuleSpec.cfc new file mode 100644 index 0000000..4a2dd25 --- /dev/null +++ b/test-harness/tests/specs/ModuleSpec.cfc @@ -0,0 +1,24 @@ +component extends="coldbox.system.testing.BaseTestCase" appMapping="root" { + + /*********************************** LIFE CYCLE Methods ***********************************/ + + function beforeAll(){ + super.beforeAll(); + setup(); + } + + function afterAll(){ + super.afterAll(); + } + + /*********************************** BDD SUITES ***********************************/ + + function run(){ + describe( "MockData CFC", function(){ + beforeEach( function( currentSpec ){ + } ); + + } ); + } + +} diff --git a/test-harness/views/main/index.cfm b/test-harness/views/main/index.cfm new file mode 100644 index 0000000..992cabe --- /dev/null +++ b/test-harness/views/main/index.cfm @@ -0,0 +1,3 @@ + +Module Tester + \ No newline at end of file