diff --git a/.gitattributes b/.gitattributes
index 5e0c801de..2cda5ad55 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6,6 +6,8 @@ test export-ignore
.gitignore export-ignore
.gitmodules export-ignore
mkdocs.yml export-ignore
+BUILD_NO export-ignore
+mkdocs_offline.yml export-ignore
sonar-project.properties export-ignore
^docs/** linguist-documentation
*.pkb linguist-language=PLSQL
diff --git a/.github/DISCUSSION_TEMPLATE/README.md b/.github/DISCUSSION_TEMPLATE/README.md
new file mode 100644
index 000000000..f6c0905f4
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/README.md
@@ -0,0 +1,150 @@
+# GitHub Discussions β setup guide for utPLSQL/utPLSQL
+
+This folder contains the discussion category form templates that power structured
+GitHub Discussions for the utPLSQL project.
+
+---
+
+## File β category mapping
+
+
+
+| File | Category name to create in GitHub | Format | Who can post |
+|------------------------|-----------------------------------|-----------------------|--------------------------------|
+| `announcements.yml` | π’ Announcements | Announcement | Maintainers only |
+| `rfcs-design.yml` | π‘ RFCs & Design | Open-ended discussion | Everyone |
+| `architecture.yml` | π Architecture | Open-ended discussion | Everyone |
+| `release-planning.yml` | π Release Planning | Open-ended discussion | Maintainers only (recommended) |
+| `q-a.yml` | β Q&A | Question / Answer | Everyone |
+| `show-and-tell.yml` | π¬ Show & Tell | Open-ended discussion | Everyone |
+| `contributors.yml` | π€ Contributors | Open-ended discussion | Everyone |
+| `general.yml` | π¬ General | Open-ended discussion | Everyone |
+
+> **Polls** are a built-in GitHub Discussions type and do not support YAML templates.
+> Create a π³ Polls category manually (type: Poll) β no template file needed.
+
+---
+
+## Step-by-step setup
+
+### 1. Enable Discussions
+Go to **Settings β Features** and check **Discussions**.
+
+### 2. Create the categories
+Go to **Discussions β Categories β βοΈ Edit categories** (gear icon).
+
+Create each category listed in the table above.
+**Order matters** β drag to set the display order shown below:
+
+1. π’ Announcements
+2. π‘ RFCs & Design
+3. π Architecture
+4. π Release Planning
+5. β Q&A
+6. π¬ Show & Tell
+7. π€ Contributors
+8. π³ Polls
+9. π¬ General
+
+### 3. Commit the templates
+Copy all `.yml` files from this folder into `.github/DISCUSSION_TEMPLATE/` in
+the **default branch** (usually `develop` for utPLSQL).
+
+```
+.github/
+βββ DISCUSSION_TEMPLATE/
+ βββ announcements.yml
+ βββ rfcs-design.yml
+ βββ architecture.yml
+ βββ release-planning.yml
+ βββ q-a.yml
+ βββ show-and-tell.yml
+ βββ contributors.yml
+ βββ general.yml
+```
+
+### 4. Configure category permissions
+
+| Category | Setting |
+|------------------|--------------------------------------------------|
+| Announcements | Set to **Maintainers only** in category settings |
+| Release Planning | Recommended: **Maintainers only** |
+| All others | Open to all |
+
+### 5. Create the welcome pinned post
+
+Create a first discussion in **Announcements** titled
+**"Welcome to utPLSQL Discussions β how to use this space"**
+
+Suggested body:
+
+```markdown
+## Welcome π
+
+This is the place for design discussions, feature proposals, and community
+conversation around utPLSQL.
+
+### Where to post
+
+| I want to⦠| Use |
+|---|---|
+| Propose a new feature or behaviour change | π‘ RFCs & Design |
+| Discuss internal architecture | π Architecture |
+| Ask a usage / how-to question | β Q&A |
+| Share a CI pipeline, integration, or tip | π¬ Show & Tell |
+| Ask about contributing / development setup | π€ Contributors |
+| Vote on priorities | π³ Polls |
+| Anything else | π¬ General |
+
+### Discussions vs Issues
+
+**Discussions** are for ideas that are still open, need input, or require consensus.
+**Issues** are for well-scoped work that someone can pick up and implement.
+
+A maintainer will convert a Discussion to an Issue once scope is agreed.
+
+### Real-time chat
+
+For quick questions: [utPLSQL Slack](https://utplsql.slack.com)
+For decisions that need a permanent record: post here.
+```
+
+Pin this post from the discussion's `β¦` menu β **Pin discussion**.
+
+### 6. Update the README
+
+Add a Discussions badge to the project README:
+
+```markdown
+[](https://github.com/utPLSQL/utPLSQL/discussions)
+```
+
+And add a short paragraph in the "Community" or "Contributing" section pointing
+to Discussions as the place for design proposals.
+
+---
+
+## Operating guidelines
+
+### Discussion β Issue conversion rule
+
+| Category | Convert when⦠|
+|---------------|----------------------------------------------------------------------|
+| RFCs & Design | Consensus reached, scope is defined |
+| Architecture | Breaking change formally agreed by maintainers |
+| Q&A | A confirmed bug surfaces in the thread |
+| Contributors | A gap in docs or tooling is identified that can be filed as an issue |
+
+Use the **"Create issue from discussion"** button (available in the discussion's sidebar).
+
+### Housekeeping
+
+- Lock **Announcements** threads after 30 days.
+- Close **Polls** after 14 days; post a summary comment with the result before closing.
+- Label cross-references: apply the same labels used on issues
+ (`enhancement`, `breaking-change`, `coverage`, `oracle-version`, etc.)
+ to discussions for consistent search.
diff --git a/.github/DISCUSSION_TEMPLATE/announcements.yml b/.github/DISCUSSION_TEMPLATE/announcements.yml
new file mode 100644
index 000000000..262746e11
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/announcements.yml
@@ -0,0 +1,54 @@
+title: "[Announcement] "
+labels: ["announcement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ > **Maintainers only.** This category is restricted to project maintainers.
+ > Announcements are pinned and locked after 30 days.
+
+ - type: dropdown
+ id: announcement_type
+ attributes:
+ label: Announcement type
+ options:
+ - New release
+ - Release candidate / pre-release
+ - Roadmap update
+ - Deprecation notice
+ - Security advisory
+ - Community / governance update
+ - Other
+ validations:
+ required: true
+
+ - type: input
+ id: version
+ attributes:
+ label: Version (if applicable)
+ placeholder: "e.g. 3.2.0"
+ validations:
+ required: false
+
+ - type: textarea
+ id: body
+ attributes:
+ label: Announcement body
+ description: |
+ Write the full announcement here.
+ For releases, include: highlights, breaking changes, upgrade notes, and a link to the full changelog.
+ validations:
+ required: true
+
+ - type: textarea
+ id: links
+ attributes:
+ label: Key links
+ description: Release tag, changelog, migration guide, Docker image, CLI download, etc.
+ placeholder: |
+ - Release: https://github.com/utPLSQL/utPLSQL/releases/tag/vβ¦
+ - Changelog: β¦
+ - Docker: β¦
+ - CLI: β¦
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/architecture.yml b/.github/DISCUSSION_TEMPLATE/architecture.yml
new file mode 100644
index 000000000..f3df8e29c
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/architecture.yml
@@ -0,0 +1,100 @@
+title: "[Architecture] "
+labels: ["architecture", "design"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Architecture discussion
+ Use this template for internal design decisions: changes to the suite-loading mechanism,
+ the coverage engine, DDL trigger behaviour, reporter infrastructure, or any
+ cross-cutting concern that affects the internals of utPLSQL.
+
+ This category is primarily for **contributors and maintainers**.
+ If you want to propose a user-facing feature, use **RFCs & Design** instead.
+
+ - type: input
+ id: title_short
+ attributes:
+ label: Component / area
+ description: Which internal component or subsystem does this discussion concern?
+ placeholder: "e.g. Suite loader, Coverage engine, Annotation parser, Event system"
+ validations:
+ required: true
+
+ - type: textarea
+ id: context
+ attributes:
+ label: Context and current design
+ description: Briefly describe how the relevant part works today.
+ validations:
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem or design question
+ description: What specific decision needs to be made, or what limitation needs to be addressed?
+ validations:
+ required: true
+
+ - type: textarea
+ id: options
+ attributes:
+ label: Options under consideration
+ description: |
+ List the design options you are weighing. For each option describe:
+ - How it works
+ - Pros
+ - Cons
+ - Impact on Oracle compatibility
+ placeholder: |
+ **Option A β β¦**
+ How: β¦
+ Pros: β¦
+ Cons: β¦
+
+ **Option B β β¦**
+ How: β¦
+ Pros: β¦
+ Cons: β¦
+ validations:
+ required: true
+
+ - type: textarea
+ id: preferred
+ attributes:
+ label: Preferred direction (if any)
+ description: If you already lean toward one option, say so and why. Leave blank if genuinely open.
+ validations:
+ required: false
+
+ - type: dropdown
+ id: breaking
+ attributes:
+ label: Does this introduce a breaking change?
+ options:
+ - "No"
+ - "Yes β public API change (ut_runner, ut packages, annotations)"
+ - "Yes β output/reporter format change"
+ - "Yes β internal package change (no public API impact)"
+ - "Unsure"
+ validations:
+ required: true
+
+ - type: textarea
+ id: migration
+ attributes:
+ label: Migration / compatibility notes
+ description: If breaking, describe the migration path for users and downstream integrations.
+ validations:
+ required: false
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ options:
+ - label: I have reviewed the existing architecture docs and source
+ required: true
+ - label: Relevant unit / integration tests have been considered
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/contributors.yml b/.github/DISCUSSION_TEMPLATE/contributors.yml
new file mode 100644
index 000000000..6325961de
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/contributors.yml
@@ -0,0 +1,56 @@
+title: "[Contributors] "
+labels: ["contributors"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Contributors
+ Questions about **contributing to utPLSQL** β development environment setup,
+ the test suite, pull request process, coding conventions, or anything else
+ that helps you get your first (or next) contribution merged.
+
+ **Useful links before posting:**
+ - [CONTRIBUTING.md](../../blob/develop/CONTRIBUTING.md)
+ - [Development environment setup](../../blob/develop/docs/development/developer-guide.md)
+ - [Open issues labelled `good first issue`](../../issues?q=is%3Aopen+label%3A%22good+first+issue%22)
+
+ - type: dropdown
+ id: topic
+ attributes:
+ label: Topic
+ options:
+ - Dev environment / Docker setup
+ - Running the test suite locally
+ - Understanding the codebase
+ - PR review process
+ - Coding conventions / style
+ - Good first issue β looking for guidance
+ - Release process
+ - Documentation contribution
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question or request
+ description: What do you need help with?
+ validations:
+ required: true
+
+ - type: textarea
+ id: context
+ attributes:
+ label: What you have tried
+ description: Steps already taken, error messages, links to relevant code, etc.
+ validations:
+ required: false
+
+ - type: input
+ id: os
+ attributes:
+ label: Host OS / environment
+ placeholder: "e.g. macOS 14, Windows 11, Ubuntu 22.04, Docker on Linux"
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/general.yml b/.github/DISCUSSION_TEMPLATE/general.yml
new file mode 100644
index 000000000..0e3b8d100
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/general.yml
@@ -0,0 +1,28 @@
+title: ""
+labels: ["general"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## General discussion
+ For open-ended conversations that don't fit another category:
+ project direction, community topics, suggestions, or anything else.
+
+ If your post turns out to be a feature proposal, a maintainer may move it to
+ **RFCs & Design**. If it is a question about using utPLSQL, consider posting
+ in **Q&A** instead so a helpful answer can be marked.
+
+ - type: textarea
+ id: body
+ attributes:
+ label: What's on your mind?
+ validations:
+ required: true
+
+ - type: textarea
+ id: context
+ attributes:
+ label: Additional context
+ description: Background, links, related issues or discussions.
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/q-a.yml b/.github/DISCUSSION_TEMPLATE/q-a.yml
new file mode 100644
index 000000000..e4ff1d452
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/q-a.yml
@@ -0,0 +1,87 @@
+title: "[Q&A] "
+labels: ["question"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Question & Answer
+ Ask anything about **using** utPLSQL β installation, writing tests, CI integration,
+ reporters, annotations, code coverage, etc.
+
+ **Tips for a fast answer:**
+ - Include your utPLSQL version and Oracle version.
+ - Paste a minimal reproducer (test package + expected vs actual output).
+ - Check the [documentation](https://utplsql.github.io/utPLSQL/) and
+ [closed Q&A discussions](../../discussions/categories/q-a?discussions_q=is%3Aclosed) first.
+
+ > If this turns out to be a **bug**, a maintainer will convert this discussion into an Issue.
+
+ - type: input
+ id: utplsql_version
+ attributes:
+ label: utPLSQL version
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: oracle_version
+ attributes:
+ label: Oracle version
+ options:
+ - Oracle 11g
+ - Oracle 12c
+ - Oracle 18c
+ - Oracle 19c
+ - Oracle 21c
+ - Oracle 23c / 23ai
+ - Other / unsure
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question
+ description: Describe what you are trying to do and what you have tried so far.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproducer
+ attributes:
+ label: Minimal reproducer
+ description: |
+ Paste a minimal test package and/or the relevant ut_runner call.
+ Include the full error message or unexpected output if applicable.
+ render: sql
+ validations:
+ required: false
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected behaviour
+ validations:
+ required: false
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual behaviour / error
+ validations:
+ required: false
+
+ - type: dropdown
+ id: install_method
+ attributes:
+ label: Installation method
+ options:
+ - utPLSQL-cli
+ - SQL*Plus script
+ - Docker / utPLSQL-docker
+ - Liquibase / Flyway
+ - Other
+ - N/A
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/release-planning.yml b/.github/DISCUSSION_TEMPLATE/release-planning.yml
new file mode 100644
index 000000000..5663d7613
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/release-planning.yml
@@ -0,0 +1,90 @@
+title: "[Release] v"
+labels: ["release-planning"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Release planning discussion
+ Use this template to discuss the scope of an upcoming release:
+ what goes in, what gets deferred, and what the acceptance criteria are.
+
+ **Maintainers:** pin this discussion and link it from the corresponding GitHub Milestone.
+
+ - type: input
+ id: version
+ attributes:
+ label: Target version
+ placeholder: "e.g. 3.2.0"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: release_type
+ attributes:
+ label: Release type
+ options:
+ - Major (breaking changes)
+ - Minor (new features, backward-compatible)
+ - Patch (bug fixes only)
+ validations:
+ required: true
+
+ - type: textarea
+ id: goals
+ attributes:
+ label: Release goals
+ description: What are the 2β4 key things this release should achieve?
+ placeholder: |
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+
+ - type: textarea
+ id: scope_in
+ attributes:
+ label: In scope (proposed issues / PRs)
+ description: |
+ Link the GitHub Issues and PRs targeted for this release.
+ Use the format: `- [ ] #123 β short description`
+ placeholder: |
+ - [ ] #123 β ...
+ - [ ] #456 β ...
+ validations:
+ required: false
+
+ - type: textarea
+ id: scope_out
+ attributes:
+ label: Out of scope / explicitly deferred
+ description: Issues that were considered but will not be included β and why.
+ validations:
+ required: false
+
+ - type: input
+ id: target_date
+ attributes:
+ label: Target release date (approximate)
+ placeholder: "e.g. 2025-Q2"
+ validations:
+ required: false
+
+ - type: textarea
+ id: oracle_matrix
+ attributes:
+ label: Oracle version test matrix
+ description: Which Oracle versions must pass CI before this release ships?
+ placeholder: |
+ - [ ] Oracle 19c
+ - [ ] Oracle 21c
+ - [ ] Oracle 23ai
+ validations:
+ required: false
+
+ - type: textarea
+ id: notes
+ attributes:
+ label: Additional notes
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/rfcs-design.yml b/.github/DISCUSSION_TEMPLATE/rfcs-design.yml
new file mode 100644
index 000000000..32c0a33c7
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/rfcs-design.yml
@@ -0,0 +1,88 @@
+title: "[RFC] "
+labels: ["rfc", "design"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Request for Comments β design proposal
+ Use this template to propose a new feature, a change to existing behaviour, or a significant refactoring.
+ Once there is consensus and a clear scope, a maintainer will convert this discussion into one or more GitHub Issues.
+
+ **Before posting:** search existing RFCs and open issues to avoid duplicates.
+
+ - type: input
+ id: summary
+ attributes:
+ label: Summary
+ description: One sentence β what are you proposing?
+ placeholder: "Add support for ..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem / motivation
+ description: What problem does this solve? Who is affected and how often?
+ placeholder: |
+ Currently, when ... it is not possible to ...
+ This forces users to ...
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed solution
+ description: Describe the solution in as much detail as you have. Pseudo-code, SQL, or PL/SQL snippets are welcome.
+ placeholder: |
+ ```sql
+ -- example of the proposed API
+ ```
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives considered
+ description: What other approaches did you look at? Why did you rule them out?
+ validations:
+ required: false
+
+ - type: textarea
+ id: breaking
+ attributes:
+ label: Breaking-change impact
+ description: |
+ Does this change affect existing annotations, package APIs, or test output formats?
+ List affected public symbols (ut_runner, ut, annotations, reporters β¦).
+ validations:
+ required: false
+
+ - type: dropdown
+ id: oracle_versions
+ attributes:
+ label: Oracle version relevance
+ description: Which Oracle versions does this apply to?
+ multiple: true
+ options:
+ - All supported versions
+ - Oracle 11g
+ - Oracle 12c
+ - Oracle 18c
+ - Oracle 19c
+ - Oracle 21c
+ - Oracle 23c / 23ai
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ options:
+ - label: I have searched existing discussions and issues for duplicates
+ required: true
+ - label: I am willing to help implement or review this feature
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/show-and-tell.yml b/.github/DISCUSSION_TEMPLATE/show-and-tell.yml
new file mode 100644
index 000000000..4443c5de6
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/show-and-tell.yml
@@ -0,0 +1,79 @@
+title: "[Show & Tell] "
+labels: ["show-and-tell"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Show & Tell
+ Share how you are using utPLSQL in the wild β CI pipelines, IDE integrations,
+ custom reporters, coverage setups, framework wrappers, or anything else the
+ community might learn from.
+
+ Posts here are a great source of real-world examples for the documentation.
+
+ - type: input
+ id: title_short
+ attributes:
+ label: What are you sharing?
+ placeholder: "e.g. utPLSQL + GitHub Actions CI pipeline for Oracle 23ai"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: category
+ attributes:
+ label: Category
+ multiple: true
+ options:
+ - CI/CD integration
+ - IDE / SQL client integration
+ - Custom reporter
+ - Code coverage setup
+ - Framework wrapper / helper library
+ - Docker / containerised testing
+ - Annotation patterns
+ - Performance / large test suite
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: Describe what you built or configured and why it might be useful to others.
+ validations:
+ required: true
+
+ - type: textarea
+ id: snippet
+ attributes:
+ label: Code or configuration snippet
+ description: Paste the most relevant excerpt. Link to a repo or Gist if you have one.
+ render: yaml
+ validations:
+ required: false
+
+ - type: input
+ id: utplsql_version
+ attributes:
+ label: utPLSQL version used
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: false
+
+ - type: input
+ id: oracle_version
+ attributes:
+ label: Oracle version
+ placeholder: "e.g. Oracle 19c"
+ validations:
+ required: false
+
+ - type: textarea
+ id: links
+ attributes:
+ label: Links
+ description: Repository, blog post, documentation page, etc.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 681bc7f3a..f0335781e 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -23,4 +23,4 @@ Add any other context or screenshots about the feature request here.
> Please do not create issues for generic SQL or PL/SQL questions. There are other forums and communities to help you with those. See [ASKTom](https://asktom.oracle.com) for example.
**Want to discuss**
-If you want to discuss your issue, join [our SLACK chat](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww).
+If you want to discuss a problem, please go to [utPLSQL discussions](https://github.com/utPLSQL/utPLSQL/discussions)
diff --git a/.github/scripts/get_project_build_version.sh b/.github/scripts/get_project_build_version.sh
deleted file mode 100755
index 838523b05..000000000
--- a/.github/scripts/get_project_build_version.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env bash
-echo `sed -E "s/(v?[0-9]+\.)([0-9]+\.)([0-9]+)(-.*)?/\1\2\3\.${UTPLSQL_BUILD_NO}\4/" <<< "${UTPLSQL_VERSION}"`
diff --git a/.github/scripts/get_project_version.sh b/.github/scripts/get_project_version.sh
index 60fc0a796..54a30a562 100755
--- a/.github/scripts/get_project_version.sh
+++ b/.github/scripts/get_project_version.sh
@@ -1,14 +1,7 @@
#!/usr/bin/env bash
-
-#When building a new version from a release branch, the version is taken from release branch name
-if [[ "${CI_ACTION_REF_NAME}" =~ ^release/v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
- version=${CI_ACTION_REF_NAME#release\/}
-else
- #Otherwise, version is taken from the VERSION file
- version=`cat VERSION`
- #When on develop branch, add "-develop" to the version text
- if [[ "${CI_ACTION_REF_NAME}" == "develop" ]]; then
+version=`cat VERSION`
+#When on develop branch, add "-develop" to the version text
+if [[ "${CI_ACTION_REF_NAME}" == "develop" ]]; then
version=`sed -E "s/(v?[0-9]+\.[0-9]+\.[0-9]+).*/\1-develop/" <<< "${version}"`
- fi
fi
echo ${version}
diff --git a/.github/scripts/set_release_version_numbers_env.sh b/.github/scripts/set_release_version_numbers_env.sh
new file mode 100755
index 000000000..a43843508
--- /dev/null
+++ b/.github/scripts/set_release_version_numbers_env.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+build_no=$(cat BUILD_NO)
+version=${CI_ACTION_REF_NAME}
+
+echo "UTPLSQL_BUILD_NO=${build_no}" >> $GITHUB_ENV
+echo "UTPLSQL_VERSION=${version}" >> $GITHUB_ENV
+echo UTPLSQL_BUILD_VERSION=$(echo ${version} | sed -E "s/(v?[0-9]+\.)([0-9]+\.)([0-9]+)(-.*)?/\1\2\3\.${build_no}\4/") >> $GITHUB_ENV
+
diff --git a/.github/scripts/set_version_numbers_env.sh b/.github/scripts/set_version_numbers_env.sh
index 10529a1bf..c61639bf9 100755
--- a/.github/scripts/set_version_numbers_env.sh
+++ b/.github/scripts/set_version_numbers_env.sh
@@ -1,10 +1,8 @@
#!/bin/bash
-UTPLSQL_BUILD_NO=$( expr ${GITHUB_RUN_NUMBER} + ${UTPLSQL_BUILD_NO_OFFSET} )
-UTPLSQL_VERSION=$(.github/scripts/get_project_version.sh)
+build_no=$( expr ${GITHUB_RUN_NUMBER} + ${UTPLSQL_BUILD_NO_OFFSET} )
+version=$(.github/scripts/get_project_version.sh)
-echo "UTPLSQL_BUILD_NO=${UTPLSQL_BUILD_NO}" >> $GITHUB_ENV
-echo "UTPLSQL_VERSION=${UTPLSQL_VERSION}" >> $GITHUB_ENV
-echo UTPLSQL_BUILD_VERSION=$(echo ${UTPLSQL_VERSION} | sed -E "s/(v?[0-9]+\.)([0-9]+\.)([0-9]+)(-.*)?/\1\2\3\.${UTPLSQL_BUILD_NO}\4/") >> $GITHUB_ENV
-
-echo "CURRENT_BRANCH=${CI_ACTION_REF_NAME}" >> $GITHUB_ENV
+echo "UTPLSQL_BUILD_NO=${build_no}" >> $GITHUB_ENV
+echo "UTPLSQL_VERSION=${version}" >> $GITHUB_ENV
+echo UTPLSQL_BUILD_VERSION=$(echo ${version} | sed -E "s/(v?[0-9]+\.)([0-9]+\.)([0-9]+)(-.*)?/\1\2\3\.${build_no}\4/") >> $GITHUB_ENV
diff --git a/.github/scripts/update_project_version.sh b/.github/scripts/update_project_version.sh
index 586cb5b64..66e45125a 100755
--- a/.github/scripts/update_project_version.sh
+++ b/.github/scripts/update_project_version.sh
@@ -16,4 +16,5 @@ sed -i -r "s/(sonar\.projectVersion=).*?/\1${UTPLSQL_VERSION}/" sonar-project.pr
echo Update VERSION file
echo ${UTPLSQL_VERSION} > VERSION
+echo ${UTPLSQL_BUILD_NO} > BUILD_NO
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c2fe3971e..be6e18ca2 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -17,6 +17,7 @@ jobs:
build:
name: Build and test on ${{matrix.db_version_name}} DB
runs-on: ubuntu-latest
+ timeout-minutes: 90
env:
ORACLE_VERSION: ${{matrix.oracle-version}}
ORACLE_SID: ${{matrix.oracle-sid}}
@@ -28,42 +29,17 @@ jobs:
matrix:
include:
- id: 1
- db_version_name: '11XE'
- oracle-sid: 'XE'
- oracle-version: "gvenzl/oracle-xe:11-full"
- oracle-base: '/u01/app/oracle'
- - id: 2
- db_version_name: '12.1EE'
+ db_version_name: '19se'
oracle-sid: 'ORCLCDB'
- oracle-version: "utplsqlv3/oracledb:12c-r1-ee-small"
- oracle-base: '/opt/oracle'
-# - id: 3
-# db_version_name: '12.2se'
-# oracle-sid: 'ORCLCDB'
-# oracle-version: "utplsqlv3/oracledb:12c-r2-se2-small"
-# oracle-base: '/opt/oracle'
- - id: 4
- db_version_name: '18XE'
- oracle-sid: 'XE'
- oracle-version: "gvenzl/oracle-xe:18-slim"
- oracle-base: '/opt/oracle'
-# TODO - need to add healthcheck.sh into our containers
-# - id: 5
-# db_version_name: '19se'
-# oracle-sid: 'ORCLCDB'
-# oracle-version: "utplsqlv3/oracledb:19c-se2-small"
-# oracle-base: '/opt/oracle'
- - id: 6
+ oracle-version: "utplsqlv3/oracledb:19c-se2-small"
+ - id: 2
db_version_name: '21XE'
oracle-sid: 'XE'
- oracle-version: "gvenzl/oracle-xe:21-slim"
- oracle-base: '/opt/oracle'
- - id: 7
- db_version_name: '23free'
+ oracle-version: "gvenzl/oracle-xe:21-slim-faststart"
+ - id: 3
+ db_version_name: '23-free'
oracle-sid: 'FREEPDB1'
- oracle-version: "gvenzl/oracle-free:23-slim"
- oracle-base: '/opt/oracle'
-
+ oracle-version: "gvenzl/oracle-free:23-slim-faststart"
services:
html_checker:
image: ghcr.io/validator/validator:latest
@@ -88,13 +64,13 @@ jobs:
--health-cmd healthcheck.sh
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
- - uses: c-py/action-dotenv-to-setenv@v2
+ - uses: c-py/action-dotenv-to-setenv@v5
with:
env-file: .github/variables/.env
- - uses: FranzDiebold/github-env-vars-action@v2 #https://github.com/marketplace/actions/github-environment-variables-action
+ - uses: FranzDiebold/github-env-vars-action@v2.8.0 #https://github.com/marketplace/actions/github-environment-variables-action
- name: Set build version number env variables
id: set-build-version-number-vars
@@ -111,52 +87,68 @@ jobs:
- name: Update privileges on sources
run: chmod -R go+w ./{source,test,examples,${UTPLSQL_DIR}/source}
+ - name: Cache OJDBC jars
+ id: cache-ojdbc
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.OJDBC_HOME }}
+ key: ${{ runner.os }}-ojdbc-${{ env.OJDBC_URL }}-v1
+
- name: Add OJDBC home
+ if: steps.cache-ojdbc.outputs.cache-hit != 'true'
id: get-ojdbc
run: mkdir -p ${OJDBC_HOME} && curl -Lk -o ${OJDBC_HOME}/ojdbc8.jar ${OJDBC_URL}/ojdbc8.jar && curl -Lk -o ${OJDBC_HOME}/orai18n.jar ${OJDBC_URL}/orai18n.jar
+ - name: Cache utPLSQL-cli
+ id: cache-utplsql-cli
+ uses: actions/cache@v4
+ with:
+ path: utPLSQL-cli
+ key: ${{ runner.os }}-utplsql-cli-v3.1.8
+
- name: Install utPLSQL-cli
+ if: steps.cache-utplsql-cli.outputs.cache-hit != 'true'
id: install-utplsql-cli
- run: curl -Lk -o utPLSQL-cli.zip "https://github.com/utPLSQL/utPLSQL-cli/releases/download/v3.1.8/utPLSQL-cli.zip" && unzip utPLSQL-cli.zip && chmod -R u+x utPLSQL-cli
+ run: curl -Lk -o utPLSQL-cli.zip "https://github.com/utPLSQL/utPLSQL-cli/releases/download/3.1.9/utPLSQL-cli.zip" && unzip utPLSQL-cli.zip && chmod -R u+x utPLSQL-cli
- name: Install utPLSQL
id: install-utplsql
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/install.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/install.sh
- name: Check code style
if: ${{ matrix.id == 1 }}
id: check-coding-style
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint "$SQLCLI" ${DOCKER_ENV} ${ORACLE_VERSION} $UT3_DEVELOP_SCHEMA/$UT3_DEVELOP_SCHEMA_PASSWORD@//$CONNECTION_STR @development/utplsql_style_check.sql
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle "$SQLCLI" ${UT3_DEVELOP_SCHEMA}/${UT3_DEVELOP_SCHEMA_PASSWORD}@//${CONNECTION_STR} @/utPLSQL/development/utplsql_style_check.sql
- name: Validate utPLSQL uninstall
if: ${{ matrix.id == 1 }}
id: validate-uninstall
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/uninstall_validate_utplsql.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/uninstall_validate_utplsql.sh
- name: Reinstall utPLSQL
if: ${{ matrix.id == 1 }}
id: reinstall-utplsql
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/install.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/install.sh
- name: Create test users
id: create-test-users
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/create_test_users.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/create_test_users.sh
- name: Install utPLSQL release
id: install-utplsql-release
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/install_utplsql_release.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/install_utplsql_release.sh
- name: Run Examples
id: run-examples
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} .github/scripts/run_examples.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/run_examples.sh
- name: Install tests
id: install-tests
- run: docker run --rm -v $(pwd):/utPLSQL -w /utPLSQL --network host --entrypoint bash ${DOCKER_ENV} ${ORACLE_VERSION} test/install_tests.sh
+ run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle test/install_tests.sh
- name: Run Tests
id: run-tests
- run: bash test/run_tests.sh
+ run: test/run_tests.sh
#Start Needed to diagnose occasional failures of DB on test runs
- name: Prepare diagnostic directory
@@ -172,7 +164,7 @@ jobs:
- name: Upload ORACLE_BASE/diag data Artifact
id: upload
if: ${{ always() && steps.run-tests.outcome == 'failure' }}
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: my-artifact$-${{matrix.db_version_name}}
path: ${{github.workspace}}/database-diag
@@ -183,7 +175,7 @@ jobs:
run: bash .github/scripts/validate_report_files.sh
- name: Codecov
- uses: codecov/codecov-action@v2
+ uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
files: ./cobertura.xml
@@ -191,22 +183,22 @@ jobs:
fail_ci_if_error: true # optional (default = false)
- name: Publish unit test results
- uses: EnricoMi/publish-unit-test-result-action@v1.24
+ uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: junit_test_results.xml
- name: SonarCloud Scan
id: sonar
- if: ${{ always() && matrix.db_version_name == '21XE' }}
- uses: SonarSource/sonarcloud-github-action@master
+ if: ${{ always() && matrix.db_version_name == '23-free' }}
+ uses: SonarSource/sonarqube-scan-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.buildString=${{ format( '{0}.{1}', env.UTPLSQL_BUILD_VERSION, matrix.id ) }}
- -Dsonar.plsql.jdbc.url=${{ format( 'jdbc:oracle:thin:@//oracle:1521/{0}', env.ORACLE_SID ) }}
+ -Dsonar.plsql.jdbc.url=${{ format( 'jdbc:oracle:thin:@//localhost:1521/{0}', env.ORACLE_SID ) }}
-Dsonar.plsql.jdbc.driver.path=${{ format( '{0}/ojdbc8.jar', env.OJDBC_HOME ) }}
publish:
@@ -214,6 +206,7 @@ jobs:
needs: [ build ]
concurrency: publish
runs-on: ubuntu-latest
+ timeout-minutes: 30
env:
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
if: |
@@ -225,14 +218,14 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: echo "API_TOKEN_GITHUB=${GITHUB_TOKEN}" >> $GITHUB_ENV
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ env.API_TOKEN_GITHUB }}
- - uses: c-py/action-dotenv-to-setenv@v2
+ - uses: c-py/action-dotenv-to-setenv@v5
with:
env-file: .github/variables/.env
- - uses: FranzDiebold/github-env-vars-action@v2 #https://github.com/marketplace/actions/github-environment-variables-action
+ - uses: FranzDiebold/github-env-vars-action@v2.8.0 #https://github.com/marketplace/actions/github-environment-variables-action
- name: Set buid version number env variables
id: set-build-version-number-vars
@@ -245,7 +238,7 @@ jobs:
- name: Push version update to repository
id: push-version-number-update
run: |
- git add sonar-project.properties VERSION source/* docs/*
+ git add sonar-project.properties VERSION BUILD_NO source/* docs/*
git commit -m 'Updated project version after build [skip ci]'
git push --quiet origin HEAD:${CI_ACTION_REF_NAME}
@@ -267,6 +260,7 @@ jobs:
concurrency: trigger
needs: [ build, publish ]
runs-on: ubuntu-latest
+ timeout-minutes: 15
if: |
github.repository == 'utPLSQL/utPLSQL' && github.base_ref == null &&
( startsWith( github.ref, 'refs/heads/release/v' ) || github.ref == 'refs/heads/develop' )
@@ -276,7 +270,7 @@ jobs:
# repo: [ 'utPLSQL/utPLSQL-v2-v3-migration' ]
steps:
- name: Repository Dispatch
- uses: peter-evans/repository-dispatch@v1
+ uses: peter-evans/repository-dispatch@v4
with:
token: ${{ secrets.API_TOKEN_GITHUB }}
repository: ${{ matrix.repo }}
@@ -287,6 +281,7 @@ jobs:
name: Post Workflow Status To Slack
needs: [ build, publish, dispatch ]
runs-on: ubuntu-latest
+ timeout-minutes: 10
steps:
- name: Slack Workflow Notification
uses: Gamesight/slack-workflow-status@master
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a748d1cbd..ab043b6eb 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,18 +14,19 @@ jobs:
name: Upload archives
concurrency: upload
runs-on: ubuntu-latest
+ timeout-minutes: 60
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
- - uses: c-py/action-dotenv-to-setenv@v2
+ - uses: c-py/action-dotenv-to-setenv@v5
with:
env-file: .github/variables/.env
- - uses: FranzDiebold/github-env-vars-action@v2 #https://github.com/marketplace/actions/github-environment-variables-action
+ - uses: FranzDiebold/github-env-vars-action@v2.8.0 #https://github.com/marketplace/actions/github-environment-variables-action
- name: Set build version number env variables
- run: .github/scripts/set_version_numbers_env.sh
+ run: .github/scripts/set_release_version_numbers_env.sh
- name: Update project version & build number in source code and documentation
run: .github/scripts/update_project_version.sh
@@ -69,6 +70,7 @@ jobs:
name: Post Workflow Status To Slack
needs: [ upload_artifacts ]
runs-on: ubuntu-latest
+ timeout-minutes: 10
steps:
- name: Slack Workflow Notification
uses: Gamesight/slack-workflow-status@master
diff --git a/BUILD_NO b/BUILD_NO
new file mode 100644
index 000000000..2bfcb2370
--- /dev/null
+++ b/BUILD_NO
@@ -0,0 +1 @@
+4342
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 41a86ecdd..3cac5c86f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -40,7 +40,7 @@ Changes are welcome from all members of the Community.
# Configuring local environment
Your local environment can be of any flavor (Unix/Linux/Windows/Mac).
-At minimum you need to have Oracle database 11.2 XE accessible for the project and SYS account access to install and develop utPLSQL.
+At minimum, you need to have Oracle database 19c accessible for the project and SYS account access to install and develop utPLSQL.
We use four different database accounts (users) for development process.
* `ut3` - holds latest released version of utPLSQL. This schema holds the testing framework used for self-testing of utPLSQL development.
@@ -57,7 +57,7 @@ To get started with development, follow the below steps.
_If you're using Windows, run the shell scripts using `GIT bash` - Windows-based bash command line._
-**Caution**: If you are using jetBrains DataGrip, don't use the ingegrated console to run the shell scripts (not even with GIT bash configured). It might disconnect from oracle randomly during script-run.
+**Caution**: If you are using jetBrains DataGrip, don't use the integrated console to run the shell scripts (not even with GIT bash configured). It might disconnect from oracle randomly during script-run.
### Clone your fork of utPLSQL git repository
@@ -94,13 +94,13 @@ export ORACLE_PWD=oracle # Adjust your local SYS password
The below script is fetching latest release version from utPLSQL repository. Latest release version is used for self-testing.
```bash
-development/refresh_sources.sh
+./development/refresh_sources.sh
```
### Setup local database for utPLSQL development
```bash
-development/install.sh
+./development/install.sh
```
### That's it
@@ -135,9 +135,9 @@ Whenever a new version of utPLSQL or a new version of utPLSQL-cli is available,
utPLSQL v3 unit tests are located in the `test` directory
-Before you push any changes and create a pull request to the utPLSQL project repository, make sure that all of the tests are executing successfully in your local environment.
+Before you push any changes and create a pull request to the utPLSQL project repository, make sure that all the tests are executing successfully in your local environment.
-Every new functionality needs to be documented by unit tests that cover both happy-path scenarios as well as edge-cases and exception paths.
+Every new functionality needs to be documented by unit tests that cover happy-path scenarios as well as edge-cases and exception paths.
> **Important notice:**
> We do our best to keep utPLSQL covered with unit tests.
@@ -145,8 +145,8 @@ Every new functionality needs to be documented by unit tests that cover both hap
To run a full suite of unit tests execute:
```bash
-development/env.sh
-test/install_and_run_tests.sh
+. ./development/env.sh
+./test/install_and_run_tests.sh
```
You can review the results of tests as well as see information about code coverage in `./coverage.html` file.
@@ -162,45 +162,20 @@ Dependencies to `ut_util` are not shown as most of modules are depending on it.
## Build Environment
-We are using private docker images to test utPLSQL for our Travis CI builds. The following versions of Oracle Database are being used.
+We are using a combination of private and publicly available docker images to test utPLSQL. The following versions of Oracle Database are used for testing:
-* 11g XE R2
-* 12c SE R1
-* 12c SE R2
-* 18c SE
+* 19c-Standard Edition (private image)
+* 21-free
+* 23-free
-These images are based on the slimmed versions [official dockerfiles released by Oracle](https://github.com/utPLSQL/docker-scripts), but due to licensing restrictions, we can't make the images public.
-You can build your own and use it locally, or push to a private docker repository.
-
-The build steps are simple if you already have some experience using Docker. You can find detailed information about how to build your own image with a running database in: [example of creating an image with pre-built DB](https://github.com/oracle/docker-images/blob/master/OracleDatabase/samples/prebuiltdb/README.md)
-
-> You can find more info about the official Oracle images on the [Oracle Database on Docker](https://github.com/oracle/docker-images/tree/master/OracleDatabase) GitHub page.
-
-> If you are new to Docker, you can start by reading the [Getting Started With Docker](https://docs.docker.com/engine/getstarted/) docs.
-
-### Docker Build Notes
-
-* You need to comment out the VOLUME line. This step is required, because volumes are not saved when using `docker commit` command.
-* When the build process is complete, you will run the container to install the database. Once everything is set up and you see the message "DATABASE IS READY!", you may change the password and stop the running container. After the container is stopped, you can safely commit the container.
-* You can use the --squash experimental docker tag to reduce the image size. Example:
-```
-docker build --force-rm --no-cache --squash -t oracle/db-prebuilt .
-```
-
-Travis will use your Docker Hub credentials to pull the private images, and the following secure environment variables must be defined.
-
-Variable | Description
----------|------------
-**DOCKER_USER**
**DOCKER_PASSWORD** | _Your Docker Hub website credentials. They will be used to pull the private database images._
+The Free varsions are publicly available and you can set up your local development environment to use one of from [here](https://github.com/gvenzl/oci-oracle-free)
-### SQLCL
+These [private image]((https://github.com/utPLSQL/docker-scripts) is a slimmed version of [the official Oracle database dockerfiles](https://github.com/oracle/docker-images/tree/master/OracleDatabase) . Due to licensing restrictions, the image cannot be public.
-Our build configuration uses SQLCL to run the scripts, and you need to configure a few additional secure environment variables. After the first build, the downloaded file will be cached.
-
-Variable | Description
----------|------------
-**ORACLE_OTN_USER
ORACLE_OTN_PASSWORD** | _Your Oracle website credentials. They will be used to download SQLCL._
+You can build your own and use it locally, or push to a private docker repository.
+The build steps are simple if you already have some experience using Docker. You can find detailed information about how to build your own image with a running database in: [example of creating an image with pre-built DB](https://github.com/oracle/docker-images/blob/master/OracleDatabase/samples/prebuiltdb/README.md)
+> If you are new to Docker, you can start by reading the [Getting Started With Docker](https://docs.docker.com/get-started/) docs.
## New to GIT
diff --git a/development/releasing.md b/development/releasing.md
index 2b9be317a..ac2091632 100644
--- a/development/releasing.md
+++ b/development/releasing.md
@@ -3,28 +3,25 @@
To create a release follow the below steps
## Release preparation
- - Create a **draft** of a Release with version number `vX.Y.X` sourced from the `main` branch using [github releases page](https://github.com/utPLSQL/utPLSQL/releases) and populate release description using information found on the issues and pull requests **since previous release**.
- To find issues closed after certain date use [advanced filters](https://help.github.com/articles/searching-issues-and-pull-requests/#search-by-open-or-closed-state).
- Example: [`is:issue closed:>2018-07-22`](https://github.com/utPLSQL/utPLSQL/issues?utf8=%E2%9C%93&q=is%3Aissue+closed%3A%3E2018-07-22+)
+ - Create a **draft** of a Release with a new tag number `vX.Y.X` sourced from the `develop` branch on [github releases page](https://github.com/utPLSQL/utPLSQL/releases)
+ - Populate release description using the `Generate release notes` button
+ - Review the auto-generated release notes and update tem if needed
+ - Optionally, split the default `## What's Changed` list into `## New features`, `## Enhancements`, `## Bug fixes`. See previous release notes for details
## Performing a release
- - create the release branch from `develop` branch and make sure to name the release branch: `release/vX.Y.Z`
- - update, commit and push at least one file change in the release branch, to kick off a build on [GithubActions](https://github.com/utPLSQL/utPLSQL/actions) or kick-off a build manually for that branch after it was created on github.
- - wait for the build to complete successfully as it will update the version to be release number (without develop)
- - merge the release branch to `main` branch and publish [the previously prepared](#release-preparation) release draft.
+ - Publish [the previously prepared](#release-preparation) release draft.
- Wait for the [Github Actions `Release`](https://github.com/utPLSQL/utPLSQL/actions/workflows/release.yml) process to complete successfully. The process will upload release artifacts (`zip` and `tar.gz` files along with `md5`)
- - After Release build was completed successfully, merge the `main` branch back into `develop` branch. At this point, main branch and release tag should be at the same commit version and artifacts should be uploaded into Github release.
- - After develop branch was built, increase the version number in `VERSION` file to represent next planned release version.
+ - After Release build was completed successfully, merge the `develop` branch into `main` branch. At this point, main branch and release tag should be at the same commit version and artifacts should be uploaded into Github release.
+ - Increase the version number in the `VERSION` file on `develop` branch to open start next release version.
- Clone `utplsql.githug.io` project and:
- Add a new announcement about next version being released in `docs/_posts`. Use previous announcements as a template. Make sure to set date, time and post title properly.
- Add the post to list in `mkdocs.yml` file in root directory of that repository.
- Add the link to the post at the beginning of the `docs/index.md` file.
+ - Send the announcement on Twitter(X) accoiunt abut utPLSQL release.
The following will happen:
- - build executed on branch `release/vX.Y.Z-[something]` updates files `sonar-project.properties`, `VERSION` with project version derived from the release branch name
- - changes to those two files are committed and pushed back to release branch
- - when a Github release is published, a new tag is added in on the repository and a release build is executed
- - With Release build, the documentation for new release is published on `utplsql.github.io` and installation archives are added to the release.
+ - When a Github release is published, a new tag is added in on the repository and a release build is executed
+ - With Release action, the documentation for new release is published on `utplsql.github.io` and installation archives are added to the release.
# Note:
The utPLSQL installation files are uploaded by the release build process as release artifacts (separate `zip` and `tar.gz` files).
diff --git a/development/template.env.sh b/development/template.env.sh
index 7761a70c4..fdbed4b6b 100755
--- a/development/template.env.sh
+++ b/development/template.env.sh
@@ -1,10 +1,10 @@
#!/bin/bash
-export SQLCLI=sql # For sqlcl client
-#export SQLCLI=sqlplus # For sqlplus client
-export CONNECTION_STR=127.0.0.1:1521/xe ORACLE_VERSION=11g-r2-xe# Adjust the connect string
-export ORACLE_PWD=oracle # Adjust your local SYS password
-export UTPLSQL_CLI_VERSION="3.1.6"
+export SQLCLI=sql # For sqlcl client
+#export SQLCLI=sqlplus # For sqlplus client
+export CONNECTION_STR=127.0.0.1:1521/xe # Adjust the connect string
+export ORACLE_PWD=oracle # Adjust your local SYS password
+export UTPLSQL_CLI_VERSION="v3.1.8"
export SELFTESTING_BRANCH=develop
export UTPLSQL_DIR="utPLSQL_latest_release"
diff --git a/docs/about/authors.md b/docs/about/authors.md
index c4c40bfad..2c2abf826 100644
--- a/docs/about/authors.md
+++ b/docs/about/authors.md
@@ -1,4 +1,4 @@
-
+
### utPLSQL v3 Major Contributors
@@ -20,7 +20,7 @@ Many thanks to all the [contributors](https://github.com/utPLSQL/utPLSQL/graphs/
### Special thanks to prior major contributors
-- Steven Feuerstein - Original Author
+- Steven Feuerstein - Original Author of utPLSQL v1 and v2
- Chris Rimmer
- Patrick Barel
- Paul Walker
diff --git a/docs/about/license.md b/docs/about/license.md
index 702ea3f9c..0485779e5 100644
--- a/docs/about/license.md
+++ b/docs/about/license.md
@@ -1,4 +1,4 @@
-
+
# Version Information
diff --git a/docs/about/project-details.md b/docs/about/project-details.md
index 60aa6a657..81e4f976e 100644
--- a/docs/about/project-details.md
+++ b/docs/about/project-details.md
@@ -1,10 +1,10 @@
-
+
# utPLSQL Project Details
[](https://github.com/utPLSQL/utPLSQL)
[](https://www.apache.org/licenses/LICENSE-2.0)
-[](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww)
+[](https://github.com/utPLSQL/utPLSQL/discussions)
[](https://twitter.com/utPLSQL)
diff --git a/docs/about/support.md b/docs/about/support.md
index fc412205d..4ac661e10 100644
--- a/docs/about/support.md
+++ b/docs/about/support.md
@@ -1,6 +1,7 @@
-
+
# How to get support
-- Feel free to post questions, bugs or issues in the [issues area of GitHub](https://github.com/utPLSQL/utPLSQL/issues)
-- [Join](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww) developers team on [utPLSQL Slack](https://utplsql.slack.com/)
+- Look into [utPLSQL github discussions](https://github.com/utPLSQL/utPLSQL/discussions) to find support, ask questions and share ideas
+- If needed open a new [issue on github](https://github.com/utPLSQL/utPLSQL/issues) for bugs or feature requests
+
diff --git a/docs/images/tap_reporter_colored.png b/docs/images/tap_reporter_colored.png
new file mode 100644
index 000000000..d4a5e9326
Binary files /dev/null and b/docs/images/tap_reporter_colored.png differ
diff --git a/docs/images/tap_reporter_no_color.png b/docs/images/tap_reporter_no_color.png
new file mode 100644
index 000000000..e7379a889
Binary files /dev/null and b/docs/images/tap_reporter_no_color.png differ
diff --git a/docs/images/tap_reporter_suitepath.png b/docs/images/tap_reporter_suitepath.png
new file mode 100644
index 000000000..488c7cfbf
Binary files /dev/null and b/docs/images/tap_reporter_suitepath.png differ
diff --git a/docs/index.md b/docs/index.md
index 8325ec636..459bc9535 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,4 +1,4 @@
-
+
## What is utPLSQL
diff --git a/docs/userguide/advanced_data_comparison.md b/docs/userguide/advanced_data_comparison.md
index 1f7f2d191..c0cbffb0e 100644
--- a/docs/userguide/advanced_data_comparison.md
+++ b/docs/userguide/advanced_data_comparison.md
@@ -1,4 +1,4 @@
-
+
# Advanced data comparison
diff --git a/docs/userguide/annotations.md b/docs/userguide/annotations.md
index d1ff5da07..3dc42e429 100644
--- a/docs/userguide/annotations.md
+++ b/docs/userguide/annotations.md
@@ -1,4 +1,4 @@
-
+
Annotations are used to configure tests and suites in a declarative way similar to modern OOP languages. This way, test configuration is stored along with the test logic inside the test package.
No additional configuration files or tables are needed for test cases. The annotation names are based on popular testing frameworks such as JUnit.
diff --git a/docs/userguide/best-practices.md b/docs/userguide/best-practices.md
index 57a108fdd..45be3be59 100644
--- a/docs/userguide/best-practices.md
+++ b/docs/userguide/best-practices.md
@@ -1,4 +1,4 @@
-
+
The following are best practices we at utPLSQL have learned about PL/SQL and Unit Testing.
diff --git a/docs/userguide/coverage.md b/docs/userguide/coverage.md
index 5d071335e..adf36baa6 100644
--- a/docs/userguide/coverage.md
+++ b/docs/userguide/coverage.md
@@ -1,4 +1,4 @@
-
+
utPLSQL comes with a built-in coverage reporting engine. The code coverage reporting uses package DBMS_PROFILER (and DBMS_PLSQL_CODE_COVERAGE on Oracle database version 12.2 and above) provided with Oracle database.
Code coverage is gathered for the following source types:
diff --git a/docs/userguide/exception-reporting.md b/docs/userguide/exception-reporting.md
index ca52ac951..e042d61ed 100644
--- a/docs/userguide/exception-reporting.md
+++ b/docs/userguide/exception-reporting.md
@@ -1,4 +1,4 @@
-
+
utPLSQL is responsible for handling exceptions wherever they occur in the test run. The framework is trapping most of the exceptions so that the test execution is not affected by individual tests or test packages throwing an exception.
The framework provides a full stacktrace for every exception that was thrown. The reported stacktrace does not include any utPLSQL library calls in it.
diff --git a/docs/userguide/expectations.md b/docs/userguide/expectations.md
index b6f3d7e29..0ea5e2e73 100644
--- a/docs/userguide/expectations.md
+++ b/docs/userguide/expectations.md
@@ -1,4 +1,4 @@
-
+
## Expectation concepts
@@ -52,7 +52,7 @@ Shortcut syntax, where matcher is directly part of expectation:
ut.expect( a_actual ).not_to_{matcher};
--example
- ut.expect( 1 ).to_( be_null() );
+ ut.expect( 1 ).to_be_null();
```
When using shortcut syntax you don't need to surround matcher with brackets. Shortcut syntax is provided for convenience.
diff --git a/docs/userguide/getting-started.md b/docs/userguide/getting-started.md
index 9620878ad..cd4feb46a 100644
--- a/docs/userguide/getting-started.md
+++ b/docs/userguide/getting-started.md
@@ -1,4 +1,4 @@
-
+
# Getting started with TDD and utPLSQL
diff --git a/docs/userguide/install.md b/docs/userguide/install.md
index 8f32c5a10..6724ac6ab 100644
--- a/docs/userguide/install.md
+++ b/docs/userguide/install.md
@@ -1,4 +1,4 @@
-
+
## Supported database versions
diff --git a/docs/userguide/querying_suites.md b/docs/userguide/querying_suites.md
index e3ec1f53d..0cdc2d7fa 100644
--- a/docs/userguide/querying_suites.md
+++ b/docs/userguide/querying_suites.md
@@ -1,4 +1,4 @@
-
+
## Obtaining information about suites
diff --git a/docs/userguide/reporters.md b/docs/userguide/reporters.md
index e37ac6627..b417ba25c 100644
--- a/docs/userguide/reporters.md
+++ b/docs/userguide/reporters.md
@@ -1,4 +1,4 @@
-
+
utPLSQL provides several reporting formats. The sections below describe most of them.
@@ -126,6 +126,20 @@ Details:
utPLSQL comes with a set of build-in coverage reporters.
[Code coverage](coverage.md) section describes in details how to use configure and use code coverage.
+## TAP Reporter
+
+The `ut_tap_reporter` produces output compatible with the [Test Anything Protocol](https://testanything.org) (Version 14). TAP output can be consumed by a TAP consumer that can aggregate results from testsuites across different programming languages while maintaining good readability for humans.
+
+
+
+If you use a compatible terminal, you can also have a colored result. Only top level `not ok`-results will be colored:
+
+
+
+Suites (and suitepaths) and contexts are included as [commented subtests](https://testanything.org/tap-version-14-specification.html#:~:text=Commented%20Subtests) including a summary of the tests performed for that specific context/suite. This example package has the suitepath "org.utplsql.tests.helpers":
+
+
+
## Debug reporter
The `ut_debug_reporter` provides a highly verbose output containing thorough details about framework and test execution.
@@ -175,6 +189,16 @@ If you need to produce a colored text output from the custom reporter, then you
It is recommended to create the reporter type in the schema where utPLSQL is installed (by default it is the `UT3` schema). Note that before running the utPLSQL uninstall scripts, all custom reporters should be dropped (cf. [the installation documentation](install.md)). In particular, when upgrading to a newer version of utPLSQL, one has to drop the custom reporters and recreate them after the upgrade.
+!!! note
+ Please make sure that grants have been added and synonyms created for the custom reporter in order for reporter to be accessible the same way as other reporters.
+ Assuming that reporter with name `customer_reporter` was created in schema `UT3`
+```sql
+ grant execute on ut3.custom_reporter to public;
+ create or replace public synonym custom_reporter for ut3.custom_reporter;
+```
+
+
+
!!! note
It is possible, but cumbersome, to use another schema for storing the custom reporters. This requires to create a synonym for the base reporter type in the schema that is going to own the custom reporter, and to provide appropriate grants both to the owner of the custom reporter and to the user running the reporter. After upgrading or reinstalling utPLSQL, the extra privileges need to be recreated. This approach is not recommended.
diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md
index 3b23f5f98..28e02d5b8 100644
--- a/docs/userguide/running-unit-tests.md
+++ b/docs/userguide/running-unit-tests.md
@@ -1,4 +1,4 @@
-
+
utPLSQL framework provides two main entry points to run unit tests from within the database:
diff --git a/docs/userguide/upgrade.md b/docs/userguide/upgrade.md
index e5537f520..818a592bc 100644
--- a/docs/userguide/upgrade.md
+++ b/docs/userguide/upgrade.md
@@ -1,4 +1,4 @@
-
+
# Upgrading from version 2
diff --git a/examples/RunAllExamples.sql b/examples/RunAllExamples.sql
index faa3388cf..f5f42b7f3 100644
--- a/examples/RunAllExamples.sql
+++ b/examples/RunAllExamples.sql
@@ -3,22 +3,8 @@ set echo on
set feedback on
set linesize 1000
-declare
- l_run_number binary_integer;
-begin
- dbms_profiler.start_profiler( run_number => l_run_number);
-end;
-/
-
-- Examples for users
@@RunUserExamples.sql
-- Framework developer examples
@@RunDeveloperExamples.sql
-
-declare
- l_return_code binary_integer;
-begin
- l_return_code := dbms_profiler.stop_profiler();
-end;
-/
diff --git a/mkdocs.yml b/mkdocs.yml
index 713722620..49356fd4e 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,7 +8,7 @@ edit_uri: ""
site_url: http://utPLSQL.org/
site_name: utPLSQL-framework
site_description: utPLSQL Ultimate Testing Framework for Oracle PL/SQL & SQL
-copyright: Copyright © 2016 - 2022 utPLSQL Team
+copyright: Copyright © 2016 - 2026 utPLSQL Team
repo_url: https://github.com/utPLSQL/utPLSQL
extra_css:
- stylesheets/extra.css
@@ -44,8 +44,8 @@ extra:
social:
- icon: fontawesome/brands/twitter
link: https://twitter.com/utPLSQL
- - icon: fontawesome/brands/slack
- link: https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww
+ - icon: fontawesome/regular/comment
+ link: https://github.com/utPLSQL/utPLSQL/discussions
- icon: fontawesome/brands/github
link: https://github.com/utPLSQL
- icon: fontawesome/solid/envelope
diff --git a/mkdocs_offline.yml b/mkdocs_offline.yml
index 31c90615e..9f0ef57af 100644
--- a/mkdocs_offline.yml
+++ b/mkdocs_offline.yml
@@ -44,8 +44,8 @@ extra:
social:
- icon: fontawesome/brands/twitter
link: https://twitter.com/utPLSQL
- - icon: fontawesome/brands/slack
- link: https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww
+ - icon: fontawesome/regular/comment
+ link: https://github.com/utPLSQL/utPLSQL/discussions
- icon: fontawesome/brands/github
link: https://github.com/utPLSQL
- icon: fontawesome/solid/envelope
diff --git a/readme.md b/readme.md
index 141c68ffe..1ca252558 100644
--- a/readme.md
+++ b/readme.md
@@ -5,12 +5,12 @@
[](https://www.apache.org/licenses/LICENSE-2.0)
[](https://github.com/utPLSQL/utPLSQL/releases)
[](http://gra.caldis.me/?url=https://github.com/utPLSQL/utPLSQL)
-[](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww)
+[](https://github.com/utPLSQL/utPLSQL/discussions)
[](https://twitter.com/utPLSQL)
[](https://github.com/utPLSQL/utPLSQL/actions/workflows/build.yml)
-[](https://sonarcloud.io/summary/new_code?id=utPLSQL)
-[](https://sonarcloud.io/summary/new_code?id=utPLSQL)
+[](https://sonarcloud.io/summary/new_code?id=utPLSQL_utPLSQL)
+[](https://sonarcloud.io/summary/new_code?id=utPLSQL_utPLSQL)
----------
utPLSQL version 3 is a complete rewrite of utPLSQL v2 from scratch.
@@ -161,8 +161,7 @@ Finished in .036027 seconds
We welcome new developers to join our community and contribute to the utPLSQL project.
If you are interested in helping please read our [guide to contributing](CONTRIBUTING.md)
The best place to start is to read the documentation and get familiar with the existing code base.
-A [slack chat](https://utplsql.slack.com/) is the place to go if you want to talk with team members.
-To sign up to the chat use [this link](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww).
+[Github discussions](https://github.com/utPLSQL/utPLSQL/discussions) is the place to go if you want to talk with team members.
----------
@@ -183,8 +182,6 @@ __Project Directories__
----------
-If you have a great feature in mind, that you would like to see in utPLSQL v3 please create an [issue on GitHub](https://github.com/utPLSQL/utPLSQL/issues) or discuss it with us in the [slack chat rooms](https://utplsql.slack.com/). Use [invite link](https://join.slack.com/t/utplsql/shared_invite/zt-xwm68udy-4cF_3PNEyczYEbWr38W5ww) to join the chat.
-
# Version 2 to Version 3 Comparison
diff --git a/sonar-project.properties b/sonar-project.properties
index d088e9ccb..f23e8cf71 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -1,6 +1,6 @@
# must be unique in a given SonarQube instance
sonar.organization=utplsql
-sonar.projectKey=utPLSQL
+sonar.projectKey=utPLSQL_utPLSQL
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=utPLSQL
sonar.projectVersion=v3.1.14-develop
diff --git a/source/core/types/ut_reporter_base.tpb b/source/core/types/ut_reporter_base.tpb
index 3f8984331..017dc8971 100644
--- a/source/core/types/ut_reporter_base.tpb
+++ b/source/core/types/ut_reporter_base.tpb
@@ -165,52 +165,54 @@ create or replace type body ut_reporter_base is
end;
overriding member procedure on_event( self in out nocopy ut_reporter_base, a_event_name varchar2, a_event_item ut_event_item) is
+ /* Resolves issue with ORA-21779 being thrown see issue: 1309 -> ( https://github.com/utPLSQL/utPLSQL/issues/1309#issuecomment-4020289898 ) */
+ l_event_item ut_event_item := a_event_item;
begin
case a_event_name
when ut_event_manager.gc_initialize
- then self.on_initialize(treat(a_event_item as ut_run));
+ then self.on_initialize(treat(l_event_item as ut_run));
when ut_event_manager.gc_before_run
- then self.before_calling_run(treat(a_event_item as ut_run));
+ then self.before_calling_run(treat(l_event_item as ut_run));
when ut_event_manager.gc_before_suite
- then self.before_calling_suite(treat(a_event_item as ut_logical_suite));
+ then self.before_calling_suite(treat(l_event_item as ut_logical_suite));
when ut_event_manager.gc_before_before_all
- then self.before_calling_before_all(treat(a_event_item as ut_executable));
+ then self.before_calling_before_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_before_each
- then self.before_calling_before_each(treat(a_event_item as ut_executable));
+ then self.before_calling_before_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_test
- then self.before_calling_test(treat(a_event_item as ut_test));
+ then self.before_calling_test(treat(l_event_item as ut_test));
when ut_event_manager.gc_before_before_test
- then self.before_calling_before_test(treat(a_event_item as ut_executable));
+ then self.before_calling_before_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_test_execute
- then self.before_calling_test_execute(treat(a_event_item as ut_executable));
+ then self.before_calling_test_execute(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_test
- then self.before_calling_after_test(treat(a_event_item as ut_executable));
+ then self.before_calling_after_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_each
- then self.before_calling_after_each(treat(a_event_item as ut_executable));
+ then self.before_calling_after_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_before_after_all
- then self.before_calling_after_all(treat(a_event_item as ut_executable));
+ then self.before_calling_after_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_run
- then self.after_calling_run(treat(a_event_item as ut_run));
+ then self.after_calling_run(treat(l_event_item as ut_run));
when ut_event_manager.gc_after_suite
- then self.after_calling_suite(treat(a_event_item as ut_logical_suite));
+ then self.after_calling_suite(treat(l_event_item as ut_logical_suite));
when ut_event_manager.gc_after_before_all
- then self.after_calling_before_all(treat(a_event_item as ut_executable));
+ then self.after_calling_before_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_before_each
- then self.after_calling_before_each(treat(a_event_item as ut_executable));
+ then self.after_calling_before_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_test
- then self.after_calling_test(treat(a_event_item as ut_test));
+ then self.after_calling_test(treat(l_event_item as ut_test));
when ut_event_manager.gc_after_before_test
- then self.after_calling_before_test(treat(a_event_item as ut_executable));
+ then self.after_calling_before_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_test_execute
- then self.after_calling_test_execute(treat(a_event_item as ut_executable));
+ then self.after_calling_test_execute(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_test
- then self.after_calling_after_test(treat(a_event_item as ut_executable));
+ then self.after_calling_after_test(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_each
- then self.after_calling_after_each(treat(a_event_item as ut_executable));
+ then self.after_calling_after_each(treat(l_event_item as ut_executable));
when ut_event_manager.gc_after_after_all
- then self.after_calling_after_all(treat(a_event_item as ut_executable));
+ then self.after_calling_after_all(treat(l_event_item as ut_executable));
when ut_event_manager.gc_finalize
- then self.on_finalize(treat(a_event_item as ut_run));
+ then self.on_finalize(treat(l_event_item as ut_run));
else null;
end case;
end;
diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb
index 6d621c339..e5fdae7ac 100644
--- a/source/core/ut_suite_cache_manager.pkb
+++ b/source/core/ut_suite_cache_manager.pkb
@@ -306,7 +306,7 @@ create or replace package body ut_suite_cache_manager is
l_object_owner varchar2(250) := upper(a_object_owner);
l_object_name varchar2(250) := upper(a_object_name);
begin
- if a_suite_items is not null and a_suite_items.count = 0 then
+ if a_suite_items is null or a_suite_items.count = 0 then
delete from ut_suite_cache t
where t.object_owner = l_object_owner
diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks
index 522da1480..9615c7b4d 100644
--- a/source/core/ut_utils.pks
+++ b/source/core/ut_utils.pks
@@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is
*
*/
- gc_version constant varchar2(50) := 'v3.1.14.4187-develop';
+ gc_version constant varchar2(50) := 'v3.1.14.4342-develop';
subtype t_executable_type is varchar2(30);
gc_before_all constant t_executable_type := 'beforeall';
diff --git a/source/create_grants.sql b/source/create_grants.sql
index 0e9f46cc5..2cdea9970 100644
--- a/source/create_grants.sql
+++ b/source/create_grants.sql
@@ -104,6 +104,7 @@ grant execute on &&ut3_owner..ut_tfs_junit_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_documentation_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_sonar_test_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_realtime_reporter to &ut3_user;
+grant execute on &&ut3_owner..ut_tap_reporter to &ut3_user;
--reporters - coverage
grant execute on &&ut3_owner..ut_coverage_html_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_coverage_sonar_reporter to &ut3_user;
diff --git a/source/create_synonyms.sql b/source/create_synonyms.sql
index fa1c1dc45..d839e11b7 100644
--- a/source/create_synonyms.sql
+++ b/source/create_synonyms.sql
@@ -119,6 +119,7 @@ create &action_type. synonym &ut3_user.ut_tfs_junit_reporter for &&ut3_owner..ut
create &action_type. synonym &ut3_user.ut_documentation_reporter for &&ut3_owner..ut_documentation_reporter;
create &action_type. synonym &ut3_user.ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter;
create &action_type. synonym &ut3_user.ut_realtime_reporter for &&ut3_owner..ut_realtime_reporter;
+create &action_type. synonym &ut3_user.ut_tap_reporter for &&ut3_owner..ut_tap_reporter;
--reporters - coverage
create &action_type. synonym &ut3_user.ut_coverage_html_reporter for &&ut3_owner..ut_coverage_html_reporter;
create &action_type. synonym &ut3_user.ut_coverage_sonar_reporter for &&ut3_owner..ut_coverage_sonar_reporter;
diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb
index 4517cd43c..875ec760a 100644
--- a/source/expectations/data_values/ut_compound_data_helper.pkb
+++ b/source/expectations/data_values/ut_compound_data_helper.pkb
@@ -300,8 +300,8 @@ create or replace package body ut_compound_data_helper is
ut_utils.append_to_clob(a_partition_stmt,' row_number() over (partition by '||l_partition_tmp||' order by '||l_partition_tmp||' ) ');
if a_pk_table.count > 0 then
- -- If key defined do the join or these and where on diffrences
- a_join_by_stmt := ut_utils.table_to_clob(l_join_by_list, ' and ');
+ -- If key defined do the join or these and where on diffrences as well as on duplicate number when rows are same.
+ a_join_by_stmt := ' e."UT3$_Dup#No" = a."UT3$_Dup#No" and '||ut_utils.table_to_clob(l_join_by_list, ' and ');
elsif a_unordered then
-- If no key defined do the join on all columns
a_join_by_stmt := ' e."UT3$_Dup#No" = a."UT3$_Dup#No" and '||ut_utils.table_to_clob(l_equal_list, ' and ');
diff --git a/source/install.sql b/source/install.sql
index 827213e6c..22ce75365 100644
--- a/source/install.sql
+++ b/source/install.sql
@@ -346,6 +346,8 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
@@install_component.sql 'reporters/ut_xunit_reporter.tpb'
@@install_component.sql 'reporters/ut_sonar_test_reporter.tps'
@@install_component.sql 'reporters/ut_sonar_test_reporter.tpb'
+@@install_component.sql 'reporters/ut_tap_reporter.tps'
+@@install_component.sql 'reporters/ut_tap_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_html_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_report_html_helper.pks'
diff --git a/source/reporters/ut_tap_reporter.tpb b/source/reporters/ut_tap_reporter.tpb
new file mode 100644
index 000000000..ff095a369
--- /dev/null
+++ b/source/reporters/ut_tap_reporter.tpb
@@ -0,0 +1,124 @@
+create or replace type body ut_tap_reporter is
+
+
+ constructor function ut_tap_reporter(self in out nocopy ut_tap_reporter) return self as result is
+ begin
+ self.init($$plsql_unit);
+ self.lvl := 0;
+ return;
+ end ut_tap_reporter;
+
+ member procedure print_comment(self in out nocopy ut_tap_reporter, a_comment clob) as
+ begin
+ self.print_clob(regexp_replace(a_comment, '^', '# ', 1, 0, 'm'));
+ end print_comment;
+
+ member function escape_special_chars(self in out nocopy ut_tap_reporter, a_string_to_escape clob) return clob as
+ begin
+ return regexp_replace(a_string_to_escape, '([\\#])', '\\\1');
+ end escape_special_chars;
+
+ overriding member procedure before_calling_suite(self in out nocopy ut_tap_reporter, a_suite ut_logical_suite) as
+ begin
+ self.print_text('# Subtest: ' || self.escape_special_chars(coalesce(a_suite.description, a_suite.name)));
+ lvl := lvl + 2;
+ self.print_text('1..' || a_suite.items.count);
+ end before_calling_suite;
+
+
+ overriding member procedure after_calling_test(self in out nocopy ut_tap_reporter, a_test ut_test) as
+ l_message varchar2(4000);
+ l_test_name varchar2(4000) := self.escape_special_chars(coalesce(a_test.description, a_test.name));
+
+ procedure print_failed_expectation(a_test ut_test) is
+ l_lines ut_varchar2_list;
+ l_failed boolean;
+ begin
+ if a_test.get_error_stack_traces().count = 0 then
+ -- If no error occurred, print failed expectation
+ l_lines := a_test.all_expectations(a_test.all_expectations.last).get_result_lines();
+ l_failed := a_test.all_expectations(a_test.all_expectations.last).status >= ut_utils.gc_success;
+ if l_failed then
+ self.print_text('message: ''' || l_lines(1) || '''');
+ self.print_text('severity: fail');
+ end if;
+ else
+ -- Print multi-line YAML-String with implicit newline characters
+ self.print_text('message: |');
+ self.lvl := self.lvl + 1;
+ self.print_text(ut_utils.table_to_clob(a_test.get_error_stack_traces()));
+ self.lvl := self.lvl - 1;
+ self.print_text('severity: error');
+ end if;
+ end print_failed_expectation;
+
+ begin
+
+ if a_test.result = ut_utils.gc_disabled then
+ self.print_text('ok - ' || l_test_name || ' # SKIP'||
+ case when a_test.disabled_reason is not null
+ then ': '|| self.escape_special_chars(a_test.disabled_reason)
+ else null
+ end );
+ elsif a_test.result = ut_utils.gc_success then
+ self.print_text('ok - ' || l_test_name);
+ elsif a_test.result > ut_utils.gc_success then
+ if self.lvl = 0 then
+ self.print_text(ut_ansiconsole_helper.red('not ok') || ' - ' || l_test_name);
+ else
+ self.print_text('not ok - ' || l_test_name);
+ end if;
+ self.lvl := self.lvl + 1;
+ self.print_text('---');
+ print_failed_expectation(a_test);
+ self.print_text('...');
+ self.lvl := self.lvl - 1;
+ end if;
+
+ self.print_comment(a_test.get_serveroutputs);
+
+ end after_calling_test;
+
+ overriding member procedure after_calling_before_all(self in out nocopy ut_tap_reporter, a_executable in ut_executable) is
+ begin
+ if a_executable.serveroutput is not null and a_executable.serveroutput != empty_clob() then
+ self.print_comment(a_executable.serveroutput);
+ end if;
+ end after_calling_before_all;
+
+ overriding member procedure after_calling_after_all(self in out nocopy ut_tap_reporter, a_executable in ut_executable) is
+ begin
+ if a_executable.serveroutput is not null and a_executable.serveroutput != empty_clob() then
+ self.print_comment(a_executable.serveroutput);
+ end if;
+ end after_calling_after_all;
+
+ overriding member procedure after_calling_suite(self in out nocopy ut_tap_reporter, a_suite ut_logical_suite) as
+ l_suite_name varchar2(4000) := coalesce(a_suite.description, a_suite.name);
+ begin
+ lvl := lvl - 2;
+ if lvl = 0 then
+ if a_suite.result = ut_utils.gc_success or a_suite.result = ut_utils.gc_disabled then
+ self.print_text('ok - ' || self.escape_special_chars(l_suite_name));
+ elsif a_suite.result > ut_utils.gc_success then
+ self.print_text(ut_ansiconsole_helper.red('not ok') || ' - ' || self.escape_special_chars(l_suite_name));
+ end if;
+
+ self.print_text(' ');
+ end if;
+
+ end after_calling_suite;
+
+ overriding member procedure before_calling_run(self in out nocopy ut_tap_reporter, a_run in ut_run) as
+ begin
+ self.print_text('TAP version 14');
+ self.print_text('1..' || a_run.items.count);
+ self.print_text(' ');
+ end before_calling_run;
+
+ overriding member procedure after_calling_run(self in out nocopy ut_tap_reporter, a_run in ut_run) as
+ begin
+ self.lvl := 0;
+ end;
+end;
+/
diff --git a/source/reporters/ut_tap_reporter.tps b/source/reporters/ut_tap_reporter.tps
new file mode 100644
index 000000000..bed809059
--- /dev/null
+++ b/source/reporters/ut_tap_reporter.tps
@@ -0,0 +1,18 @@
+create or replace type ut_tap_reporter under ut_documentation_reporter(
+
+ constructor function ut_tap_reporter(self in out nocopy ut_tap_reporter) return self as result,
+ member procedure print_comment(self in out nocopy ut_tap_reporter, a_comment clob),
+ member function escape_special_chars(self in out nocopy ut_tap_reporter, a_string_to_escape clob) return clob,
+ overriding member procedure before_calling_suite(self in out nocopy ut_tap_reporter, a_suite ut_logical_suite),
+
+ overriding member procedure after_calling_test(self in out nocopy ut_tap_reporter, a_test ut_test),
+
+ overriding member procedure after_calling_before_all (self in out nocopy ut_tap_reporter, a_executable in ut_executable),
+ overriding member procedure after_calling_after_all (self in out nocopy ut_tap_reporter, a_executable in ut_executable),
+ overriding member procedure before_calling_run(self in out nocopy ut_tap_reporter, a_run in ut_run),
+ overriding member procedure after_calling_suite(self in out nocopy ut_tap_reporter, a_suite ut_logical_suite),
+ overriding member procedure after_calling_run(self in out nocopy ut_tap_reporter, a_run in ut_run)
+
+)
+not final
+/
diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh
index 04f51fb3c..1719f137a 100755
--- a/test/install_and_run_tests.sh
+++ b/test/install_and_run_tests.sh
@@ -1,9 +1,11 @@
#!/bin/bash
set -ev
+. ./development/env.sh
+
#goto git root directory
git rev-parse && cd "$(git rev-parse --show-cdup)"
cd test
-time . ./${DIR}/install_tests.sh
-time . ./${DIR}/run_tests.sh
+time . ./install_tests.sh
+time . ./run_tests.sh
diff --git a/test/install_ut3_user_tests.sql b/test/install_ut3_user_tests.sql
index ad7f014bc..518e07841 100644
--- a/test/install_ut3_user_tests.sql
+++ b/test/install_ut3_user_tests.sql
@@ -43,6 +43,7 @@ set define off
@@ut3_user/reporters/test_documentation_reporter.pks
@@ut3_user/reporters/test_debug_reporter.pks
@@ut3_user/reporters/test_realtime_reporter.pks
+@@ut3_user/reporters/test_tap_reporter.pks
@@ut3_user/reporters/test_coverage.pks
@@ut3_user/reporters/test_coverage/test_coverage_standalone.pks
set define on
@@ -86,6 +87,7 @@ set define off
@@ut3_user/reporters/test_documentation_reporter.pkb
@@ut3_user/reporters/test_debug_reporter.pkb
@@ut3_user/reporters/test_realtime_reporter.pkb
+@@ut3_user/reporters/test_tap_reporter.pkb
@@ut3_user/reporters/test_coverage/test_coverage_standalone.pkb
set define on
@@ut3_user/reporters/test_coverage/test_extended_coverage.pkb
diff --git a/test/run_tests.sh b/test/run_tests.sh
index 118bab920..7d0431aec 100755
--- a/test/run_tests.sh
+++ b/test/run_tests.sh
@@ -4,7 +4,9 @@ set -ev
#goto git root directory
git rev-parse && cd "$(git rev-parse --show-cdup)"
-time utPLSQL-cli/bin/utplsql run UT3_TESTER_HELPER/ut3@${CONNECTION_STR} \
+export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
+
+time utPLSQL-cli/bin/utplsql run UT3_TESTER_HELPER/ut3@//${CONNECTION_STR} -D \
-source_path=source -owner=ut3_develop \
-p='ut3_tester,ut3_user' \
-test_path=test -c \
diff --git a/test/ut3_tester/core/test_suite_manager.pks b/test/ut3_tester/core/test_suite_manager.pks
index ac7818f4f..44f102716 100644
--- a/test/ut3_tester/core/test_suite_manager.pks
+++ b/test/ut3_tester/core/test_suite_manager.pks
@@ -163,7 +163,7 @@ create or replace package test_suite_manager is
--%context(get_schema_ut_packages)
- --%test(returns list of all unit test packages in given schema)
+ --%test(returns list of all unit test packages in given schema excluding packages that are not suites)
--%beforetest(create_ut3_suite)
--%aftertest(drop_ut3_suite)
procedure test_get_schema_ut_packages;
diff --git a/test/ut3_tester_helper/run_helper.pkb b/test/ut3_tester_helper/run_helper.pkb
index 6289b1642..9d65d6667 100644
--- a/test/ut3_tester_helper/run_helper.pkb
+++ b/test/ut3_tester_helper/run_helper.pkb
@@ -855,12 +855,23 @@ create or replace package body run_helper is
--%test
procedure some_test;
+ end;]';
+ execute immediate q'[
+ create or replace package ut3_develop.package_that_is_not_a_test
+ as
+ --%parameter(a comment inside)
+ --%parameters( description )
+
+ --%test
+ procedure some_test;
+
end;]';
end;
procedure drop_ut3_suite is
pragma autonomous_transaction;
begin
+ execute immediate q'[drop package ut3_develop.package_that_is_not_a_test]';
execute immediate q'[drop package ut3_develop.some_test_package]';
end;
diff --git a/test/ut3_user/api/test_ut_run.pkb b/test/ut3_user/api/test_ut_run.pkb
index e80235744..f0cfd8373 100644
--- a/test/ut3_user/api/test_ut_run.pkb
+++ b/test/ut3_user/api/test_ut_run.pkb
@@ -742,7 +742,7 @@ Failures:%
procedure remove_time_from_results(a_results in out nocopy ut3_develop.ut_varchar2_list) is
begin
for i in 1 .. a_results.count loop
- a_results(i) := regexp_replace(a_results(i),'\[[0-9]*[\.,][0-9]+ sec\]','');
+ a_results(i) := regexp_replace(a_results(i),'\[[0-9]*[\.,]?[0-9]+ sec\]','');
a_results(i) := regexp_replace(a_results(i),'Finished in [0-9]*[\.,][0-9]+ seconds','');
end loop;
end;
diff --git a/test/ut3_user/api/test_ut_runner.pkb b/test/ut3_user/api/test_ut_runner.pkb
index b6b7c67e7..d665718e1 100644
--- a/test/ut3_user/api/test_ut_runner.pkb
+++ b/test/ut3_user/api/test_ut_runner.pkb
@@ -393,7 +393,8 @@ end;';
select 'UT3_DEVELOP.UT_SONAR_TEST_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_TEAMCITY_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_TFS_JUNIT_REPORTER', 'Y' from dual union all
- select 'UT3_DEVELOP.UT_XUNIT_REPORTER', 'Y' from dual
+ select 'UT3_DEVELOP.UT_XUNIT_REPORTER', 'Y' from dual union all
+ select 'UT3_DEVELOP.UT_TAP_REPORTER', 'Y' from dual
order by 1;
--Act
open l_actual for select * from table(ut3_develop.ut_runner.GET_REPORTERS_LIST()) order by 1;
diff --git a/test/ut3_user/expectations/test_expectations_cursor.pkb b/test/ut3_user/expectations/test_expectations_cursor.pkb
index 847cce9a0..a4ef4e8f2 100644
--- a/test/ut3_user/expectations/test_expectations_cursor.pkb
+++ b/test/ut3_user/expectations/test_expectations_cursor.pkb
@@ -2950,5 +2950,47 @@ Rows: [ 2 differences ]
);
end;
+ procedure cr_joinby_compare_issue_1293 is
+ l_actual sys_refcursor;
+ l_expected sys_refcursor;
+ begin
+ --Arrange
+ open l_expected for
+ select 'FOO' username, 12 from dual union all
+ select 'TEST' username, -600 user_id from dual
+ order by 1 desc;
+ open l_actual for
+ select 'FOO' username, 12 from dual union all
+ select 'TEST' username, -600 user_id from dual union all
+ -- DUPLICATE!!!
+ select 'TEST' username, -600 user_id from dual
+ order by 1 asc;
+ --Act
+ ut3_develop.ut.expect(l_actual).to_equal(l_expected).join_by('USERNAME');
+ --Assert
+ ut.expect(ut3_tester_helper.main_helper.get_failed_expectations_num).to_be_greater_than(0);
+ end;
+
+ procedure cr_not_joinby_comp_issue_1293 is
+ l_actual sys_refcursor;
+ l_expected sys_refcursor;
+ begin
+ --Arrange
+ open l_expected for
+ select 'FOO' username, 12 from dual union all
+ select 'TEST' username, -600 user_id from dual
+ order by 1 desc;
+ open l_actual for
+ select 'FOO' username, 12 from dual union all
+ select 'TEST' username, -600 user_id from dual union all
+ -- DUPLICATE!!!
+ select 'TEST' username, -600 user_id from dual
+ order by 1 asc;
+ --Act
+ ut3_develop.ut.expect(l_actual).to_equal(l_expected);
+ --Assert
+ ut.expect(ut3_tester_helper.main_helper.get_failed_expectations_num).to_be_greater_than(0);
+ end;
+
end;
/
diff --git a/test/ut3_user/expectations/test_expectations_cursor.pks b/test/ut3_user/expectations/test_expectations_cursor.pks
index 0f34486a9..8cceb5e01 100644
--- a/test/ut3_user/expectations/test_expectations_cursor.pks
+++ b/test/ut3_user/expectations/test_expectations_cursor.pks
@@ -485,5 +485,11 @@ create or replace package test_expectations_cursor is
--%test( Multiple failures reported correctly - Issue #998 )
procedure multiple_cursor_expectations;
+ --%test( Compares cursors with duplicate rows using join by - Issue #1293 )
+ procedure cr_joinby_compare_issue_1293;
+
+ --%test( Compares cursors with duplicate rows - Issue #1293 )
+ procedure cr_not_joinby_comp_issue_1293;
+
end;
/
diff --git a/test/ut3_user/reporters/test_documentation_reporter.pkb b/test/ut3_user/reporters/test_documentation_reporter.pkb
index 2a05679ff..016cec256 100644
--- a/test/ut3_user/reporters/test_documentation_reporter.pkb
+++ b/test/ut3_user/reporters/test_documentation_reporter.pkb
@@ -34,7 +34,6 @@ Failures:
"Fails as values are different"
Actual: 'number [1] ' (varchar2) was expected to equal: 'number [2] ' (varchar2)%
at "UT3_USER.TEST_REPORTERS%", line 36 ut3_develop.ut.expect('number [1] ','Fails as values are different').to_equal('number [2] ');
-%
%
2) erroring_test
ORA-06502: PL/SQL: %: character to number conversion error
diff --git a/test/ut3_user/reporters/test_realtime_reporter.pkb b/test/ut3_user/reporters/test_realtime_reporter.pkb
index 2dafa71d0..84053c3c9 100644
--- a/test/ut3_user/reporters/test_realtime_reporter.pkb
+++ b/test/ut3_user/reporters/test_realtime_reporter.pkb
@@ -408,7 +408,7 @@ create or replace package body test_realtime_reporter as
from table(g_events) t
where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval()
= 'realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error';
- ut3_tester_helper.main_helper.append_to_list(l_expected_list, '');
l_expected := ut3_tester_helper.main_helper.table_to_clob(l_expected_list);
diff --git a/test/ut3_user/reporters/test_tap_reporter.pkb b/test/ut3_user/reporters/test_tap_reporter.pkb
new file mode 100644
index 000000000..786c53ee0
--- /dev/null
+++ b/test/ut3_user/reporters/test_tap_reporter.pkb
@@ -0,0 +1,254 @@
+create or replace package body test_tap_reporter as
+
+ gc_boilerplate_suitepath_expression constant varchar2(300) := 'TAP version 14\s*1..1\s*# Subtest: org\s{5}1..1\s{5}# Subtest: utplsql\s{9}1..1\s{9}# Subtest: tests\s{13}1..1\s{13}# Subtest: helpers\s{17}1..1\s{17}# Subtest: A suite for testing different outcomes from reporters';
+
+
+ procedure compile_tests as
+ pragma autonomous_transaction;
+ begin
+
+ execute immediate q'[
+ create or replace package test_tap_escaping as
+ --%suite(Some \ and # to be escaped)
+
+ --%test(Even more \\ and multiple ###)
+ procedure more_escaping;
+
+ --%test(Disabled test)
+ --%disabled(With \ and # in skip reason)
+ procedure not_skipping_escapes;
+
+ --%test(Escaped Comments)
+ procedure escaped_comments;
+
+ --%context(Some context)
+
+ --%test(Another disabled test)
+ --%disabled
+ procedure another_disabled_test;
+
+ --%endcontext
+ end test_tap_escaping;
+ ]';
+
+ execute immediate q'[
+ create or replace package body test_tap_escaping as
+
+ procedure more_escaping as
+ begin
+ ut.expect(1).to_equal(1);
+ end more_escaping;
+
+
+ procedure not_skipping_escapes as
+ begin
+ ut.expect(10).to_equal(1);
+ end not_skipping_escapes;
+
+ procedure escaped_comments as
+ begin
+ dbms_output.put_line('This \ and # should not be escaped, and this not as well!!!');
+ ut.expect(1).to_equal(1);
+ end escaped_comments;
+
+ procedure another_disabled_test as
+ begin
+ ut.expect(10).to_equal(1);
+ end;
+ end test_tap_escaping;
+ ]';
+
+ end compile_tests;
+
+
+ procedure simple_succeeding_test as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := gc_boilerplate_suitepath_expression || '\s{21}1..1\s{21}# \s{21}# Subtest: A description of some context\s{25}1..1\s{25}ok - passing_test\s{25}# \s{25}# \s{25}# \s{25}# \s{25}# \s{21}# \sok - org\s*';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.passing_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected);
+ end simple_succeeding_test;
+
+ procedure simple_failing_test as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := gc_boilerplate_suitepath_expression || q'[\s{21}1..1\s{21}# \s{21}not ok - a test with failing assertion\s{23}---\s{23}message: '"Fails as values are different"'\s{23}severity: fail\s{23}...\s{21}# \s{21}# \s{21}# \s{21}# \snot ok - org\s*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.failing_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected);
+ end simple_failing_test;
+
+
+ procedure simple_erroring_test as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := gc_boilerplate_suitepath_expression || q'[\s{21}1..1\s{21}# \s{21}not ok - a test raising unhandled exception\s{23}---\s{23}message: |\s{25ORA-06502: .*\s{25}ORA-06512: at line [[:digit:]]+\s{23}severity: error\s{23}...\s{21}# \s{21}# \s{21}# \s{21}# \snot ok - org\s*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.erroring_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected);
+ end simple_erroring_test;
+
+
+ procedure disabled_test as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := gc_boilerplate_suitepath_expression || q'[\s{21}1..1\s{21}# \s{21}ok - a disabled test # SKIP: Disabled for testing purpose\s{21}# \sok - org\s*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.disabled_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected);
+ end disabled_test;
+
+
+ procedure disabled_test_no_description as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := gc_boilerplate_suitepath_expression || q'[\s{21}1..1\s{21}# \s{21}ok - a disabled test with no reason # SKIP\s{21}# \sok - org\s*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.disabled_test_no_reason',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected);
+ end disabled_test_no_description;
+
+
+ procedure multiple_tests_different_outcome as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[TAP version 14\s*1..1\s*# Subtest: org.*# Subtest: A suite.*\s{21}1..5\s{21}# \s{21}# Subtest: A desc.*\s{25}1..1\s{25}ok - passing_test\s{25}# \s{25}# \s{21}not ok - a test w.*\s{23}---\s{23}message:.*\s{21}# .*\s{21}# not ok - a test rai.*\s{23}---\s{23}message: |.*ok - a disabled test # SKIP: Disabled for testing purpose.*ok - a dis.* # SKIP\s{21}# \snot ok - org\s*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected, 'n');
+ end multiple_tests_different_outcome;
+
+
+ procedure escape_suite_name as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%# Subtest: Some \\ and \# to be escaped%ok - Some \\ and \# to be escaped%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_tap_escaping.more_escaping',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+ end escape_suite_name;
+
+
+ procedure escape_multiple_characters_test_name as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%ok - Even more \\\\ and multiple \#\#\#%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_tap_escaping.more_escaping',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+ end escape_multiple_characters_test_name;
+
+
+ procedure special_characters_in_disabled_reason as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%ok - Disabled test # SKIP: With \\ and \# in skip reason%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_tap_escaping.not_skipping_escapes',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+ end special_characters_in_disabled_reason;
+
+
+ procedure special_characters_in_comment as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%ok - Escaped Comments%# This \ and # should not be escaped, and this not as well!!!%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_tap_escaping.escaped_comments',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+ end special_characters_in_comment;
+
+
+ procedure context_as_commented_subtests as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%# Subtest: A suite for testing different outcomes from reporters%# Subtest: A description of some context%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.passing_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+
+ end context_as_commented_subtests;
+
+
+ procedure suitepath_as_chopped_subtests as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[.*# Subtest: org.*1\s{5}# Subtest: utplsql.*1\s{9}# Subtest: tests.*1\s{13}# Subtest: helpers.*1\s{17}# Subtest: A suite for testing different outcomes from reporters.*]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_reporters.passing_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_match(l_expected, 'n');
+
+ end suitepath_as_chopped_subtests;
+
+
+ procedure include_context_with_skipped_tests as
+ l_output_data ut3_develop.ut_varchar2_list;
+ l_expected varchar2(32767);
+ begin
+ l_expected := q'[%# Subtest: Some context%]';
+
+ select *
+ bulk collect into l_output_data
+ from table(ut3_develop.ut.run('test_tap_escaping.another_disabled_test',ut3_develop.ut_tap_reporter()));
+
+ ut.expect(ut3_tester_helper.main_helper.table_to_clob(l_output_data)).to_be_like(l_expected);
+
+ end include_context_with_skipped_tests;
+
+
+ procedure drop_help_tests as
+ pragma autonomous_transaction;
+ begin
+ execute immediate 'drop package test_tap_escaping';
+ end drop_help_tests;
+end test_tap_reporter;
+/
\ No newline at end of file
diff --git a/test/ut3_user/reporters/test_tap_reporter.pks b/test/ut3_user/reporters/test_tap_reporter.pks
new file mode 100644
index 000000000..27f9651bc
--- /dev/null
+++ b/test/ut3_user/reporters/test_tap_reporter.pks
@@ -0,0 +1,53 @@
+create or replace package test_tap_reporter as
+
+ --%suite(ut_tap_reporter)
+ --%suitepath(utplsql.test_user.reporters)
+
+ --%beforeall
+ procedure compile_tests;
+
+ --%test(Simple succeeding test)
+ procedure simple_succeeding_test;
+
+ --%test(Simple failing test)
+ procedure simple_failing_test;
+
+ --%test(Simple erroring test)
+ procedure simple_erroring_test;
+
+ --%test(Skipped test)
+ procedure disabled_test;
+
+ --%test(Skipped test without description)
+ procedure disabled_test_no_description;
+
+ --%test(Multiple tests with different outcome)
+ procedure multiple_tests_different_outcome;
+
+ --%test(Escape special characters in suite name)
+ procedure escape_suite_name;
+
+ --%test(Escape multiple special characters in test name)
+ procedure escape_multiple_characters_test_name;
+
+ --%test(Disabled Test with special characters in disable reason)
+ procedure special_characters_in_disabled_reason;
+
+ --%test(Don't escape special characters in comment)
+ procedure special_characters_in_comment;
+
+ --%test(Include context as commented subtests)
+ procedure context_as_commented_subtests;
+
+ --%test(Suitepath as chopped subtests)
+ procedure suitepath_as_chopped_subtests;
+
+ --%test(Include context with only skipped tests in output)
+ procedure include_context_with_skipped_tests;
+
+
+ --%afterall
+ procedure drop_help_tests;
+
+end test_tap_reporter;
+/
\ No newline at end of file