diff --git a/.github/DISCUSSION_TEMPLATE/README.md b/.github/DISCUSSION_TEMPLATE/README.md
deleted file mode 100644
index f6c0905f4..000000000
--- a/.github/DISCUSSION_TEMPLATE/README.md
+++ /dev/null
@@ -1,150 +0,0 @@
-# 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
deleted file mode 100644
index 262746e11..000000000
--- a/.github/DISCUSSION_TEMPLATE/announcements.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-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
deleted file mode 100644
index f3df8e29c..000000000
--- a/.github/DISCUSSION_TEMPLATE/architecture.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-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/bug-triage.yml b/.github/DISCUSSION_TEMPLATE/bug-triage.yml
new file mode 100644
index 000000000..7a5da8d73
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/bug-triage.yml
@@ -0,0 +1,69 @@
+title: "[Bug?] "
+labels: ["bug-triage"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category if you think you have found a bug in the utPLSQL framework and want to discuss it before a formal issue is opened.
+
+ Once a maintainer confirms the bug, they will open an issue and link it back here. You do not need to open an issue yourself.
+
+ If you are certain it is a bug and can provide a reliable reproduction, you may open an issue directly instead.
+
+ - type: input
+ id: utplsql-version
+ attributes:
+ label: utPLSQL version
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: true
+
+ - type: input
+ id: oracle-version
+ attributes:
+ label: Oracle Database version
+ placeholder: "e.g. 19c, 21c"
+ validations:
+ required: true
+
+ - type: input
+ id: os
+ attributes:
+ label: Operating system
+ placeholder: "e.g. Linux, Windows Server 2019"
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: What did you observe?
+ description: Describe the unexpected behaviour. Include any error messages or stack traces.
+ render: text
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: What did you expect?
+ description: Describe what you expected to happen instead.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Reproduction case
+ description: Paste the minimal PL/SQL needed to reproduce the problem. The simpler, the better.
+ render: sql
+ validations:
+ required: false
+
+ - type: textarea
+ id: investigation
+ attributes:
+ label: What have you investigated so far?
+ description: Any findings from your own debugging that might help narrow this down.
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/contributing.yml b/.github/DISCUSSION_TEMPLATE/contributing.yml
new file mode 100644
index 000000000..31a213cbb
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/contributing.yml
@@ -0,0 +1,43 @@
+title: ""
+labels: ["contributing"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category if you are working on or considering a contribution to the utPLSQL framework codebase and have questions about the internals, development setup, testing approach, or contribution process.
+
+ Before posting, it is worth checking:
+ - [CONTRIBUTING.md](https://github.com/utPLSQL/utPLSQL/blob/develop/CONTRIBUTING.md)
+ - [Development setup guide](https://github.com/utPLSQL/utPLSQL/blob/develop/development/README.md)
+
+ - type: dropdown
+ id: topic
+ attributes:
+ label: Topic
+ options:
+ - Development environment setup
+ - Understanding the codebase
+ - Test writing and running locally
+ - CI / build pipeline
+ - Pull request process
+ - Architectural question
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question or topic
+ description: Describe what you are working on and what you need help with.
+ validations:
+ required: true
+
+ - type: textarea
+ id: context
+ attributes:
+ label: Relevant code or context
+ description: Paste any relevant code, configuration, or error output here.
+ render: sql
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/contributors.yml b/.github/DISCUSSION_TEMPLATE/contributors.yml
deleted file mode 100644
index 6325961de..000000000
--- a/.github/DISCUSSION_TEMPLATE/contributors.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-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/feature-requests.yml b/.github/DISCUSSION_TEMPLATE/feature-requests.yml
new file mode 100644
index 000000000..130d30c28
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/feature-requests.yml
@@ -0,0 +1,62 @@
+title: "[Feature] "
+labels: ["feature-request"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this category for feature ideas specific to the utPLSQL framework: new matchers, annotation behaviour, reporter output, suite control, coverage, or installation.
+
+ > For ideas that affect multiple components or the project direction overall, use [org-level Feature Requests](https://github.com/orgs/utPLSQL/discussions/categories/feature-requests) instead.
+
+ A maintainer will mark this discussion as answered once the proposal is accepted or declined.
+ If accepted, a maintainer will convert it to an issue for implementation tracking -- you do not need to open an issue yourself.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem or motivation
+ description: What problem does this feature solve? What is the current limitation or pain point?
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed solution
+ description: Describe the feature you have in mind. Include examples of how it would be used, ideally with PL/SQL annotation or API examples.
+ render: sql
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives or workarounds considered
+ description: Have you found any alternative approaches or partial workarounds?
+ validations:
+ required: false
+
+ - type: dropdown
+ id: area
+ attributes:
+ label: Framework area
+ options:
+ - Annotations
+ - Matchers
+ - Reporters
+ - Suite / test control
+ - Coverage
+ - Transaction control
+ - Installation / upgrade
+ - Performance
+ - Other
+ validations:
+ required: true
+
+ - type: input
+ id: utplsql-version
+ attributes:
+ label: utPLSQL version you are using
+ placeholder: "e.g. 3.1.13"
+ validations:
+ required: false
diff --git a/.github/DISCUSSION_TEMPLATE/general.yml b/.github/DISCUSSION_TEMPLATE/general.yml
deleted file mode 100644
index 0e3b8d100..000000000
--- a/.github/DISCUSSION_TEMPLATE/general.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-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
index e4ff1d452..30b372760 100644
--- a/.github/DISCUSSION_TEMPLATE/q-a.yml
+++ b/.github/DISCUSSION_TEMPLATE/q-a.yml
@@ -17,25 +17,18 @@ body:
> If this turns out to be a **bug**, a maintainer will convert this discussion into an Issue.
- type: input
- id: utplsql_version
+ id: utplsql-version
attributes:
label: utPLSQL version
placeholder: "e.g. 3.1.13"
validations:
required: true
- - type: dropdown
- id: oracle_version
+ - type: input
+ id: oracle-version
attributes:
- label: Oracle version
- options:
- - Oracle 11g
- - Oracle 12c
- - Oracle 18c
- - Oracle 19c
- - Oracle 21c
- - Oracle 23c / 23ai
- - Other / unsure
+ label: Oracle Database version
+ placeholder: "e.g. 19c, 21c"
validations:
required: true
@@ -43,7 +36,7 @@ body:
id: question
attributes:
label: Question
- description: Describe what you are trying to do and what you have tried so far.
+ description: Describe what you are trying to do and what you have already tried.
validations:
required: true
@@ -59,29 +52,10 @@ body:
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
+ id: output
attributes:
- label: Installation method
- options:
- - utPLSQL-cli
- - SQL*Plus script
- - Docker / utPLSQL-docker
- - Liquibase / Flyway
- - Other
- - N/A
+ label: Actual output or error
+ description: Paste any error messages or unexpected output here.
+ render: text
validations:
required: false
diff --git a/.github/DISCUSSION_TEMPLATE/release-planning.yml b/.github/DISCUSSION_TEMPLATE/release-planning.yml
deleted file mode 100644
index 5663d7613..000000000
--- a/.github/DISCUSSION_TEMPLATE/release-planning.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-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
deleted file mode 100644
index 32c0a33c7..000000000
--- a/.github/DISCUSSION_TEMPLATE/rfcs-design.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-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
deleted file mode 100644
index 4443c5de6..000000000
--- a/.github/DISCUSSION_TEMPLATE/show-and-tell.yml
+++ /dev/null
@@ -1,79 +0,0 @@
-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/scripts/create_test_users.sh b/.github/scripts/create_test_users.sh
index fe43b7467..6c3030206 100755
--- a/.github/scripts/create_test_users.sh
+++ b/.github/scripts/create_test_users.sh
@@ -18,6 +18,9 @@ PROMPT Creating UT3_TESTER - Power-user for testing internal framework code
create user UT3_TESTER identified by "ut3" default tablespace $UT3_TABLESPACE quota unlimited on $UT3_TABLESPACE;
grant create session, create procedure, create type, create table to UT3_TESTER;
+# Editioning is enable on test users to validate that utPLSQL works well with editioned schema
+alter user UT3_TESTER enable editions;
+
grant execute on dbms_lock to UT3_TESTER;
PROMPT Granting $UT3_DEVELOP_SCHEMA code to UT3_TESTER
@@ -52,6 +55,9 @@ PROMPT Creating UT3_USER - minimal privileges user for API testing
create user UT3_USER identified by "ut3" default tablespace $UT3_TABLESPACE quota unlimited on $UT3_TABLESPACE;
grant create session, create procedure, create type, create table to UT3_USER;
+# Editioning is enable on test users to validate that utPLSQL works well with editioned schema
+alter user UT3_USER enable editions;
+
PROMPT Grants for starting a debugging session from UT3_USER
grant debug connect session to UT3_USER;
grant debug any procedure to UT3_USER;
@@ -86,7 +92,7 @@ PROMPT Grants for testing coverage outside of main $UT3_DEVELOP_SCHEMA schema.
grant create any procedure, drop any procedure, execute any procedure, create any type, drop any type, execute any type, under any type,
select any table, update any table, insert any table, delete any table, create any table, drop any table, alter any table,
select any dictionary, create any synonym, drop any synonym,
- grant any object privilege, grant any privilege, create public synonym, drop public synonym, create any trigger
+ grant any object privilege, grant any privilege, create public synonym, drop public synonym, create any trigger, drop any trigger
to UT3_TESTER_HELPER;
grant create job to UT3_TESTER_HELPER;
diff --git a/.github/scripts/install.sh b/.github/scripts/install.sh
index 46750b89c..5f034951c 100755
--- a/.github/scripts/install.sh
+++ b/.github/scripts/install.sh
@@ -19,3 +19,13 @@ set verify off
alter session set plsql_optimize_level=0;
@${INSTALL_FILE} $UT3_DEVELOP_SCHEMA $UT3_DEVELOP_SCHEMA_PASSWORD
SQL
+
+#Enable editioning on the UT3_DEVELOP schema
+time "$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<-SQL
+whenever sqlerror exit failure rollback
+set feedback off
+set verify off
+
+alter user $UT3_DEVELOP_SCHEMA enable editions;
+exit
+SQL
diff --git a/.github/scripts/post_release_announcement.sh b/.github/scripts/post_release_announcement.sh
new file mode 100755
index 000000000..c74394505
--- /dev/null
+++ b/.github/scripts/post_release_announcement.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Posts a release announcement to the utPLSQL org .github repository's
+# Announcements discussion category.
+#
+# Required environment variables:
+# GH_TOKEN - GitHub token with write:discussion scope (ORG_DISCUSSION_TOKEN)
+# RELEASE_TAG - e.g. v3.2.3
+# RELEASE_BODY - markdown release notes
+# RELEASE_URL - URL of the GitHub release page
+
+set -euo pipefail
+
+ORG="utPLSQL"
+REPO_NAME=".github"
+
+# Get org node ID
+ORG_DATA=$(gh api graphql -f query='query($org: String!) {
+ organization(login: $org) {
+ id
+ }
+}' -f org="$ORG")
+ORG_ID=$(echo "$ORG_DATA" | jq -r '.data.organization.id')
+
+# Get repository node ID
+REPO_DATA=$(gh api graphql -f query='query($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {
+ id
+ }
+}' -f owner="$ORG" -f name="$REPO_NAME")
+REPO_ID=$(echo "$REPO_DATA" | jq -r '.data.repository.id')
+
+# Get Announcements category ID
+CATEGORY_DATA=$(gh api graphql -f query='query($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {
+ discussionCategories(first: 20) {
+ nodes { id name }
+ }
+ }
+}' -f owner="$ORG" -f name="$REPO_NAME")
+CATEGORY_ID=$(echo "$CATEGORY_DATA" | jq -r \
+ '.data.repository.discussionCategories.nodes[] | select(.name == "Announcements") | .id')
+
+BODY="${RELEASE_BODY}
+
+
This discussion was created from the release ${RELEASE_TAG}."
+
+DISCUSSION_URL=$(gh api graphql -f query='mutation($repoId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
+ createDiscussion(input: {
+ repositoryId: $repoId,
+ categoryId: $categoryId,
+ title: $title,
+ body: $body
+ }) {
+ discussion { url }
+ }
+}' \
+ -f repoId="$REPO_ID" \
+ -f categoryId="$CATEGORY_ID" \
+ -f title="utPLSQL ${RELEASE_TAG} released" \
+ -f body="$BODY" \
+ --jq '.data.createDiscussion.discussion.url')
+
+echo "Announcement posted: $DISCUSSION_URL"
diff --git a/.github/scripts/publish_release_post.sh b/.github/scripts/publish_release_post.sh
new file mode 100755
index 000000000..89438738c
--- /dev/null
+++ b/.github/scripts/publish_release_post.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Publishes a release announcement post to utplsql.github.io.
+# Creates the post file, prepends an entry to docs/index.md,
+# and inserts the post into the mkdocs.yml nav.
+#
+# Required environment variables:
+# API_TOKEN_GITHUB - GitHub token with write access to utPLSQL.github.io
+# RELEASE_TAG - e.g. v3.2.01
+# RELEASE_BODY - markdown release notes (from github.event.release.body)
+# RELEASE_DATE - ISO-8601 publish timestamp (from github.event.release.published_at)
+
+set -euo pipefail
+
+GITHUB_IO_REPO="utPLSQL/utPLSQL.github.io"
+GITHUB_IO_BRANCH="main"
+
+VERSION="${RELEASE_TAG#v}"
+POST_DATE=$(echo "${RELEASE_DATE}" | cut -c1-10)
+POST_TIME=$(echo "${RELEASE_DATE}" | sed 's/T/ /' | sed 's/Z/ +0000/')
+POST_FILENAME="${POST_DATE}-version${VERSION}-released.md"
+POST_TITLE="utPLSQL ${RELEASE_TAG} released"
+POST_NAV_TITLE="utPLSQL ${VERSION} released"
+
+mkdir -p github_io
+cd github_io
+git clone --depth 1 "https://${API_TOKEN_GITHUB}@github.com/${GITHUB_IO_REPO}" -b "${GITHUB_IO_BRANCH}" .
+
+# Format the release body for the post:
+# 1. Convert bare GitHub issue/PR URLs to [#NUMBER](URL)
+# e.g. https://github.com/utPLSQL/utPLSQL/pull/1320
+# -> [#1320](https://github.com/utPLSQL/utPLSQL/pull/1320)
+# 2. Convert the auto-generated "Full Changelog" bare URL to a labelled link
+# e.g. **Full Changelog**: https://.../compare/v3.2.01...v3.2.2
+# -> **Full Changelog**: [v3.2.01...v3.2.2](https://.../compare/v3.2.01...v3.2.2)
+FORMATTED_BODY=$(echo "${RELEASE_BODY}" \
+ | sed -E 's@https://github\.com/([^/]+)/([^/]+)/(pull|issues)/([0-9]+)@[#\4](https://github.com/\1/\2/\3/\4)@g' \
+ | sed -E 's@\*\*Full Changelog\*\*: (https://[^ ]+/compare/([^ ]+))@\*\*Full Changelog\*\*: [\2](\1)@g')
+
+# Create the post file
+cat > "docs/_posts/${POST_FILENAME}" < /tmp/index_new.md
+mv /tmp/index_new.md docs/index.md
+
+# Insert new post into mkdocs.yml nav immediately after "- index.md"
+sed -i "s| - index.md| - index.md\n - ${POST_NAV_TITLE}: _posts/${POST_FILENAME}|" mkdocs.yml
+
+git add "docs/_posts/${POST_FILENAME}" docs/index.md mkdocs.yml
+git commit -m "Release announcement for ${RELEASE_TAG}"
+git push origin "${GITHUB_IO_BRANCH}"
+
+echo "Release post published: docs/_posts/${POST_FILENAME}"
diff --git a/.github/scripts/update_changelog.sh b/.github/scripts/update_changelog.sh
new file mode 100755
index 000000000..011c08819
--- /dev/null
+++ b/.github/scripts/update_changelog.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Updates CHANGELOG.md by prepending a new section for the release.
+#
+# Required environment variables:
+# RELEASE_TAG - e.g. v3.2.3
+# RELEASE_BODY - markdown release notes
+# RELEASE_DATE - ISO-8601 date string (only the first 10 chars are used)
+# TARGET_BRANCH - branch to push the updated changelog to
+
+set -euo pipefail
+
+python3 - <<'PYEOF'
+import os
+
+tag = os.environ['RELEASE_TAG']
+body = os.environ['RELEASE_BODY'].strip()
+date = os.environ['RELEASE_DATE'][:10]
+
+new_section = f"## [{tag}] - {date}\n\n{body}\n\n---\n\n"
+
+with open('CHANGELOG.md', 'r') as f:
+ content = f.read()
+
+marker = '\n---\n'
+pos = content.index(marker) + len(marker)
+updated = content[:pos] + '\n' + new_section + content[pos:]
+
+with open('CHANGELOG.md', 'w') as f:
+ f.write(updated)
+
+print(f"Added {tag} to CHANGELOG.md")
+PYEOF
+
+git add CHANGELOG.md
+git commit -m "Add release notes for ${RELEASE_TAG} to CHANGELOG.md [skip ci]"
+git push origin HEAD:"${TARGET_BRANCH}"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index be6e18ca2..8c77c486c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -32,6 +32,8 @@ jobs:
db_version_name: '19se'
oracle-sid: 'ORCLCDB'
oracle-version: "utplsqlv3/oracledb:19c-se2-small"
+ check-coding-style: true
+ validate-utplsql-uninstall: true
- id: 2
db_version_name: '21XE'
oracle-sid: 'XE'
@@ -40,6 +42,8 @@ jobs:
db_version_name: '23-free'
oracle-sid: 'FREEPDB1'
oracle-version: "gvenzl/oracle-free:23-slim-faststart"
+ fips-enabled: true
+ run-sonar-scanner: true
services:
html_checker:
image: ghcr.io/validator/validator:latest
@@ -84,6 +88,19 @@ jobs:
# For PR build - test using target branch as framework, for branch build use self as testing framework
run: git clone --depth=1 --branch=${CI_BASE_REF:-$CI_REF_NAME} https://github.com/utPLSQL/utPLSQL.git $UTPLSQL_DIR
+ - name: Enable FIPS 140 on Oracle DB
+ id: enable-fips
+ if: ${{ matrix.fips-enabled == true }}
+ run: |
+ docker exec oracle bash -c "
+ echo \"ALTER SYSTEM SET DBFIPS_140=TRUE SCOPE=SPFILE;
+ SHUTDOWN IMMEDIATE;
+ STARTUP;
+ PROMPT Should show true for DBFIPS_140
+ SELECT name, value FROM v$parameter WHERE name = 'DBFIPS_140';
+ EXIT;\" | sqlplus -s / as sysdba
+ "
+ docker exec oracle bash -c "until healthcheck.sh; do echo 'Waiting for DB restart...'; sleep 1; done"
- name: Update privileges on sources
run: chmod -R go+w ./{source,test,examples,${UTPLSQL_DIR}/source}
@@ -116,17 +133,17 @@ jobs:
run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/install.sh
- name: Check code style
- if: ${{ matrix.id == 1 }}
+ if: ${{ matrix.check-style == true }}
id: check-coding-style
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 }}
+ if: ${{ matrix.validate-utplsql-uninstall == true }}
id: validate-uninstall
run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/uninstall_validate_utplsql.sh
- name: Reinstall utPLSQL
- if: ${{ matrix.id == 1 }}
+ if: ${{ matrix.validate-utplsql-uninstall == true }}
id: reinstall-utplsql
run: docker exec -w /utPLSQL ${DOCKER_ENV} oracle .github/scripts/install.sh
@@ -190,7 +207,7 @@ jobs:
- name: SonarCloud Scan
id: sonar
- if: ${{ always() && matrix.db_version_name == '23-free' }}
+ if: ${{ always() && matrix.run-sonar-scanner == true }}
uses: SonarSource/sonarqube-scan-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
@@ -276,17 +293,3 @@ jobs:
repository: ${{ matrix.repo }}
event-type: utPLSQL-build
- slack-workflow-status:
- if: always()
- 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
- with:
- repo_token: ${{secrets.GITHUB_TOKEN}}
- slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}}
- name: 'Github Actions[bot]'
- icon_url: 'https://octodex.github.com/images/mona-the-rivetertocat.png'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ab043b6eb..c4c76222c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -15,27 +15,33 @@ jobs:
concurrency: upload
runs-on: ubuntu-latest
timeout-minutes: 60
+ env:
+ API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
+ RELEASE_BODY: ${{ github.event.release.body }}
+ RELEASE_DATE: ${{ github.event.release.published_at }}
+ RELEASE_URL: ${{ github.event.release.html_url }}
+ TARGET_BRANCH: ${{ github.event.release.target_commitish }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
+ token: ${{ env.API_TOKEN_GITHUB }}
- uses: c-py/action-dotenv-to-setenv@v5
with:
env-file: .github/variables/.env
- uses: FranzDiebold/github-env-vars-action@v2.8.0 #https://github.com/marketplace/actions/github-environment-variables-action
+ - name: Update CHANGELOG.md with release notes
+ run: .github/scripts/update_changelog.sh
+
- name: Set build version number env variables
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
- - name: Setup git config
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
-
- name: Build and publish documentation
run: |
pip install mkdocs
@@ -53,30 +59,23 @@ jobs:
run: |
git archive --prefix=utPLSQL/ -o utPLSQL.zip --format=zip HEAD
git archive --prefix=utPLSQL/ -o utPLSQL.tar.gz --format=tar.gz HEAD
- md5sum utPLSQL.zip --tag > utPLSQL.zip.md5
- md5sum utPLSQL.tar.gz --tag > utPLSQL.tar.gz.md5
+ sha256sum utPLSQL.zip --tag > utPLSQL.zip.sha256
+ sha256sum utPLSQL.tar.gz --tag > utPLSQL.tar.gz.sha256
- name: Release
uses: softprops/action-gh-release@v1
with:
files: |
utPLSQL.zip
- utPLSQL.zip.md5
+ utPLSQL.zip.sha256
utPLSQL.tar.gz
- utPLSQL.tar.gz.md5
+ utPLSQL.tar.gz.sha256
- slack-workflow-status:
- if: always()
- 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
- with:
- repo_token: ${{secrets.GITHUB_TOKEN}}
- slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}}
- name: 'Github Actions[bot]'
- icon_url: 'https://octodex.github.com/images/mona-the-rivetertocat.png'
+ - name: Post release announcement to org discussions
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_API_TOKEN }}
+ run: .github/scripts/post_release_announcement.sh
+
+ - name: Publish release post to utplsql.github.io
+ run: .github/scripts/publish_release_post.sh
diff --git a/.github/workflows/test_publishing.yml b/.github/workflows/test_publishing.yml
new file mode 100644
index 000000000..0aac3805b
--- /dev/null
+++ b/.github/workflows/test_publishing.yml
@@ -0,0 +1,52 @@
+name: Test publishing
+on:
+ workflow_dispatch:
+
+defaults:
+ run:
+ shell: bash
+
+jobs:
+
+ upload_artifacts:
+ name: Upload archives
+ concurrency: upload
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ env:
+ API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
+ RELEASE_TAG: "v3.2.2"
+ RELEASE_BODY: |
+ ## What's Changed
+ * Filtering by tags fixed for schemas containing suite-paths and contexts by @jgebal in https://github.com/utPLSQL/utPLSQL/pull/1325
+ * Fixed issue with reporter failing to initialize by @jgebal in https://github.com/utPLSQL/utPLSQL/pull/1354
+ * Fixed issue with duplicate sources from dba_source by @jgebal in https://github.com/utPLSQL/utPLSQL/pull/1355
+ * Allow HTML coverage on FIPS-enabled DB by @jgebal in https://github.com/utPLSQL/utPLSQL/pull/1356
+
+
+ **Full Changelog**: https://github.com/utPLSQL/utPLSQL/compare/v3.2.01...v3.2.2
+ RELEASE_DATE: "2026-05-24 10:48:22"
+ RELEASE_URL: "https://github.com/utPLSQL/utPLSQL/releases/tag/v3.2.2"
+ TARGET_BRANCH: "develop"
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ token: ${{ env.API_TOKEN_GITHUB }}
+ - uses: c-py/action-dotenv-to-setenv@v5
+ with:
+ env-file: .github/variables/.env
+ - uses: FranzDiebold/github-env-vars-action@v2.8.0 #https://github.com/marketplace/actions/github-environment-variables-action
+
+# - name: Update CHANGELOG.md with release notes
+# run: .github/scripts/update_changelog.sh
+
+# - name: Post release announcement to org discussions
+# env:
+# GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }}
+# run: .github/scripts/post_release_announcement.sh
+
+# - name: Publish release post to utplsql.github.io
+# run: .github/scripts/publish_release_post.sh
+
diff --git a/BUILD_NO b/BUILD_NO
index 2bfcb2370..4a4c5f9fb 100644
--- a/BUILD_NO
+++ b/BUILD_NO
@@ -1 +1 @@
-4342
+4488
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..d304ab172
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,613 @@
+# Changelog
+
+All notable changes to utPLSQL are documented here.
+Releases are available on the [GitHub Releases page](https://github.com/utPLSQL/utPLSQL/releases).
+
+---
+
+## [v3.2.2] - 2026-05-24
+
+## What's Changed
+* Filtering by tags fixed for schemas containing suite-paths and contexts by @jgebal in [1325](https://github.com/utPLSQL/utPLSQL/pull/1325)
+* Fixed issue with reporter failing to initialize by @jgebal in [1354](https://github.com/utPLSQL/utPLSQL/pull/1354)
+* Fixed issue with duplicate sources from dba_source by @jgebal in [1355](https://github.com/utPLSQL/utPLSQL/pull/1355)
+* Allow HTML coverage on FIPS-enabled DB by @jgebal in [1356](https://github.com/utPLSQL/utPLSQL/pull/1356)
+
+
+**Full Changelog**: https://github.com/utPLSQL/utPLSQL/compare/v3.2.01...v3.2.2
+
+---
+
+## [v3.2.01] - 2026-04-22
+
+## Important
+ - Dropped support for Oracle Database versions older than 19c
+
+## New features
+ - Add TAP reporter by @WayneNani in [#1305](https://github.com/utPLSQL/utPLSQL/pull/1305)
+
+## Enhancements and bug fixes
+ - Added duplicate detection on cursor comparison using `join_by` by @lwasylow in [#1295](https://github.com/utPLSQL/utPLSQL/pull/1295)
+ - Fix code causing the object duration Oracle exception on oracle 23.26 by @lwasylow in [#1310](https://github.com/utPLSQL/utPLSQL/pull/1310)
+ - Packages with annotation-like comments are not test suites by @jgebal in [#1313](https://github.com/utPLSQL/utPLSQL/pull/1313)
+ - Performance improvements to annotation parsing by @lwasylow in [#1312](https://github.com/utPLSQL/utPLSQL/pull/1319)
+ - Updated documentation and copyright banners across source files @jgebal in [#1319](https://github.com/utPLSQL/utPLSQL/pull/1319)
+
+---
+
+## [v3.1.14] - 2024-02-19
+
+## New features
+
+ - Added support for `and` and `or` operators when running tests by tags by @lwasylow in [#1250](https://github.com/utPLSQL/utPLSQL/pull/1250)
+
+## Enhancements
+
+ - Allow for test runs over 4 hours by @jgebal in [#1243](https://github.com/utPLSQL/utPLSQL/pull/1243)
+ - Framework performance improvements by @jgebal in [#1249](https://github.com/utPLSQL/utPLSQL/pull/1249)
+ - Support multiple expectation failures with teamcity reporter by @jgebal in [#1251](https://github.com/utPLSQL/utPLSQL/pull/1251)
+ - Update TFS reporter to correct format by @lwasylow in [#1270](https://github.com/utPLSQL/utPLSQL/pull/1270)
+
+## Bug fixes
+
+ - Address issue where the `not_to(contain)` did not run correctly by @lwasylow in [#1246](https://github.com/utPLSQL/utPLSQL/pull/1246)
+ - Fix regex to be NLS_SORT independent by @jgebal in [#1253](https://github.com/utPLSQL/utPLSQL/pull/1253)
+ - Fix output length error and output buffer. by @jgebal in [#1255](https://github.com/utPLSQL/utPLSQL/pull/1255)
+ - (docs): Update running-unit-tests.md - remove example by @gassenmj in [#1261](https://github.com/utPLSQL/utPLSQL/pull/1261)
+ - The line-rate is not recorded for packages and classes in cobertura coverage reporter by @lwasylow in [#1269](https://github.com/utPLSQL/utPLSQL/pull/1269)
+ - (docs): Fix nested list issue by @iamrachid in [#1274](https://github.com/utPLSQL/utPLSQL/pull/1274)
+
+---
+
+## [v3.1.13] - 2022-12-11
+
+## New features
+
+ - Add ability to run tests by part of a name. Fixed in [#1203](https://github.com/utPLSQL/utPLSQL/pull/1203), resolves [#470](https://github.com/utPLSQL/utPLSQL/issues/470)
+
+## Enhancements
+
+ - Added documentation section on creating a custom reporter. Fixed in [#1225](https://github.com/utPLSQL/utPLSQL/pull/1225), resolves [#710](https://github.com/utPLSQL/utPLSQL/issues/701)
+ - Add ability to specify code coverage objects include/exclude masks as regular expressions. Fixed in [#1186](https://github.com/utPLSQL/utPLSQL/issues/1186), resolves [#1053](https://github.com/utPLSQL/utPLSQL/issues/1053)
+
+## Bug fixes
+
+ - Comparing collection that have long type names. Fixed in [#1238](https://github.com/utPLSQL/utPLSQL/issues/1238), resolves [#1235](https://github.com/utPLSQL/utPLSQL/issues/1235).
+ - Code coverage reporting on code with long lines. Fixed in [#1240](https://github.com/utPLSQL/utPLSQL/issues/1240), resolves [#1232](https://github.com/utPLSQL/utPLSQL/issues/1232), [#1087](https://github.com/utPLSQL/utPLSQL/issues/1087).
+ - Code coverage reporting does not exclude tests. Fixed in [#1226](https://github.com/utPLSQL/utPLSQL/issues/1226), resolves [#1222](https://github.com/utPLSQL/utPLSQL/issues/1222).
+ - Uninstall script buffer overflow. Fixed in [#1221](https://github.com/utPLSQL/utPLSQL/issues/1221), resolves [#1220](https://github.com/utPLSQL/utPLSQL/issues/1220).
+
+## Internal improvements
+
+ - Improved process of generating utPLSQL documentation. Implemented in [689bbd0](https://github.com/utPLSQL/utPLSQL/commit/689bbd0e365ed919315c29727bc10fbfc0dadce8), resolves [#1237](https://github.com/utPLSQL/utPLSQL/issues/1237).
+ - Removed username env variables for internal development. Implemented in [#1201](https://github.com/utPLSQL/utPLSQL/issues/1221), resolves [#1200](https://github.com/utPLSQL/utPLSQL/issues/1200).
+ - Test execution data of utPLSQL project not showing on SonarCloud. Implemented in [#1199](https://github.com/utPLSQL/utPLSQL/issues/1199), resolves [#1198](https://github.com/utPLSQL/utPLSQL/issues/1198).
+
+---
+
+## [v3.1.12] - 2022-02-25
+
+## New features
+ - Added support for description in the `--%disabled` annotation. See [documentation](https://github.com/utPLSQL/utPLSQL/blob/4515e0b5a3b4b0de0c2198db3235ef8614bff4d8/docs/userguide/annotations.md#disabled). Implemented in: [#1183](https://github.com/utPLSQL/utPLSQL/pull/1183), resolves [#610](https://github.com/utPLSQL/utPLSQL/issues/610).
+ - Added support for native `JSON` datatype on Oracle `21c`. Implemented in [#1181](https://github.com/utPLSQL/utPLSQL/pull/1181), resolves [#1114](https://github.com/utPLSQL/utPLSQL/issues/1114).
+ - Added new mather `to_be_within( distance|pct ).of_(expoected)`. See [documentation](https://github.com/utPLSQL/utPLSQL/blob/fd7ef9c14111a48e03fff7851f990c7192539170/docs/userguide/expectations.md#to_be_within-of). Implemented in [#1076](https://github.com/utPLSQL/utPLSQL/pull/1076), resolves [#77](https://github.com/utPLSQL/utPLSQL/issues/77).
+
+## Enhancements
+
+- Improved performance of SQL used to retrieve Coverage sources. Implemented in [#1187](https://github.com/utPLSQL/utPLSQL/pull/1187), resolves [#1169](https://github.com/utPLSQL/utPLSQL/issues/1169).
+- Added ability for utPLSQL to gather coverage on code invoking DBMS_STATS package. Implemented in [#1184](https://github.com/utPLSQL/utPLSQL/pull/1184), resolves [#1097](https://github.com/utPLSQL/utPLSQL/issues/1097), [#1094](https://github.com/utPLSQL/utPLSQL/issues/1094).
+- Fixed typos and improved documentation. Implemented in [#1173](https://github.com/utPLSQL/utPLSQL/pull/1173), [#1171](https://github.com/utPLSQL/utPLSQL/pull/1171)
+
+## Bug fixes
+
+- Actual and Expected are now correctly reported when comparing `JSON` data. Implemented in [#1181](https://github.com/utPLSQL/utPLSQL/pull/1181), resolves [#1113](https://github.com/utPLSQL/utPLSQL/issues/1113).
+- Packages with removed annotations are now correctly recognized as non-utPLSQL packages. Implemented in [#1180](https://github.com/utPLSQL/utPLSQL/pull/1180), resolves [#1177](https://github.com/utPLSQL/utPLSQL/issues/1177).
+- Fixed issues with comparison of nested object structures. Implemented in [#1179](https://github.com/utPLSQL/utPLSQL/pull/1179), resolves [#1082](https://github.com/utPLSQL/utPLSQL/issues/1082), [#1083](https://github.com/utPLSQL/utPLSQL/issues/1083), [#1098](https://github.com/utPLSQL/utPLSQL/issues/1098).
+
+## Internal improvements
+
+- Moved build and test process for utPLSQL from Travis to GithubActions. Implemented in [#1175](https://github.com/utPLSQL/utPLSQL/pull/1175)
+
+---
+
+## [v3.1.11] - 2021-11-17
+
+## Enhancements
+
+- utPLSQL can now be used to generate coverage reports for external tools. See [documentation](https://github.com/utPLSQL/utPLSQL/blob/955de5c2dc527a98a6f5dc0dd8bd8d81a44c459f/docs/userguide/coverage.md#reporting-coverage-outside-of-utplsql)
+ Implemented in: [#1079](https://github.com/utPLSQL/utPLSQL/pull/1079), resolves [#1025](https://github.com/utPLSQL/utPLSQL/issues/1025)
+- Enhanced UT_COVERAGE_COBERTURA_REPORTER to better support TFS and GitLab. Implemented in [#1137](https://github.com/utPLSQL/utPLSQL/pull/1137) and [#1140](https://github.com/utPLSQL/utPLSQL/pull/1140), resolves [#1107](https://github.com/utPLSQL/utPLSQL/issues/1107)
+- Added support for installation on Oracle 21c - removed dependency on DBMS_OBFUSCATION_TOOLKIT. Implemented in [#1112](https://github.com/utPLSQL/utPLSQL/pull/1112), resolves [#1111](https://github.com/utPLSQL/utPLSQL/issues/1111) and [#1127](https://github.com/utPLSQL/utPLSQL/issues/1127)
+- Added support for running utPLSQL framework in parallel-enabled database. Implemented in [#1160](https://github.com/utPLSQL/utPLSQL/pull/1160), resolves [#1134](https://github.com/utPLSQL/utPLSQL/issues/1134)
+
+## Bug fixes
+
+- Suite structure is built properly even with other than English TNS settings. Implemented in [#1061](https://github.com/utPLSQL/utPLSQL/pull/1061), resolves [#1060](https://github.com/utPLSQL/utPLSQL/issues/1060)
+- Fixed XML content reporting (CDATA) in UT_REALTIME_REPORTER used by SQLDeveloper plugin. Implemented in [#1075](https://github.com/utPLSQL/utPLSQL/pull/1075), resolves [#1073](https://github.com/utPLSQL/utPLSQL/issues/1073)
+- Fixed XML content reporting (CDATA) in JUnit reporter - regression. Implemented in [#1085](https://github.com/utPLSQL/utPLSQL/pull/1085), resolves [#1084](https://github.com/utPLSQL/utPLSQL/issues/1084)
+- Fixed issue with utPLSQL failing to run coverage reporting when trigger has overlapping name with procedure/function/package/type. Implemented in [#1091](https://github.com/utPLSQL/utPLSQL/pull/1091), resolves [#1086](https://github.com/utPLSQL/utPLSQL/issues/1086)
+- Fixed issue with parsing utPLSQL suites with DDL trigger when usign AUTHID clause. Implemented in [#1093](https://github.com/utPLSQL/utPLSQL/pull/1093), resolves [#1088](https://github.com/utPLSQL/utPLSQL/issues/1088)
+
+## Internal improvements
+
+- Improved how privilege checks are handled by framework installation. Implemented in [#1056](https://github.com/utPLSQL/utPLSQL/pull/1056), resolves [#1050](https://github.com/utPLSQL/utPLSQL/issues/1050)
+- Restructured installation instructions to make it more readable. Implemented in [#1063](https://github.com/utPLSQL/utPLSQL/pull/1063), resolves [#1062](https://github.com/utPLSQL/utPLSQL/issues/1062)
+- Updated database requirements in documentation. Implemented in [#1065](https://github.com/utPLSQL/utPLSQL/pull/1065), resolves [#1064](https://github.com/utPLSQL/utPLSQL/issues/1064)
+- Removed duplicated call to install profiler tables. Implemented in [#1164](https://github.com/utPLSQL/utPLSQL/pull/1164), resolves [#1149](https://github.com/utPLSQL/utPLSQL/issues/1149)
+- Fixed failing internal framework tests on Oracle 21c. Implemented in [#1158](https://github.com/utPLSQL/utPLSQL/pull/1158), resolves [#1151](https://github.com/utPLSQL/utPLSQL/issues/1151)
+- Fixed confusing typo in documentation. Resolves [#1154](https://github.com/utPLSQL/utPLSQL/issues/1154)
+- Moved build process from travis-ci.org to travis-ci.com. Implemented in [#1152](https://github.com/utPLSQL/utPLSQL/pull/1152)
+- Added an example of reporter reporting all expectations, not only the failing ones. Implemented in [#1092](https://github.com/utPLSQL/utPLSQL/pull/1092)
+
+---
+
+## [v3.1.10] - 2020-02-23
+
+## Enhancements
+
+- utPLSQL test runner is now validating arguments of `--%throws` annotations at runtime [#721](https://github.com/utPLSQL/utPLSQL/issues/721) [#1033](https://github.com/utPLSQL/utPLSQL/issues/1033)
+- Documented limitations of insignificant spaces comparison in compound data [#880](https://github.com/utPLSQL/utPLSQL/issues/880)
+- utPLSQL will now detect empty annotation cache for schema even with DLL trigger enabled [#975](https://github.com/utPLSQL/utPLSQL/issues/975)
+- Order of procedures and annotation now determines default order of tests in suite [#1036](https://github.com/utPLSQL/utPLSQL/issues/1036)
+
+## Bug fixes
+
+- Nested contexts are now properly identified [#1034](https://github.com/utPLSQL/utPLSQL/issues/1034)
+- TeamCity test reporter is now including error message [#1045](https://github.com/utPLSQL/utPLSQL/issues/1045)
+
+## Internal improvements
+
+- All self-tests for utPLSQL framework can now be executed using test-owner schema [#969](https://github.com/utPLSQL/utPLSQL/issues/969)
+- Misleading rollback warning is no longer showing when running self-tests for utPLSQL [#982](https://github.com/utPLSQL/utPLSQL/issues/982)
+
+---
+
+## [v3.1.9] - 2019-11-10
+
+## New features
+
+- Added ability to define [nested contexts](https://github.com/utPLSQL/utPLSQL/blob/v3.1.9/docs/userguide/annotations.md#context) within test suite [#938](https://github.com/utPLSQL/utPLSQL/issues/938)
+- Added ability to [exclude tests/suites by tags](https://github.com/utPLSQL/utPLSQL/blob/v3.1.9/docs/userguide/annotations.md#excluding-testssuites-by-tags) when invoking a test-run [#1007](https://github.com/utPLSQL/utPLSQL/issues/1007) [#983](https://github.com/utPLSQL/utPLSQL/issues/983)
+- Added new annotation [`--%name`](https://github.com/utPLSQL/utPLSQL/blob/v3.1.9/docs/userguide/annotations.md#name) to allow for providing custom name for contexts [#1016](https://github.com/utPLSQL/utPLSQL/issues/1016)
+
+## Important changes
+
+The value of `--%context` annotation is no longer representing context `name`.
+This value is now context description (displayname).
+With this change, the `--%context` annotation is now aligned with `--%test` and `--%suite` annotation syntax.
+
+New annotation `--%name` was introduced to facilitate naming of contexts.
+
+## Enhancements
+
+- Improved documentation for running tests
+- Improved documentation for tags [#1003](https://github.com/utPLSQL/utPLSQL/issues/1003)
+- Improved documentation for annotations
+
+## Bug fixes
+
+- Fixed bug with bad stacktrace showing in failing/erroring test [#1000](https://github.com/utPLSQL/utPLSQL/issues/1000)
+- Fixed issue with lack of validation for context name [#966](https://github.com/utPLSQL/utPLSQL/issues/966)
+- Fixed problem with install script privilege check for installation with DDL trigger [#992](https://github.com/utPLSQL/utPLSQL/issues/992)
+- Fixed issue with some common column names causing cursor comparison to fail [#997](https://github.com/utPLSQL/utPLSQL/issues/997)
+- Fixed issue with invocation of standalone expectations on cursor [#998](https://github.com/utPLSQL/utPLSQL/issues/998)
+
+## Internal improvements
+
+- Fixed runability of utplsql self-tests [#968](https://github.com/utPLSQL/utPLSQL/issues/968)
+
+---
+
+## [v3.1.8] - 2019-09-03
+
+## New features
+
+- Added support for [session context](https://github.com/utPLSQL/utPLSQL/blob/v3.1.8/docs/userguide/annotations.md#sys_context) to provide test and suite information during test run [#963](https://github.com/utPLSQL/utPLSQL/issues/963) [#781](https://github.com/utPLSQL/utPLSQL/issues/781)
+- Added ability to [invoke expectations without running framework](https://github.com/utPLSQL/utPLSQL/blob/v3.1.8/docs/userguide/expectations.md#running-expectations-outside-utplsql-framework) [#956](https://github.com/utPLSQL/utPLSQL/issues/956) [#963](https://github.com/utPLSQL/utPLSQL/issues/963)
+- Failing expectations are now reported with call stack [#967](https://github.com/utPLSQL/utPLSQL/issues/967) [#963](https://github.com/utPLSQL/utPLSQL/issues/963)
+
+## Enhancements
+
+- Improved framework table private data protection [#922](https://github.com/utPLSQL/utPLSQL/issues/922) [#954](https://github.com/utPLSQL/utPLSQL/issues/954)
+- Improved install process. It is now unified for installation with both public and private synonyms [#957](https://github.com/utPLSQL/utPLSQL/issues/957) [#954](https://github.com/utPLSQL/utPLSQL/issues/954)
+- Improved reporting of warnings for integration with SQLDeveloper [#964](https://github.com/utPLSQL/utPLSQL/issues/964)
+- Improved query to retrieve coverage sources [#981](https://github.com/utPLSQL/utPLSQL/issues/981) [#970](https://github.com/utPLSQL/utPLSQL/issues/970)
+- Improved security around malicious utPLSQL owner name [#920](https://github.com/utPLSQL/utPLSQL/issues/920)
+
+## Bug fixes
+
+- Fixed cursor comparison on Oracle 11.2 [#947](https://github.com/utPLSQL/utPLSQL/issues/947)
+- Fixed issue with retrieving suite data [#977](https://github.com/utPLSQL/utPLSQL/issues/977) [#974](https://github.com/utPLSQL/utPLSQL/issues/974) [#978](https://github.com/utPLSQL/utPLSQL/issues/978)
+- Application context is now reset in session after test run [#951](https://github.com/utPLSQL/utPLSQL/issues/951)
+
+---
+
+## [v3.1.7] - 2019-06-18
+
+## New features
+
+- Added support for [comparing `json`](https://github.com/utPLSQL/utPLSQL/blob/v3.1.7/docs/userguide/expectations.md#comparing-json-objects) in Oracle 12.2 and above [#924](https://github.com/utPLSQL/utPLSQL/issues/924)
+- Introduced [`tag` annotation](https://github.com/utPLSQL/utPLSQL/blob/v3.1.7/docs/userguide/annotations.md#tags) to enable tagging of tests and suites [#66](https://github.com/utPLSQL/utPLSQL/issues/66)
+- Added support for [random order](https://github.com/utPLSQL/utPLSQL/blob/v3.1.7/docs/userguide/running-unit-tests.md#random-order) of test execution [#422](https://github.com/utPLSQL/utPLSQL/issues/422)
+
+## Enhancements
+
+- Added optional [install with DDL trigger](https://github.com/utPLSQL/utPLSQL/blob/v3.1.7/docs/userguide/install.md#installation-with-ddl-trigger) to speed up framework start [#901](https://github.com/utPLSQL/utPLSQL/issues/901)
+- Removed dependency on `dbms_utility.name_resolve` [#569](https://github.com/utPLSQL/utPLSQL/issues/569) [#885](https://github.com/utPLSQL/utPLSQL/issues/885)
+- New output buffer table structures improving performance and addressing timeout issues [#915](https://github.com/utPLSQL/utPLSQL/issues/915)
+
+## Bug fixes
+
+- Fixed `ut_realtime_reporter` missing warnings in test and suite output structures [#936](https://github.com/utPLSQL/utPLSQL/issues/936)
+- Fixed output_buffer purging error [#934](https://github.com/utPLSQL/utPLSQL/issues/934)
+- Fixed `join_by / exclude / include` invalid syntax on collection in anydata compare [#912](https://github.com/utPLSQL/utPLSQL/issues/912)
+- Fixed `ut_junit_reporter` producing invalid output on failing tests with long failure message [#927](https://github.com/utPLSQL/utPLSQL/issues/927)
+- Fixed `ut_sonar_test_reporter` producing invalid output on failing tests with long failure message [#925](https://github.com/utPLSQL/utPLSQL/issues/925)
+- Fixed `ut_coverage_cobertura_reporter` producing wrong line breaks which breaks the xml validation against DTD [#917](https://github.com/utPLSQL/utPLSQL/issues/917)
+- Fixed `exclude` option for ref cursor where column order was not resolved correctly [#911](https://github.com/utPLSQL/utPLSQL/issues/911)
+- Fixed `unordered` option for ref cursor with null values [#914](https://github.com/utPLSQL/utPLSQL/issues/914)
+- Fixed number precision when selecting from dual [#907](https://github.com/utPLSQL/utPLSQL/issues/907)
+- Fixed ref cursor errors with generated column names [#902](https://github.com/utPLSQL/utPLSQL/issues/902)
+- Fixed `ORA-00907` when comparing ref cursors with BINARY_ columns [#899](https://github.com/utPLSQL/utPLSQL/issues/899)
+- Fixed wrong results when comparing CLOBs with `to_be_like` in Oracle Database 11.2.0.4 due to Oracle Bug 14402514 [#891](https://github.com/utPLSQL/utPLSQL/issues/891)
+- Fixed performance issue with code coverage report on huge PL/SQL code base [#882](https://github.com/utPLSQL/utPLSQL/issues/882)
+
+## Documentation improvements
+
+- Added install instructions for DDL trigger [#874](https://github.com/utPLSQL/utPLSQL/issues/874)
+
+## Internal enhancements
+
+- Fixed SQL vulnerability on all input parameters used in dynamic SQL and PL/SQL [#921](https://github.com/utPLSQL/utPLSQL/issues/921)
+- Fixed message id in output buffer [#916](https://github.com/utPLSQL/utPLSQL/issues/916)
+- Included 19c database in self testing [#909](https://github.com/utPLSQL/utPLSQL/issues/909)
+- Introduced testing with multiple schemas and different grants [#893](https://github.com/utPLSQL/utPLSQL/issues/893)
+- Fixed installation script warnings [#879](https://github.com/utPLSQL/utPLSQL/issues/879)
+
+---
+
+## [v3.1.6] - 2019-03-24
+
+Bugfix release for `v3.1.5`
+
+## Bug fixes
+
+- Fixed a bug in release `3.1.5` where `to_equal` matcher was failing due to privileges when comparing non sql diffable types [#870](https://github.com/utPLSQL/utPLSQL/issues/870)
+
+## Improvements
+- Reduced number of information displaying about user defined type. We will now display only type name instead of full structure [#866](https://github.com/utPLSQL/utPLSQL/issues/866)
+
+---
+
+## [v3.1.5] - 2019-03-20
+
+Bugfix release for `v3.1.4`
+
+## Bug fixes
+
+- Fixed a bug in release `3.1.4` where `to_be_empty` matcher was failing due to privileges [#864](https://github.com/utPLSQL/utPLSQL/issues/864)
+
+---
+
+## [v3.1.4] - 2019-03-19
+
+**This release contains a bug that is fixed by release 3.1.5**
+Please use release 3.1.5 rather than this release.
+
+## New features
+
+- Added `to_contain` matcher for collections and cursors [#79](https://github.com/utPLSQL/utPLSQL/issues/79)
+- Added `unordered_columns` (`uc`) option for cursor comparison to ignore the order of the columns [#779](https://github.com/utPLSQL/utPLSQL/issues/779)
+- Added `ut_debug_reporter` for debug logging [#480](https://github.com/utPLSQL/utPLSQL/issues/480)
+- Added `ut_realtime_reporter` for utPLSQL-SQLDeveloper extension [#795](https://github.com/utPLSQL/utPLSQL/issues/795)
+
+## Important Changes
+
+- Due to improvements of the cursor comparison, it is now necessary to use `ut.set_nls()` before creating the cursor and `ut.reset_nls()` after the __expectation__ when comparing dates. [More info in the docs](https://github.com/utPLSQL/utPLSQL/blob/v3.1.4/docs/userguide/expectations.md#comparing-cursor-data-containing-date-fields)
+
+## Enhancements
+
+- Improved performance of cursor comparison [#780](https://github.com/utPLSQL/utPLSQL/issues/780)
+- Added support for installation on databases with block size < 8KB [#848](https://github.com/utPLSQL/utPLSQL/issues/848)
+- Added initial timeout to `ut_output_buffer` [#840](https://github.com/utPLSQL/utPLSQL/issues/840)
+- Enhanced performance of `get_reporters_list` function [#814](https://github.com/utPLSQL/utPLSQL/issues/814)
+- Moved calls of `dbms_lock.sleep` to `dbms_session` for newer DB versions [#806](https://github.com/utPLSQL/utPLSQL/issues/806)
+- utPLSQL coverage will now work without re-install after DB-upgrade from 12.1 to 12.2 [#803](https://github.com/utPLSQL/utPLSQL/issues/803)
+
+## Bug fixes
+
+- Fixed problem with REGEXP in annotation parsing with NLS CANADIAN FRENCH [#844](https://github.com/utPLSQL/utPLSQL/issues/844)
+- Fixed issue with Rollback to savepoint failing on distributed transaction [#839](https://github.com/utPLSQL/utPLSQL/issues/839)
+- Fixed reporting of differences when comparing collections scalar values [#835](https://github.com/utPLSQL/utPLSQL/issues/835)
+- Fixed issue with test run failing due to too many transaction invalidators [#834](https://github.com/utPLSQL/utPLSQL/issues/834)
+- Fixed randomly occurring error during cursor comparison [#827](https://github.com/utPLSQL/utPLSQL/issues/827)
+- utPLSQL install script will now support special characters in passwords [#804](https://github.com/utPLSQL/utPLSQL/issues/804)
+
+## Documentation improvements
+
+- Fixed documentation examples for context annotation [#851](https://github.com/utPLSQL/utPLSQL/issues/851)
+- Added description on how to check version of utPLSQL [#822](https://github.com/utPLSQL/utPLSQL/issues/822)
+
+## Internal enhancements
+
+- Implemented Sonar analysis on DBA Views [#850](https://github.com/utPLSQL/utPLSQL/issues/850)
+- Finished migration from old-tests [#475](https://github.com/utPLSQL/utPLSQL/issues/475)
+- Fixed shell scripts to support multiple unix dialects (especially for macOS) [#796](https://github.com/utPLSQL/utPLSQL/issues/796)
+- Added info on project support from Redgate [#841](https://github.com/utPLSQL/utPLSQL/issues/841)
+- Added `code_of_conduct` [#836](https://github.com/utPLSQL/utPLSQL/issues/836)
+- Added issue templates [#842](https://github.com/utPLSQL/utPLSQL/issues/842)
+- Added utPLSQL logo [#845](https://github.com/utPLSQL/utPLSQL/issues/845)
+
+---
+
+## [v3.1.3] - 2018-11-20
+
+## New features
+
+- added function `ut_runner.is_test` [#788](https://github.com/utPLSQL/utPLSQL/issues/788)
+- added function `ut_runner.is_suite` [#787](https://github.com/utPLSQL/utPLSQL/issues/787)
+- added function `ut_runner.has_suites` [#786](https://github.com/utPLSQL/utPLSQL/issues/786)
+- added ability to disable automatic rollback for a test-run [#784](https://github.com/utPLSQL/utPLSQL/issues/784)
+- when invoked with package name, utPLSQL will now run only tests from specified package even if package has child packages by suitepath [#776](https://github.com/utPLSQL/utPLSQL/issues/776)
+
+## Enhancements
+
+- Improved performance of schema-scanning and utPLSQL startup [#778](https://github.com/utPLSQL/utPLSQL/issues/778)
+- Improved performance of output-buffer [#777](https://github.com/utPLSQL/utPLSQL/issues/777)
+- Improved documentation to mention ability to pass client encoding for HTML & XML reports [#775](https://github.com/utPLSQL/utPLSQL/issues/775)
+- Improved documentation for cursor comparison to mention challenges with TIMESTAMP bind variables
+
+## Bug-fixes
+
+- utPLSQL code coverage will now work properly with long object names [#716](https://github.com/utPLSQL/utPLSQL/issues/716)
+- utPLSQL installation will now also work properly, when user performing the install has `ANY` grants [#737](https://github.com/utPLSQL/utPLSQL/issues/737)
+- fixed documentation bug for `--%context` with `--%displayname` [#726](https://github.com/utPLSQL/utPLSQL/issues/726)
+- fixed Teamcity reporter issues with missing escape for some characters and long messages [#747](https://github.com/utPLSQL/utPLSQL/issues/747)
+- fixed issue with sonar test results reporter when contexts are used [#749](https://github.com/utPLSQL/utPLSQL/issues/749)
+- fixed issue with ORA-07455 getting thrown on cursor comparison [#752](https://github.com/utPLSQL/utPLSQL/issues/752)
+- fixed issue with wrong failure message for unordered data [#764](https://github.com/utPLSQL/utPLSQL/issues/764)
+- fixed missing privilege issue for unordered/join-by cursor data comparison [#765](https://github.com/utPLSQL/utPLSQL/issues/765) [#770](https://github.com/utPLSQL/utPLSQL/issues/770)
+
+## Internal enhancements
+
+- added suite-level cache to allow for faster retrieval of suite contents and enable implementation of additional features [#783](https://github.com/utPLSQL/utPLSQL/issues/783)
+
+---
+
+## [v3.1.2] - 2018-07-22
+
+## New features
+
+- Added ability to join and compare cursor content by specific columns (PK/UK) [#453](https://github.com/utPLSQL/utPLSQL/issues/453)
+- Added support for comma separated list of suite paths/packages when calling `ut.run` [#479](https://github.com/utPLSQL/utPLSQL/issues/479)
+- Added ability to run a test package that got invalidated due to dependency invalidation [#489](https://github.com/utPLSQL/utPLSQL/issues/489)
+- Added support for package level constants and predefined exceptions in `--%throws` annotation [#685](https://github.com/utPLSQL/utPLSQL/issues/685)
+- Added support for standalone `--%beforeall`, `--%beforeeach`, `--%afterall`, `--%aftereach` annotations with list of procedures to execute [#649](https://github.com/utPLSQL/utPLSQL/issues/649)
+- Added support for list of procedure names in before/after annotations [#649](https://github.com/utPLSQL/utPLSQL/issues/649)
+- Added support for BLOB/CLOB in `is_empty()` matcher [#707](https://github.com/utPLSQL/utPLSQL/issues/707)
+
+## Enhancements
+
+- utPLSQL will now provide additional warnings, when unsupported annotations are found in a unit test suite package [#624](https://github.com/utPLSQL/utPLSQL/issues/624)
+- utPLSQL will now produce valid XML in UT_JUNIT_REPORTER when dbms_output or test results contain `1 |
| **Test Output** | | |
| Real-time test execution progress reporting | No | Yes |
diff --git a/docs/index.md b/docs/index.md
index 459bc9535..71f9cdc83 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 c0cbffb0e..5d37731f4 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 3dc42e429..e075cd4cb 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.
@@ -23,8 +23,8 @@ In below example we have a `suite` annotation with `Stuff) -- we should name thi
Do not place comments within annotation line to avoid unexpected behaviors.
-**Note:**
->Annotations are interpreted only in the package specification and are case-insensitive. We strongly recommend using lower-case annotations as described in this documentation.
+!!! note
+ Annotations are interpreted only in the package specification and are case-insensitive. We strongly recommend using lower-case annotations as described in this documentation.
There are two distinct types of annotations, identified by their location in package.
- package annotations
@@ -46,7 +46,7 @@ package test_package is
--%disabled
procedure my_first_procedure;
- $if dbms_db_version.version >= 12 $then --This is ok - annotation before procedure
+ $if dbms_db_version.version >= 19 $then --This is ok - annotation before procedure
--%test()
procedure my_first_procedure;
$end
@@ -71,7 +71,7 @@ package test_package is
procedure proc1;
--%test() --This is wrong as there is a compiler directive between procedure and annotation
- $if dbms_db_version.version >= 12 $then
+ $if dbms_db_version.version >= 19 $then
procedure proc_12;
$end
@@ -151,15 +151,13 @@ The `--%suite` annotation denotes PLSQL package as a unit test suite.
It accepts an optional description that will be visible when running the tests.
When description is not provided, package name is displayed on report.
-**Note**
->Package is considered a test-suite only when package specification contains the `--%suite` annotation at the package level.
->
->Some annotations like `--%suite`, `--%test` and `--%displayname` accept parameters. The parameters for annotations need to be placed in brackets.
-Values for parameters should be provided without any quotation marks.
-If the parameters are placed without brackets or with incomplete brackets, they will be ignored.
->
->Example: `--%suite(The name of suite without closing bracket`
->Example: `--%suite The name of suite without brackets`
+!!! note
+ Package is considered a test-suite only when package specification contains the `--%suite` annotation at the package level.
+ Some annotations like `--%suite`, `--%test` and `--%displayname` accept parameters. The parameters for annotations need to be placed in brackets.
+ Values for parameters should be provided without any quotation marks.
+ If the parameters are placed without brackets or with incomplete brackets, they will be ignored.
+ Example: `--%suite(The name of suite without closing bracket`
+ Example: `--%suite The name of suite without brackets`
Suite package without description.
@@ -459,7 +457,7 @@ Finished in .005868 seconds
### Beforeall
-There are two possible ways to use the `--%beforeall` annotation.
+There are two possible ways to use the `--%beforeall` annotation.
As a procedure level annotation:
```sql linenums="1"
@@ -545,7 +543,7 @@ Finished in .012292 seconds
```
In the below example a combination pacakge and procedure level `--%beforeall` annotations is used.
-The order of execution of the beforeall procedures is determined by the annotation position in package.
+The execution order of the `--%beforeall` procedures is determined by the annotation position in the package.
All of the `--%beforeall` procedures get invoked before any test is executed in a suite.
```sql linenums="1"
create or replace package test_package as
@@ -672,6 +670,8 @@ Finished in .012158 seconds
2 tests, 0 failed, 0 errored, 0 disabled, 2 warning(s)
```
+!!! note "Suite scope"
+ The `--%beforeall` procedrues in parent suite package are always part of all suite packages that are children on the suitepath.
### Afterall
@@ -759,6 +759,10 @@ Finished in .014161 seconds
2 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)
```
+!!! note "Suite scope"
+ The `--%afterall` procedrues in parent suite package are always part of all suite packages that are children on the suitepath.
+
+
### Beforeeach
The procedure annotated as `--%beforeeach` is getting executed before each test in a suite.
@@ -868,6 +872,9 @@ Finished in .014683 seconds
2 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)
```
+!!! note "Package scope"
+ Unlike `--%beforeall`, the `--%beforeeach` annotation is only applicable within the scope of current test suite package. The `--%beforeeach` annotations from parent suite package are ignored.
+
See [beforeall](#Beforeall) for more examples.
### Aftereach
@@ -977,6 +984,9 @@ Finished in .018115 seconds
2 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)
```
+!!! note "Package scope"
+ Unlike `--%afterall`, the `--%aftereach` annotation is only applicable within the scope of current test suite package. The `--%aftereach` annotations from parent suite package are ignored.
+
See [beforeall](#Beforeall) for more examples.
### Beforetest
@@ -1715,6 +1725,8 @@ When executing tests, `path` for executing tests can be provided in three ways:
* [schema]:suite1[.suite2][.suite3]...[.procedure] - execute all tests by `suitepath` in all suites on path suite1[.suite2][.suite3]...[.procedure]. If schema is not provided, then the current schema is used. Example: `:all.rooms_tests`
* [schema.]package[.procedure] - execute all tests in the specified test package. The whole hierarchy of suites in the schema is built before all before/after hooks or part suites for the provided suite package are executed as well. Example: `tests.test_contact.test_last_name_validator` or simply `test_contact.test_last_name_validator` if `tests` is the current schema.
+!!! note
+ Only the `beforeall` and `afterall` hooks of the parent suite are executed for the suite package. The `beforeeach` and `aftereach` hooks of the suite package are not executed.
### Rollback
@@ -1740,12 +1752,12 @@ Doing so allows your tests to use the framework's automatic transaction control
When you are testing code that performs explicit or implicit commits, you may set the test procedure to run as an autonomous transaction with `pragma autonomous_transaction`.
Keep in mind that when your test runs as autonomous transaction it will not see the data prepared in a setup procedure unless the setup procedure committed the changes.
-**Note**
-> The `--%suitepath` annotation, when used, must be provided with a value of path.
-> The path in suitepath cannot contain spaces. Dot (.) identifies individual elements of the path.
->
-> Example: `--%suitepath(org.utplsql.core.utils)`
->
+!!! note
+ The `--%rollback(manual)` annotation is only relevant for suites that use shared setup/cleanup with beforeall,
+ The `--%suitepath` annotation, when used, must be provided with a value of path.
+ The path in suitepath cannot contain spaces. Dot (.) identifies individual elements of the path.
+ Example: `--%suitepath(org.utplsql.core.utils)`
+
### Throws
@@ -1753,11 +1765,11 @@ Keep in mind that when your test runs as autonomous transaction it will not see
The `--%throws` annotation allows you to specify a list of exceptions as one of:
- number literals - example `--%throws(-20134)`
-- variables of type exception defined in a package specification - example `--%throws(exc_pkg.c_exception_No_variable)`
-- variables of type number defined in a package specification - example `--%throws(exc_pkg.c_some_exception)`
-- [predefined oracle exceptions](https://docs.oracle.com/cd/E11882_01/timesten.112/e21639/exceptions.htm#CIHFIGFE) - example `--%throws(no_data_found)`
+- variables of type `exception` defined in a package specification - example `--%throws(exc_pkg.c_exception_no_variable)`
+- variables or constants of containing a valid negative exception number defined in a package specification - example `--%throws(exc_pkg.c_some_exception)`
+- [predefined oracle exceptions](https://docs.oracle.com/en//database/oracle/oracle-database/19/lnpls/predefined-exceptions.html) - example `--%throws(no_data_found)`
-The annotation is ignored, when no valid arguments are provided. Examples of invalid annotations `--%throws()`,`--%throws`, `--%throws(abe, 723pf)`.
+The annotation is ignored when no valid arguments are provided. Examples of invalid annotations `--%throws()`,`--%throws`, `--%throws(abe, 723pf)`.
If `--%throws` annotation is specified with arguments and no exception is raised, the test is marked as failed.
@@ -1768,22 +1780,30 @@ The framework will raise a warning, when `--%throws` annotation has invalid argu
Annotation `--%throws(7894562, operaqk, -=1, -20496, pow74d, posdfk3)` will be interpreted as `--%throws(-20496)`.
Please note that `NO_DATA_FOUND` exception is a special case in Oracle. To capture it use `NO_DATA_FOUND` named exception or `-1403` exception No.
-
+
+Syntax: `--%throws( [[schema.]package.]exception [, ... ])`
+
+The exception name can be provided with or without the schema and package name. The package name is required only when the exception variable is located in another package than the unit test package. The schema name is required only when the exception variable is located in a package in another schema.
+
Example:
```sql linenums="1"
create or replace package exc_pkg is
c_e_option1 constant number := -20200;
c_e_option2 constant varchar2(10) := '-20201';
- c_e_option3 number := -20202;
-
- e_option4 exception;
- pragma exception_init(e_option4, -20203);
+ c_e_option3 integer := -20202;
+ e_initialized_exception exception;
+ pragma exception_init(e_initialized_exception, -20203);
+
+ e_uninitialized_exception exception;
end;
/
create or replace package example_pgk as
+ e_local_exception exception;
+ e_local_exception_num constant integer := -20123;
+
--%suite(Example Throws Annotation)
--%test(Throws one of the listed exceptions)
@@ -1814,10 +1834,22 @@ create or replace package example_pgk as
--%throws(exc_pkg.c_e_option3)
procedure raised_option3_exception;
- --%test(Throws package exception option4)
- --%throws(exc_pkg.e_option4)
- procedure raised_option4_exception;
+ --%test(Throws exception associated with exception number)
+ --%throws(exc_pkg.e_initialized_exception)
+ procedure raised_initialized_exception;
+
+ --%test(Throws uninitialized exception)
+ --%throws(exc_pkg.e_uninitialized_exception)
+ procedure raised_uninitialized_exception;
+ --%test(Throws exception local to unit tests package)
+ --%throws(e_local_exception)
+ procedure raised_local_exception;
+
+ --%test(Throws exception local to unit tests package with exception number)
+ --%throws(e_local_exception_num)
+ procedure raised_local_exception_num;
+
--%test(Raise name exception)
--%throws(DUP_VAL_ON_INDEX)
procedure raise_named_exc;
@@ -1828,6 +1860,7 @@ create or replace package example_pgk as
end;
/
+
create or replace package body example_pgk is
procedure raised_one_listed_exception is
begin
@@ -1864,11 +1897,28 @@ create or replace package body example_pgk is
raise_application_error(exc_pkg.c_e_option3, 'Test error');
end;
- procedure raised_option4_exception is
+ procedure raised_initialized_exception is
+ begin
+ raise exc_pkg.e_initialized_exception;
+ end;
+
+ procedure raised_uninitialized_exception is
+ begin
+ raise exc_pkg.e_uninitialized_exception;
+ end;
+
+ procedure raised_local_exception is
+ pragma autonomous_transaction;
begin
- raise exc_pkg.e_option4;
+ raise e_local_exception;
end;
+ procedure raised_local_exception_num is
+ pragma autonomous_transaction;
+ begin
+ raise_application_error(e_local_exception_num, 'Test error');
+ end;
+
procedure raise_named_exc is
begin
raise DUP_VAL_ON_INDEX;
@@ -1887,48 +1937,55 @@ exec ut3.ut.run('example_pgk');
Running the test will give report:
```
Example Throws Annotation
- Throws one of the listed exceptions [.002 sec]
- Throws different exception than expected [.002 sec] (FAILED - 1)
- Throws different exception than listed [.003 sec] (FAILED - 2)
- Gives failure when an exception is expected and nothing is thrown [.002 sec] (FAILED - 3)
- Throws package exception option1 [.003 sec]
- Throws package exception option2 [.002 sec]
- Throws package exception option3 [.002 sec]
- Throws package exception option4 [.002 sec]
- Raise name exception [.002 sec]
- Invalid throws annotation [.002 sec]
-
+ Throws one of the listed exceptions [,026 sec]
+ Throws different exception than expected [,009 sec] (FAILED - 1)
+ Throws different exception than listed [,014 sec] (FAILED - 2)
+ Gives failure when an exception is expected and nothing is thrown [,016 sec] (FAILED - 3)
+ SUCCESS
+ Actual: 1 (number) was expected to equal: 1 (number)
+ Throws package exception option1 [,007 sec]
+ Throws package exception option2 [,008 sec]
+ Throws package exception option3 [,007 sec]
+ Throws exception associated with exception number [,006 sec]
+ Throws uninitialized exception [,006 sec]
+ Throws exception local to unit tests package [,009 sec]
+ Throws exception local to unit tests package with exception number [,011 sec]
+ Raise name exception [,006 sec]
+ Invalid throws annotation [,004 sec]
+
Failures:
-
+
1) raised_different_exception
Actual: -20143 was expected to equal: -20144
ORA-20143: Test error
- ORA-06512: at "UT3.EXAMPLE_PGK", line 9
- ORA-06512: at "UT3.EXAMPLE_PGK", line 9
- ORA-06512: at line 6
-
+ ORA-06512: at "UT3_TESTER.EXAMPLE_PGK", line 9
+ ORA-06512: at "UT3_TESTER.EXAMPLE_PGK", line 9
+ ORA-06512: at line 7
+
2) raised_unlisted_exception
Actual: -20143 was expected to be one of: (-20144, -1, -20145)
ORA-20143: Test error
- ORA-06512: at "UT3.EXAMPLE_PGK", line 14
- ORA-06512: at "UT3.EXAMPLE_PGK", line 14
- ORA-06512: at line 6
-
+ ORA-06512: at "UT3_TESTER.EXAMPLE_PGK", line 14
+ ORA-06512: at "UT3_TESTER.EXAMPLE_PGK", line 14
+ ORA-06512: at line 7
+
3) nothing_thrown
Expected one of exceptions (-20459, -20136, -20145) but nothing was raised.
-
-
+
+
Warnings:
-
- 1) example_pgk
+
+ 1) example_pgk.raised_one_listed_exception
Invalid parameter value "bad" for "--%throws" annotation. Parameter ignored.
- at "UT3.EXAMPLE_PGK.RAISED_ONE_LISTED_EXCEPTION", line 6
+ at package "UT3_TESTER.EXAMPLE_PGK.RAISED_ONE_LISTED_EXCEPTION", line 8
+
2) example_pgk
"--%throws" annotation requires a parameter. Annotation ignored.
- at "UT3.EXAMPLE_PGK.BAD_THROWS_ANNOTATION", line 42
-
-Finished in .025784 seconds
-10 tests, 3 failed, 0 errored, 0 disabled, 2 warning(s)
+ at package "UT3_TESTER.EXAMPLE_PGK.BAD_THROWS_ANNOTATION", line 57
+
+Finished in ,138276 seconds
+13 tests, 3 failed, 0 errored, 0 disabled, 2 warning(s)
+
```
## Order of execution
diff --git a/docs/userguide/best-practices.md b/docs/userguide/best-practices.md
index 45be3be59..5993c3824 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 adf36baa6..5e37f149e 100644
--- a/docs/userguide/coverage.md
+++ b/docs/userguide/coverage.md
@@ -1,6 +1,6 @@
-
+
-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.
+utPLSQL comes with a built-in coverage reporting engine. The code coverage reporting combines data from package DBMS_PROFILER and DBMS_PLSQL_CODE_COVERAGE.
Code coverage is gathered for the following source types:
* package bodies
@@ -22,12 +22,11 @@ To obtain information about code coverage for unit tests, run utPLSQL with one o
The following code coverage reporters are supplied with utPLSQL:
* `ut_coverage_html_reporter` - generates a HTML coverage report providing summary and detailed information on code coverage. The HTML reporter is based on the open-source [simplecov-html](https://github.com/colszowka/simplecov-html) reporter for Ruby. It includes source code of the code that was covered (if the code is accessible for test user)
-* `ut_coveralls_reporter` - generates a [Coveralls compatible JSON](https://coveralls.zendesk.com/hc/en-us/articles/201774865-API-Introduction) coverage report providing detailed information on code coverage with line numbers. This coverage report is designed to be consumed by cloud services like [Coveralls](https://coveralls.io)
* `ut_coverage_sonar_reporter` - generates a [Sonar Compatible XML](https://docs.sonarqube.org/latest/analysis/generic-test/) coverage report providing detailed information on code coverage with line numbers. This coverage report is designed to be consumed by services like [SonarQube](https://www.sonarqube.org/) and [SonarCloud](https://about.sonarcloud.io/)
* `ut_coverage_cobertura_reporter` - generates a basic Cobertura coverage (http://cobertura.sourceforge.net/xml/coverage-04.dtd) report providing detailed information on code coverage with line numbers. This coverage report is designed to be consumed by services like TFS and Jenkins. Check this link for an example of XML generated by Java: https://raw.githubusercontent.com/jenkinsci/cobertura-plugin/master/src/test/resources/hudson/plugins/cobertura/coverage-with-data.xml
## Security model
-utPLSQL code coverage uses DBMS_PROFILER to gather information about the execution of code under test and therefore follows the [DBMS_PROFILER's Security Model](https://docs.oracle.com/database/121/ARPLS/d_profil.htm#ARPLS67465).
+utPLSQL code coverage uses DBMS_PROFILER to gather information about the execution of code under test and therefore follows the [DBMS_PROFILER's Security Model](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_PROFILER.html#GUID-DEE5EA97-14AA-4AF2-A5F7-4AB1D004B99F).
In order to be able to gather coverage information, the user executing unit tests needs to be either:
* The owner of the code that is being tested
@@ -63,14 +62,15 @@ The report allow you to navigate to each source file and inspect line by line co

-### Oracle 12.2 extended coverage with profiler and block coverage
-Using data collected from profiler and block coverage running parallel we are able to enrich information about coverage.
-For every line recorded by the profiler if we have a partially covered same line in block coverage we will display that information
-presenting line as partially covered, displaying number of block and how many blocks have been covered in that line.The feature will be automatically enabled in the Oracle database version 12.2 and higher, for older versions current profiler will be used.
+### Partial Coverage
-utPLSQL installation automatically creates tables needed by `dbms_plsql_code_coverage` on databases in versions above 12c Release 1.
-Due to security model of `dbms_plsql_code_coverage` package, utPLSQL grants access to those tables and creates synonyms for those tables.
-The access and synonyms will be public when using the headless installation. This approach avoids complexity of forcing every user of utPLSQL framework to create tables on their own.
+#### What it does
+Partial coverage combines two data sources β the profiler and block coverage β to give you a more detailed picture of which parts of your code have been tested.
+When a line appears in both sources, and block coverage shows it was only partially covered, the display will reflect that: you'll see the line marked as partially covered, along with how many blocks on that line were executed out of the total.
+
+#### Setup and permissions
+utPLSQL automatically creates the tables required by Oracle's dbms_plsql_code_coverage package β you don't need to create them manually.
+Because of how dbms_plsql_code_coverage handles security, utPLSQL also takes care of granting access to those tables and creating the necessary synonyms. In a headless installation, both the grants and synonyms are made public, keeping things simple without requiring every utPLSQL user to set up their own tables.
Sample output:
@@ -309,9 +309,9 @@ Executes test `test_award_bonus` in schema `unit_test_schema`. Coverage will be
### Project based Coverage
-utPLSQL provides reporters that produce reports consumable by external tools like `Sonar`/`SonarCloud` & `Coveralls`.
+utPLSQL provides reporters that produce reports consumable by external tools like `Sonar`/`SonarCloud`.
-Services like Sonar, Coveralls and others perform analysis based on source code in project files.
+Services like Sonar and others perform analysis based on source code in project files.
They are abstracted from database, schema names, packages, procedures and functions, and operate on a more generic concept of project source code.
To be able to effectively use reporters dedicated for those tools, utPLSQL provides functionality for mapping database object names to project files.
@@ -319,7 +319,7 @@ To be able to effectively use reporters dedicated for those tools, utPLSQL provi
There are a few significant differences when running coverage on project files compared to running coverage on schema(s).
- Coverage is only reported on objects that were successfully mapped to project files.
-- Project files (database objects) that were not executed at all are not reported as fully uncovered. It is up to the consumer (Sonar/Coveralls) to determine if project file should be considered as 0% coverage or just ignored.
+- Project files (database objects) that were not executed at all are not reported as fully uncovered. It is up to the consumer (Sonar) to determine if project file should be considered as 0% coverage or just ignored.
In order to successfully use coverage on project files, those files must be mapped to database objects.
diff --git a/docs/userguide/exception-reporting.md b/docs/userguide/exception-reporting.md
index e042d61ed..cfe79069a 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 0ea5e2e73..6b26dd1c8 100644
--- a/docs/userguide/expectations.md
+++ b/docs/userguide/expectations.md
@@ -1,4 +1,4 @@
-
+
## Expectation concepts
@@ -648,9 +648,7 @@ Syntax:
`ut.expect( a_actual ).to_be_like( a_mask [, a_escape_char] )`
-Parameters `a_mask` and `a_escape_char` represent valid parameters of the [Oracle LIKE condition](https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF52142).
-
-If you use Oracle Database version 11.2.0.4, you may run into Oracle Bug 14402514: WRONG RESULTS WITH LIKE ON CLOB USING ESCAPE CHARACTER. In this case we recommend to use `match` instead of `be_like`.
+Parameters `a_mask` and `a_escape_char` represent valid parameters of the [Oracle LIKE condition](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Pattern-matching-Conditions.html).
Usage:
```sql linenums="1"
@@ -806,7 +804,7 @@ Syntax:
`ut.expect( a_actual ).to_match( a_pattern [, a_modifiers] );`
-Parameters `a_pattern` and `a_modifiers` represent a valid regexp pattern accepted by [Oracle REGEXP_LIKE condition](https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF00501)
+Parameters `a_pattern` and `a_modifiers` represent a valid regexp pattern accepted by [Oracle REGEXP_LIKE condition](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Pattern-matching-Conditions.html#GUID-D2124F3A-C6E4-4CCA-A40E-2FFCABFD8E19)
Usage:
```sql linenums="1"
@@ -1224,9 +1222,7 @@ utPLSQL is capable of comparing compound data-types including:
- Comparison of cursor returning `TIMESTAMP` **columns** against cursor returning `TIMESTAMP` **bind variables** requires variables to be cast to proper precision. This is an Oracle SQL - PLSQL compatibility issue and usage of CAST is the only known workaround for now. See [Comparing cursor data containing TIMESTAMP bind variables](#comparing-cursor-data-containing-timestamp-bind-variables) for examples.
- To compare nested table/varray type you need to convert it to `anydata` by using `anydata.convertCollection()`
- To compare object type you need to convert it to `anydata` by using `anydata.convertObject()`
-- It is possible to compare PL/SQL records, collections, varrays and associative arrays. To compare this types of data, use cursor comparison feature of utPLSQL and TABLE operator in SQL query
- - On Oracle 11g Release 2 - pipelined table functions are needed (see section [Implicit (Shadow) Types in this artcile](https://oracle-base.com/articles/misc/pipelined-table-functions))
- - On Oracle 12c and above - use [TABLE function on nested tables/varrays/associative arrays of PL/SQL records](https://oracle-base.com/articles/12c/using-the-table-operator-with-locally-defined-types-in-plsql-12cr1)
+- It is possible to compare PL/SQL records, collections, varrays and associative arrays. To compare this types of data, use cursor comparison feature of utPLSQL and [TABLE operator in SQL query](https://oracle-base.com/articles/12c/using-the-table-operator-with-locally-defined-types-in-plsql-12cr1)
- utPLSQL is not able to distinguish between NULL and whitespace-only column/attribute value when comparing compound data. This is due to Oracle limitation on of XMLType.
See [issue #880](https://github.com/utPLSQL/utPLSQL/issues/880) for details. *Note: This behavior might be fixed in future releases, when utPLSQL is no longer depending on XMLType for compound data comparison.*
@@ -1763,10 +1759,10 @@ FAILURE
## Comparing Json objects
-utPLSQL is capable of comparing json data-types of `json_element_t` **on Oracle 12.2 and above**, and also `json` **on Oracle 21 and above**
+utPLSQL is capable of comparing json data-types of `json_element_t`, and also `json` **on Oracle 21 and above**
!!! note
- Whenever a database is upgraded to compatible version the utPLSQL needs to be reinstalled to pick up json changes. E.g. upgrade from 18c to 21c to enable `json` type compare.
+ Whenever a database is upgraded to compatible version the utPLSQL needs to be reinstalled to pick up json changes. E.g. upgrade from 19c to 23 AI to enable `json` type compare.
### Notes on comparison of json data
diff --git a/docs/userguide/getting-started.md b/docs/userguide/getting-started.md
index cd4feb46a..1fa394be5 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 6724ac6ab..f1e36e625 100644
--- a/docs/userguide/install.md
+++ b/docs/userguide/install.md
@@ -1,26 +1,16 @@
-
+
## Supported database versions
-utPLSQL is continuously tested against following versions of Oracle databases
+- Oracle Database 19c or newer (SE/EE/Cloud/Free)
-* 11g R2
-* 12c
-* 12c R2
-* 18c
-* 19c
+We do our best to assure full compatibility with **actively supported** versions of Oracle databases.
+See [this page](https://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf#page=6) for Oracle Database Releases and their Support Lifetime by Oracle.
-We do our best to assure full compatibility with supported versions of Oracle databases [See](http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf#page=6)
-
-## Requirements
-
-utPLSQL will run on any Oracle Database version 11g relase 2 or above.
### Licensed features required
-utPLSQL doesn't require any extra licensed features of Oracle database. It can be installed on any Standard Edition Oracle Database.
-
-In fact, it even supports Oracle 11g XE which is a free Oracle Database version with minimal features and storage limits.
+utPLSQL doesn't require any extra licensed features of Oracle database. It can be installed on any Edition of Oracle Database.
### Storage requirements
@@ -124,9 +114,6 @@ The scripts need to be executed by `SYSDBA`, in order to grant access to `DBMS_L
- `DBMS_LOCK` is required for session synchronization between main session and session consuming realtime reports.
- The user performing the installation must have the `ADMINISTER DATABASE TRIGGER` privilege. This is required for installation of trigger that is responsible for parsing annotations at at compile-time of a package.
- When installed with DDL trigger, utPLSQL will not be registering unit tests for any of oracle-maintained schemas.
- - For Oracle 11g following users are excluded:
- ANONYMOUS, APPQOSSYS, AUDSYS, DBSFWUSER, DBSNMP, DIP, GGSYS, GSMADMIN_INTERNAL, GSMCATUSER, GSMUSER, ORACLE_OCM, OUTLN, REMOTE_SCHEDULER_AGENT, SYS, SYS$UMF, SYSBACKUP, SYSDG, SYSKM, SYSRAC, SYSTEM, WMSYS, XDB, XS$NULL
- - For Oracle 12c and above the users returned by below query are excluded by utPLSQL:
`select username from all_users where oracle_maintained='Y';`
### Installation without DDL trigger
@@ -179,7 +166,7 @@ If the installing user and utPLSQL owner is one and the same, the user must have
In addition, the user must be granted the execute privilege on `DBMS_LOCK` and `DBMS_CRYPTO` packages.
-utPLSQL is using [DBMS_PROFILER tables](https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_profil.htm#i999476) for code coverage. The tables required by DBMS_PROFILER will be created in the installation schema unless they already exist.
+utPLSQL is using [DBMS_PROFILER tables](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_PROFILER.html) for code coverage. The tables required by DBMS_PROFILER will be created in the installation schema unless they already exist.
It is up to DBA to maintain the storage of the profiler tables.
@@ -274,7 +261,7 @@ select
## Additional requirements
In order to use the Code Coverage functionality of utPLSQL, users executing the tests must have the CREATE privilege on the PLSQL code that the coverage is gathered on.
-This is a requirement of [DBMS_PROFILER package](https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_profil.htm#i999476).
+This is a requirement of [DBMS_PROFILER package](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_PROFILER.html#GUID-DEE5EA97-14AA-4AF2-A5F7-4AB1D004B99F).
In practice, user running tests for PLSQL code that he does not own, needs to have CREATE ANY PROCEDURE/CREATE ANY TRIGGER privileges.
Running code coverage on objects that the user does not own will **not produce any coverage information** without those privileges.
diff --git a/docs/userguide/querying_suites.md b/docs/userguide/querying_suites.md
index 0cdc2d7fa..e9d8d7ad7 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 b417ba25c..36b7e8932 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.
diff --git a/docs/userguide/running-unit-tests.md b/docs/userguide/running-unit-tests.md
index 28e02d5b8..324e97602 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 818a592bc..e69998a46 100644
--- a/docs/userguide/upgrade.md
+++ b/docs/userguide/upgrade.md
@@ -1,4 +1,4 @@
-
+
# Upgrading from version 2
diff --git a/examples/annoation_parser_testing/annotation_parser_test.sql b/examples/annoation_parser_testing/annotation_parser_test.sql
new file mode 100644
index 000000000..d1ff43fcd
--- /dev/null
+++ b/examples/annoation_parser_testing/annotation_parser_test.sql
@@ -0,0 +1,298 @@
+-- Annotation Manager Volume Benchmark
+-- 1000 generated packages, cold cache per iteration
+
+set serveroutput on size unlimited
+set timing off
+set feedback off
+
+declare
+ c_packages constant pls_integer := 1000;
+ c_procs_per_pkg constant pls_integer := 20;
+ c_contexts_per_pkg constant pls_integer := 4;
+ c_pkg_prefix constant varchar2(20) := 'TST_GEN_PKG_';
+ c_iterations constant pls_integer := 4;
+ c_perf_threshold constant number := 0.80;
+
+ l_baseline_total_ms number := 0;
+ l_new_total_ms number := 0;
+ l_start timestamp;
+ l_elapsed interval day to second;
+
+ -- Source holders
+ l_source_lines dbms_preprocessor.source_lines_t;
+ l_source_clob clob;
+ l_result ut_annotations;
+
+ -- Correctness tracking
+ l_missing_from_cache pls_integer := 0;
+ l_count_mismatches pls_integer := 0;
+ l_mismatch_detail varchar2(32767);
+
+ -- Cache check
+ l_cursor sys_refcursor;
+ l_annotated_obj ut_annotated_object;
+ l_name varchar2(128);
+ l_annotations ut_annotations;
+ l_cache_count pls_integer := 0;
+
+ -- Per-package timing
+ l_pkg_baseline_ms number;
+ l_pkg_new_ms number;
+ l_pkg varchar2(30);
+ l_ratio number;
+
+ -- Expected annotation count β mirrors generator logic exactly
+ function expected_annotation_count(
+ a_pkg_number pls_integer,
+ a_procs pls_integer,
+ a_contexts pls_integer
+ ) return pls_integer is
+ l_count pls_integer := 0;
+ begin
+ l_count := l_count + 2; -- %suite + %suitepath
+ l_count := l_count + 2; -- %beforeall + %afterall
+ l_count := l_count + 2; -- %beforeeach + %aftereach
+
+ -- package level conditional
+ if mod(a_pkg_number, 3) = 0 then l_count := l_count + 1; end if; -- %displayname
+ if mod(a_pkg_number, 5) = 0 then l_count := l_count + 1; end if; -- %rollback
+
+ -- contexts: each contributes %context + %endcontext
+ l_count := l_count + (a_contexts * 2);
+
+ -- per procedure
+ for i in 1 .. a_procs loop
+ l_count := l_count + 1; -- %test
+ if mod(i, 3) = 0 then l_count := l_count + 1; end if; -- %tags
+ if mod(i, 6) = 0 then l_count := l_count + 1; end if; -- %throws
+ if mod(i, 8) = 0 then l_count := l_count + 1; end if; -- %disabled
+ if mod(i, 5) = 0 then l_count := l_count + 2; end if; -- %beforetest + %aftertest
+ end loop;
+
+ return l_count;
+ end expected_annotation_count;
+
+begin
+ dbms_output.put_line('Packages : ' || c_packages);
+ dbms_output.put_line('Procs/pkg : ' || c_procs_per_pkg);
+ dbms_output.put_line('Contexts/pkg: ' || c_contexts_per_pkg);
+ dbms_output.put_line('Iterations : ' || c_iterations);
+ dbms_output.put_line('Started : ' || to_char(systimestamp,'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+ -- Phase 1: Performance benchmark (cold cache per package per iteration)
+ dbms_output.put_line(chr(10) || '-- Phase 1: Performance --');
+ dbms_output.put_line(
+ rpad('package', 20) || ' | ' ||
+ lpad('baseline_ms', 11) || ' | ' ||
+ lpad('new_ms', 6) || ' | ' ||
+ lpad('ratio', 5) || ' | ' ||
+ 'status'
+ );
+ dbms_output.put_line(rpad('-', 70, '-'));
+
+ for p in 1 .. c_packages loop
+ l_pkg := c_pkg_prefix || lpad(p, 4, '0');
+
+ -- load source once per package
+ l_source_lines := dbms_preprocessor.get_post_processed_source(
+ object_type => 'PACKAGE',
+ schema_name => user,
+ object_name => l_pkg
+ );
+
+ dbms_lob.createtemporary(l_source_clob, true);
+ for i in 1 .. l_source_lines.count loop
+ dbms_lob.writeappend(l_source_clob, length(l_source_lines(i)), l_source_lines(i));
+ end loop;
+
+ -- baseline: clob version
+ l_pkg_baseline_ms := 0;
+ for iter in 1 .. c_iterations loop
+ ut_annotation_manager.purge_cache(user, 'PACKAGE');
+ l_start := systimestamp;
+ l_result := ut_annotation_parser.parse_object_annotations(l_source_clob);
+ l_elapsed := systimestamp - l_start;
+ l_pkg_baseline_ms := l_pkg_baseline_ms +
+ extract(second from l_elapsed) * 1000;
+ end loop;
+ l_pkg_baseline_ms := l_pkg_baseline_ms / c_iterations;
+
+ -- new: source_lines_t version
+ l_pkg_new_ms := 0;
+ for iter in 1 .. c_iterations loop
+ ut_annotation_manager.purge_cache(user, 'PACKAGE');
+ l_start := systimestamp;
+ l_result := ut_annotation_parser.parse_object_annotations(l_source_lines);
+ l_elapsed := systimestamp - l_start;
+ l_pkg_new_ms := l_pkg_new_ms +
+ extract(second from l_elapsed) * 1000;
+ end loop;
+ l_pkg_new_ms := l_pkg_new_ms / c_iterations;
+
+ -- accumulate
+ l_baseline_total_ms := l_baseline_total_ms + l_pkg_baseline_ms;
+ l_new_total_ms := l_new_total_ms + l_pkg_new_ms;
+
+ l_ratio := round(l_pkg_new_ms / nullif(l_pkg_baseline_ms, 0), 3);
+
+ -- print every 100 packages to avoid flooding output
+ if mod(p, 100) = 0 or p = 1 then
+ dbms_output.put_line(
+ rpad(l_pkg, 20) || ' | ' ||
+ lpad(round(l_pkg_baseline_ms, 3), 11) || ' | ' ||
+ lpad(round(l_pkg_new_ms, 3), 6) || ' | ' ||
+ lpad(l_ratio, 5) || ' | ' ||
+ case when l_ratio <= c_perf_threshold
+ then 'PASS (' || round((1-l_ratio)*100,1) || '% faster)'
+ else 'SLOW (ratio=' || l_ratio || ')'
+ end
+ );
+ end if;
+
+ dbms_lob.freetemporary(l_source_clob);
+ end loop;
+
+ -- -------------------------------------------------------------------------
+ -- Phase 1 summary
+ -- -------------------------------------------------------------------------
+ l_ratio := round(l_new_total_ms / nullif(l_baseline_total_ms, 0), 3);
+
+ dbms_output.put_line(rpad('-', 70, '-'));
+ dbms_output.put_line('Baseline total ms : ' || round(l_baseline_total_ms, 3));
+ dbms_output.put_line('New total ms : ' || round(l_new_total_ms, 3));
+ dbms_output.put_line('Overall ratio : ' || l_ratio);
+ dbms_output.put_line('Improvement : ' || round((1 - l_ratio) * 100, 1) || '%');
+
+ -- Phase 2: Cache presence check
+ dbms_output.put_line(chr(10) || '-- Phase 2: Cache presence --');
+
+ ut_annotation_manager.purge_cache(user, 'PACKAGE');
+ ut_annotation_manager.rebuild_annotation_cache(user, 'PACKAGE');
+
+ -- query cache tables directly to avoid validate_annotation_cache side effects
+ open l_cursor for
+ select ut_annotated_object(
+ i.object_owner, i.object_name, i.object_type, i.parse_time,
+ cast(
+ collect(
+ ut_annotation(
+ c.annotation_position, c.annotation_name,
+ c.annotation_text, c.subobject_name
+ ) order by c.annotation_position
+ ) as ut_annotations
+ )
+ )
+ from ut_annotation_cache_info i
+ join ut_annotation_cache c on i.cache_id = c.cache_id
+ where i.object_owner = user
+ and i.object_type = 'PACKAGE'
+ and i.object_name like c_pkg_prefix || '%'
+ group by i.object_owner, i.object_type, i.object_name, i.parse_time;
+
+ loop
+ fetch l_cursor into l_annotated_obj;
+ exit when l_cursor%notfound;
+ l_cache_count := l_cache_count + 1;
+ end loop;
+ close l_cursor;
+
+ dbms_output.put_line('Expected in cache : ' || c_packages);
+ dbms_output.put_line('Found in cache : ' || l_cache_count);
+ dbms_output.put_line('Cache check : ' ||
+ case when l_cache_count = c_packages
+ then 'PASS β all ' || c_packages || ' packages found in cache'
+ else 'FAIL β missing ' || (c_packages - l_cache_count) || ' packages from cache'
+ end
+ );
+
+ -- Phase 3: Annotation count correctness
+ dbms_output.put_line(chr(10) || '-- Phase 3: Annotation count correctness --');
+
+ -- reopen same direct cache query for correctness check
+ open l_cursor for
+ select ut_annotated_object(
+ i.object_owner, i.object_name, i.object_type, i.parse_time,
+ cast(
+ collect(
+ ut_annotation(
+ c.annotation_position, c.annotation_name,
+ c.annotation_text, c.subobject_name
+ ) order by c.annotation_position
+ ) as ut_annotations
+ )
+ )
+ from ut_annotation_cache_info i
+ join ut_annotation_cache c on i.cache_id = c.cache_id
+ where i.object_owner = user
+ and i.object_type = 'PACKAGE'
+ and i.object_name like c_pkg_prefix || '%'
+ group by i.object_owner, i.object_type, i.object_name, i.parse_time;
+
+ loop
+ fetch l_cursor into l_annotated_obj;
+ exit when l_cursor%notfound;
+ l_name := l_annotated_obj.object_name;
+ l_annotations := l_annotated_obj.annotations;
+
+ declare
+ l_pkg_number pls_integer;
+ l_expected pls_integer;
+ begin
+ l_pkg_number := to_number(substr(l_name, length(c_pkg_prefix) + 1));
+ l_expected := expected_annotation_count(
+ l_pkg_number,
+ c_procs_per_pkg,
+ c_contexts_per_pkg
+ );
+
+ if l_annotations.count != l_expected then
+ l_count_mismatches := l_count_mismatches + 1;
+ if l_count_mismatches <= 10 then
+ l_mismatch_detail := l_mismatch_detail || chr(10) ||
+ ' ' || l_name ||
+ ': expected=' || l_expected ||
+ ' actual=' || l_annotations.count;
+ end if;
+ end if;
+ end;
+ end loop;
+ close l_cursor;
+
+ dbms_output.put_line('Packages checked : ' || c_packages);
+ dbms_output.put_line('Count mismatches : ' || l_count_mismatches);
+ if l_count_mismatches > 0 then
+ dbms_output.put_line('Mismatch detail (first 10):' || l_mismatch_detail);
+ end if;
+ dbms_output.put_line('Count check : ' ||
+ case when l_count_mismatches = 0
+ then 'PASS β all annotation counts match expected'
+ else 'FAIL β ' || l_count_mismatches || ' packages have wrong annotation count'
+ end
+ );
+
+ dbms_output.put_line(chr(10) || '=================================================');
+ dbms_output.put_line('FINAL RESULTS');
+ dbms_output.put_line('=================================================');
+ dbms_output.put_line('Performance : ' ||
+ case when l_ratio <= c_perf_threshold then 'PASS' else 'FAIL' end);
+ dbms_output.put_line('Cache : ' ||
+ case when l_cache_count = c_packages then 'PASS' else 'FAIL' end);
+ dbms_output.put_line('Counts : ' ||
+ case when l_count_mismatches = 0 then 'PASS' else 'FAIL' end);
+ dbms_output.put_line('Overall : ' ||
+ case when l_ratio <= c_perf_threshold
+ and l_cache_count = c_packages
+ and l_count_mismatches = 0
+ then 'PASS'
+ else 'FAIL'
+ end
+ );
+ dbms_output.put_line('Finished : ' ||
+ to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS.FF3'));
+ dbms_output.put_line('=================================================');
+
+ -- cleanup
+ ut_annotation_manager.purge_cache(user, 'PACKAGE');
+
+end;
+/
diff --git a/examples/annoation_parser_testing/create_test_packages.sql b/examples/annoation_parser_testing/create_test_packages.sql
new file mode 100644
index 000000000..94a7f3de2
--- /dev/null
+++ b/examples/annoation_parser_testing/create_test_packages.sql
@@ -0,0 +1,185 @@
+declare
+ c_packages constant pls_integer := 1000;
+ c_procs_per_pkg constant pls_integer := 20;
+
+ l_spec varchar2(32767);
+ l_body varchar2(32767);
+ l_pkg varchar2(30);
+ l_errors pls_integer := 0;
+
+ procedure append_to_source(a_source in out nocopy varchar2, a_text varchar2) is
+ begin
+ a_source := a_source || a_text;
+ end;
+
+ procedure append_line(a_source in out nocopy varchar2, a_text varchar2 default null) is
+ begin
+ a_source := a_source || a_text || chr(10);
+ end;
+
+begin
+
+ for r in (
+ select object_name
+ from user_objects
+ where object_name like 'TST_GEN_PKG_%'
+ and object_type = 'PACKAGE'
+ order by object_name
+ ) loop
+ begin
+ execute immediate 'drop package ' || r.object_name;
+ exception
+ when others then
+ dbms_output.put_line('ERROR dropping ' || r.object_name || ': ' || sqlerrm);
+ end;
+ end loop;
+ dbms_output.put_line('Existing packages dropped.');
+
+ for p in 1 .. c_packages loop
+ l_pkg := 'TST_GEN_PKG_' || lpad(p, 4, '0');
+ l_spec := null;
+ l_body := null;
+
+ -- Package spec
+ append_line(l_spec, 'create or replace package ' || l_pkg || ' as');
+ append_line(l_spec);
+ append_line(l_spec, ' --%suite(Generated suite ' || p || ')');
+ append_line(l_spec, ' --%suitepath(generated.vol_test)');
+
+ if mod(p, 3) = 0 then
+ append_line(l_spec, ' --%displayname(Suite display name for pkg ' || p || ')');
+ end if;
+ if mod(p, 5) = 0 then
+ append_line(l_spec, ' --%rollback(manual)');
+ end if;
+
+ append_line(l_spec);
+ append_line(l_spec, ' --%beforeall');
+ append_line(l_spec, ' procedure setup_suite;');
+ append_line(l_spec);
+ append_line(l_spec, ' --%afterall');
+ append_line(l_spec, ' procedure teardown_suite;');
+ append_line(l_spec);
+ append_line(l_spec, ' --%beforeeach');
+ append_line(l_spec, ' procedure setup_test;');
+ append_line(l_spec);
+ append_line(l_spec, ' --%aftereach');
+ append_line(l_spec, ' procedure teardown_test;');
+ append_line(l_spec);
+
+ for i in 1 .. c_procs_per_pkg loop
+ declare
+ l_proc varchar2(30) := 'test_proc_' || lpad(i, 3, '0');
+ begin
+ if mod(i - 1, 5) = 0 then
+ append_line(l_spec, ' --%context(context_' || ceil(i/5) || ')');
+ append_line(l_spec);
+ end if;
+
+ if mod(i, 4) = 0 then
+ append_line(l_spec, ' /* multi-line comment for ' || l_proc || ' */');
+ end if;
+
+ append_line(l_spec, ' --%test(Test ' || i || ' in pkg ' || p || ')');
+
+ if mod(i, 3) = 0 then
+ append_line(l_spec, ' --%tags(tag_' || mod(i,5) || ',smoke)');
+ end if;
+ if mod(i, 6) = 0 then
+ append_line(l_spec, ' --%throws(-20001)');
+ end if;
+ if mod(i, 8) = 0 then
+ append_line(l_spec, ' --%disabled(generated disabled test ' || i || ')');
+ end if;
+ if mod(i, 5) = 0 then
+ append_line(l_spec, ' --%beforetest(setup_test)');
+ append_line(l_spec, ' --%aftertest(teardown_test)');
+ end if;
+
+ append_line(l_spec, ' -- regular comment');
+ append_line(l_spec, ' procedure ' || l_proc || ';');
+ append_line(l_spec);
+
+ if mod(i, 5) = 0 then
+ append_line(l_spec, ' --%endcontext');
+ append_line(l_spec);
+ end if;
+ end;
+ end loop;
+
+ append_line(l_spec, 'end ' || l_pkg || ';');
+
+ -- -----------------------------------------------------------------------
+ -- Package body
+ -- -----------------------------------------------------------------------
+ append_line(l_body, 'create or replace package body ' || l_pkg || ' as');
+ append_line(l_body);
+
+ for stub in (
+ select column_value as proc_name
+ from table(ut_varchar2_list(
+ 'setup_suite','teardown_suite',
+ 'setup_test','teardown_test'
+ ))
+ ) loop
+ append_line(l_body, ' procedure ' || stub.proc_name || ' is');
+ append_line(l_body, ' begin');
+ append_line(l_body, ' null;');
+ append_line(l_body, ' end ' || stub.proc_name || ';');
+ append_line(l_body);
+ end loop;
+
+ for i in 1 .. c_procs_per_pkg loop
+ declare
+ l_proc varchar2(30) := 'test_proc_' || lpad(i, 3, '0');
+ begin
+ append_line(l_body, ' procedure ' || l_proc || ' is');
+ append_line(l_body, ' begin');
+ if mod(i, 4) = 0 then
+ append_line(l_body, ' ut.expect(''/* not a comment */'').to_equal(''/* not a comment */'');');
+ elsif mod(i, 4) = 1 then
+ append_line(l_body, ' ut.expect(' || i || ').to_be_greater_than(0);');
+ elsif mod(i, 4) = 2 then
+ append_line(l_body, ' ut.expect(q''[-- not a comment]'').to_equal(q''[-- not a comment]'');');
+ else
+ append_line(l_body, ' ut.expect(''test_' || i || ''').not_to_be_null();');
+ end if;
+ append_line(l_body, ' end ' || l_proc || ';');
+ append_line(l_body);
+ end;
+ end loop;
+
+ append_line(l_body, 'end ' || l_pkg || ';');
+
+ -- Execute DDL β with error capture so one bad package doesn't stop all
+ begin
+ execute immediate l_spec;
+ execute immediate l_body;
+ exception
+ when others then
+ l_errors := l_errors + 1;
+ dbms_output.put_line('ERROR on ' || l_pkg || ': ' || sqlerrm);
+ end;
+
+ if mod(p, 100) = 0 then
+ dbms_output.put_line('Created ' || p || ' packages...');
+ end if;
+
+ end loop;
+
+ dbms_output.put_line('----------------------------------------');
+ dbms_output.put_line('Done. packages=' || c_packages ||
+ ' errors=' || l_errors);
+
+ -- quick sanity check
+ declare
+ l_count pls_integer;
+ begin
+ select count(*) into l_count
+ from user_objects
+ where object_name like 'TST_GEN_PKG_%'
+ and object_type = 'PACKAGE';
+ dbms_output.put_line('Packages in user_objects: ' || l_count);
+ end;
+end;
+/
diff --git a/readme.md b/readme.md
index 1ca252558..bba640d17 100644
--- a/readme.md
+++ b/readme.md
@@ -1,102 +1,47 @@

-----------
-
-[](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://www.apache.org/licenses/LICENSE-2.0)
[](https://github.com/utPLSQL/utPLSQL/discussions)
-[](https://twitter.com/utPLSQL)
-
+[](https://twitter.com/utPLSQL)
[](https://github.com/utPLSQL/utPLSQL/actions/workflows/build.yml)
[](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.
-Version 2 still supports older versions of Oracle that are no longer available.
-The community that had developed on GitHub decided that a new internal architecture was needed, from that version 3 was born.
-
-# Introduction
-utPLSQL is a Unit Testing framework for Oracle PL/SQL and SQL.
-The framework follows industry standards and best patterns of modern Unit Testing frameworks like [JUnit](http://junit.org/junit4/) and [RSpec](http://rspec.info/)
-
-
-# Key features
-
-- multiple ways to compare data with [matchers](docs/userguide/expectations.md)
-- native comparison of complex types (objects/collections/cursors)
-- in-depth and consistent reporting of failures and errors for tests
-- tests identified and configured by [annotations](docs/userguide/annotations.md)
-- hierarchies of test suites configured with annotations
-- automatic (configurable) transaction control
-- Build-in [coverage](docs/userguide/coverage.md) reporting
-- Integration with SonarQube, Coveralls, Jenkins and Teamcity with [reporters](docs/userguide/reporters.md)
-- plugin architecture for reporters and matchers
-- flexible and simple test invocation
-- multi-reporting from test-run from [command line](https://github.com/utPLSQL/utPLSQL-cli)
-
-Requirements:
- - Version of Oracle under [extended support](http://www.oracle.com/us/support/library/lifetime-support-technology-069183.pdf) (Currently 11.2 and above)
-
-# Download
-
-Published releases are available for download on the [utPLSQL GitHub Releases Page.](https://github.com/utPLSQL/utPLSQL/releases)
-
-# Documentation
-
-Full documentation of the project is automatically published on [utPLSQL github pages](https://utplsql.github.io/utPLSQL/)
-
-[Cheat-sheets](https://www.cheatography.com/jgebal/lists/utplsql-v3-cheat-sheets/)
-
-# Installation
+utPLSQL is a unit testing framework for Oracle PL/SQL and SQL, following industry standards and best practices of modern testing frameworks like [JUnit](http://junit.org/junit4/) and [RSpec](http://rspec.info/).
-To install the utPLSQL into a new database schema and grant it to public, execute the script `install_headless.sql`.
-This will create a new user `UT3`, grant all required privileges to that user and create PUBLIC synonyms needed.
-
-For detailed instructions on other install options see the [Install Guide](docs/userguide/install.md)
-
-
-# Running tests
-
-To execute using development IDE (TOAD/SQLDeveloper/PLSQLDeveloper/other) use one of following commands.
-```sql
-begin
- ut.run();
-end;
-/
-```
-```sql
-exec ut.run();
-```
-```sql
-select * from table(ut.run());
-```
+## Key Features
-The above commands will run all the suites in the current schema and provide report to dbms_output or as a select statement.
+- Multiple ways to compare data with [matchers](docs/userguide/expectations.md)
+- Native comparison of complex types (objects, collections, cursors)
+- In-depth and consistent reporting of failures and errors
+- Tests identified and configured by [annotations](docs/userguide/annotations.md)
+- Hierarchies of test suites configured with annotations
+- Automatic (configurable) transaction control
+- Built-in [coverage](docs/userguide/coverage.md) reporting
+- Integration with SonarQube, Jenkins and TeamCity via [reporters](docs/userguide/reporters.md)
+- Plugin architecture for reporters and matchers
+- Flexible and simple test invocation
+- Multi-format reporting from the [command line client](https://github.com/utPLSQL/utPLSQL-cli)
-# Command line client
+## Requirements
-You can use the utPLSQL command line client [utPLSQL-cli](https://github.com/utPLSQL/utPLSQL-cli) to run tests without the need for Oracle Client or any IDE like SQLDeveloper/TOAD etc.
+- Oracle Database 19c or newer
-Amongst many benefits it provides ability to:
-* see the progress of test execution for long-running tests - real-time reporting
-* use many reporting formats simultaneously and save reports to files (publish)
-* map your project source files and test files into database objects
+## Installation
-Download the [latest client](https://github.com/utPLSQL/utPLSQL-cli/releases/latest) and are good to go.
-See [project readme](https://github.com/utPLSQL/utPLSQL-cli/blob/develop/README.md) for details.
+Published releases are available for download on the [utPLSQL GitHub Releases page](https://github.com/utPLSQL/utPLSQL/releases).
+To install utPLSQL into a new database schema and grant it to public, execute the script `install_headless.sql`.
+This creates a new user `UT3`, grants all required privileges, and creates PUBLIC synonyms.
-# Example unit test packages
+For all install options see the [Install Guide](docs/userguide/install.md).
-**For examples of using Continuous Integration Server & SonarCloud with utPLSQL see the [utPLSQL demo project](https://github.com/utPLSQL/utPLSQL-demo-project/).**
+## Quick Start
+**1. Write a test package**
-The below test package is a fully-functional Unit Test package for testing a [`betwnstr` function](examples/between_string/betwnstr.sql).
-The package specification is [annotated](docs/userguide/annotations.md) with special comments.
-The annotations define that a package is a unit test suite, they also allow defining a description for the suite as well as the test itself.
-The package body consists of procedures containing unit test code. To validate [an expectation](docs/userguide/expectations.md) in test, use `ut.expect( actual_data ).to_( ... )` syntax.
+Annotate a package specification to define a test suite and its tests, then implement each test procedure in the package body:
```sql
create or replace package test_between_string as
@@ -106,12 +51,6 @@ create or replace package test_between_string as
-- %test(Returns substring from start position to end position)
procedure normal_case;
- -- %test(Returns substring when start position is zero)
- procedure zero_start_position;
-
- -- %test(Returns string until end if end position is greater than string length)
- procedure big_end_position;
-
-- %test(Returns null for null input string value)
procedure null_string;
end;
@@ -124,16 +63,6 @@ create or replace package body test_between_string as
ut.expect( betwnstr( '1234567', 2, 5 ) ).to_( equal('2345') );
end;
- procedure zero_start_position is
- begin
- ut.expect( betwnstr( '1234567', 0, 5 ) ).to_( equal('12345') );
- end;
-
- procedure big_end_position is
- begin
- ut.expect( betwnstr( '1234567', 0, 500 ) ).to_( equal('1234567') );
- end;
-
procedure null_string is
begin
ut.expect( betwnstr( null, 2, 5 ) ).to_( be_null );
@@ -143,60 +72,83 @@ end;
/
```
-Outputs from running the above tests
+**2. Run your tests**
+
+```sql
+exec ut.run();
+```
+
+**3. See the results**
+
```
Between string function
Returns substring from start position to end position
- Returns substring when start position is zero
- Returns string until end if end position is greater than string length
Returns null for null input string value
Finished in .036027 seconds
-4 tests, 0 failures
+2 tests, 0 failures
+```
+
+For complete working examples see [examples/](examples/).
+
+## Running Tests
+
+From any Oracle-compatible IDE (SQL Developer, TOAD, PL/SQL Developer):
+
+```sql
+begin
+ ut.run();
+end;
+/
```
+```sql
+exec ut.run();
+```
+```sql
+select * from table(ut.run());
+```
+
+These commands run all suites in the current schema and report test results to `DBMS_OUTPUT` or as a result set.
+## Command Line Client
-# Contributing to the project
+[utPLSQL-cli](https://github.com/utPLSQL/utPLSQL-cli) lets you run tests without an Oracle Client or IDE. It provides:
-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.
-[Github discussions](https://github.com/utPLSQL/utPLSQL/discussions) is the place to go if you want to talk with team members.
+- Real-time test reporting
+- Simultaneous output of multiple report formats into different files
+- Source files and test files mapping for coverage reports
+Download the [latest release](https://github.com/utPLSQL/utPLSQL-cli/releases/latest) and see the [CLI readme](https://github.com/utPLSQL/utPLSQL-cli/blob/develop/README.md) for details.
-----------
-[__Authors__](docs/about/authors.md)
+## Documentation
+Full documentation is published at [https://www.utplsql.org/utPLSQL/](https://www.utplsql.org/utPLSQL/).
-----------
-__Project Directories__
+[Cheat-sheets](https://www.cheatography.com/jgebal/lists/utplsql-v3-cheat-sheets/) are available for quick reference.
-* .github - contains files needed for github Actions integration
-* .travis - contains files needed for travis-ci integration
-* client_source - Sources to be used on the client-side. Developer workstation or CI platform to run the tests.
-* development - Set of useful scripts and utilities for development and debugging of utPLSQL
-* docs - Documentation of the project
-* examples - Example source code and unit tests
-* source - The installation code for utPLSQL
-* tests - Tests for utPLSQL framework
+See the [Changelog](CHANGELOG.md) for the full version history.
-----------
+Migrating from legacy utPLSQL v2? See the [version 2 to version 3 comparison](docs/compare_version2_to_3.md).
+## Contributing
-# Version 2 to Version 3 Comparison
+We welcome contributions of all kinds. Please read the [contributing guide](CONTRIBUTING.md) and the [code of conduct](CODE_OF_CONDUCT.md) before getting started.
-[Version 2 to Version 3 Comparison](docs/compare_version2_to_3.md)
+[GitHub Discussions](https://github.com/utPLSQL/utPLSQL/discussions) is the place to ask questions and connect with the team.
-# Supporters
+## Supporters
-The utPLSQL project is community-driven and is not commercially motivated. Nonetheless, donations and other contributions are always welcome, and are detailed below.
+utPLSQL is community-driven and not commercially motivated. Donations and contributions are always welcome.
-
utPLSQL has been supported by Redgate in the form of sponsored stickers and t-shirts. Thank you for helping us spreading the word!
+
utPLSQL has been supported by Redgate in the form of sponsored stickers and t-shirts. Thank you for helping us spread the word!
+---
+
+[Authors](docs/about/authors.md)
diff --git a/sonar-project.properties b/sonar-project.properties
index f23e8cf71..efcaeb5e6 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -3,7 +3,7 @@ sonar.organization=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
+sonar.projectVersion=v3.2.01-develop
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set.
@@ -15,7 +15,7 @@ sonar.coverage.exclusions=**/*.sql,**/*.pks
sonar.tests=./test
sonar.testExecutionReportPaths=./test_results.xml
sonar.links.issue=https://github.com/utPLSQL/utPLSQL/issues
-sonar.links.ci=https://travis-ci.org/utPLSQL/utPLSQL
+sonar.links.ci=https://github.com/utPLSQL/utPLSQL/actions
sonar.links.homepage=https://github.com/utPLSQL/utPLSQL
sonar.projectDescription=PL/SQL Unit Testing Framework
sonar.plsql.file.suffixes=sql,tab,pkb,tpb
diff --git a/source/api/be_between.syn b/source/api/be_between.syn
index c0972595d..233dd65bf 100644
--- a/source/api/be_between.syn
+++ b/source/api/be_between.syn
@@ -1 +1 @@
-create synonym be_between for ut_be_between;
+create noneditionable synonym be_between for ut_be_between;
diff --git a/source/api/be_empty.syn b/source/api/be_empty.syn
index a8e28de6e..f63366fa3 100644
--- a/source/api/be_empty.syn
+++ b/source/api/be_empty.syn
@@ -1 +1 @@
-create synonym be_empty for ut_be_empty;
+create noneditionable synonym be_empty for ut_be_empty;
diff --git a/source/api/be_false.syn b/source/api/be_false.syn
index c2665bbcb..cdf497235 100644
--- a/source/api/be_false.syn
+++ b/source/api/be_false.syn
@@ -1 +1 @@
-create synonym be_false for ut_be_false;
+create noneditionable synonym be_false for ut_be_false;
diff --git a/source/api/be_greater_or_equal.syn b/source/api/be_greater_or_equal.syn
index 386fe7f32..67616dc1d 100644
--- a/source/api/be_greater_or_equal.syn
+++ b/source/api/be_greater_or_equal.syn
@@ -1 +1 @@
-create synonym be_greater_or_equal for ut_be_greater_or_equal;
+create noneditionable synonym be_greater_or_equal for ut_be_greater_or_equal;
diff --git a/source/api/be_greater_than.syn b/source/api/be_greater_than.syn
index 6f97b7d22..c180f3d43 100644
--- a/source/api/be_greater_than.syn
+++ b/source/api/be_greater_than.syn
@@ -1 +1 @@
-create synonym be_greater_than for ut_be_greater_than;
+create noneditionable synonym be_greater_than for ut_be_greater_than;
diff --git a/source/api/be_less_or_equal.syn b/source/api/be_less_or_equal.syn
index b2f836144..0069f52ba 100644
--- a/source/api/be_less_or_equal.syn
+++ b/source/api/be_less_or_equal.syn
@@ -1 +1 @@
-create synonym be_less_or_equal for ut_be_less_or_equal;
+create noneditionable synonym be_less_or_equal for ut_be_less_or_equal;
diff --git a/source/api/be_less_than.syn b/source/api/be_less_than.syn
index fbef3b4c3..5d2766d05 100644
--- a/source/api/be_less_than.syn
+++ b/source/api/be_less_than.syn
@@ -1 +1 @@
-create synonym be_less_than for ut_be_less_than;
+create noneditionable synonym be_less_than for ut_be_less_than;
diff --git a/source/api/be_like.syn b/source/api/be_like.syn
index a8be1de71..6f62f21a0 100644
--- a/source/api/be_like.syn
+++ b/source/api/be_like.syn
@@ -1 +1 @@
-create synonym be_like for ut_be_like;
+create noneditionable synonym be_like for ut_be_like;
diff --git a/source/api/be_not_null.syn b/source/api/be_not_null.syn
index d6458683a..a9e02b94d 100644
--- a/source/api/be_not_null.syn
+++ b/source/api/be_not_null.syn
@@ -1 +1 @@
-create synonym be_not_null for ut_be_not_null;
+create noneditionable synonym be_not_null for ut_be_not_null;
diff --git a/source/api/be_null.syn b/source/api/be_null.syn
index 42f6516c3..4fe3fb9dd 100644
--- a/source/api/be_null.syn
+++ b/source/api/be_null.syn
@@ -1 +1 @@
-create synonym be_null for ut_be_null;
+create noneditionable synonym be_null for ut_be_null;
diff --git a/source/api/be_true.syn b/source/api/be_true.syn
index bf7392a62..1aa348c7e 100644
--- a/source/api/be_true.syn
+++ b/source/api/be_true.syn
@@ -1 +1 @@
-create synonym be_true for ut_be_true;
+create noneditionable synonym be_true for ut_be_true;
diff --git a/source/api/be_within.syn b/source/api/be_within.syn
index e00005bb7..4f4f77606 100644
--- a/source/api/be_within.syn
+++ b/source/api/be_within.syn
@@ -1 +1 @@
-create synonym be_within for ut_be_within;
+create noneditionable synonym be_within for ut_be_within;
diff --git a/source/api/be_within_pct.syn b/source/api/be_within_pct.syn
index 40e3fb8b9..b9fc1cd53 100644
--- a/source/api/be_within_pct.syn
+++ b/source/api/be_within_pct.syn
@@ -1 +1 @@
-create synonym be_within_pct for ut_be_within_pct;
+create noneditionable synonym be_within_pct for ut_be_within_pct;
diff --git a/source/api/contain.syn b/source/api/contain.syn
index 5bce7d1d2..5b4158635 100644
--- a/source/api/contain.syn
+++ b/source/api/contain.syn
@@ -1 +1 @@
-create synonym contain for ut_contain;
+create noneditionable synonym contain for ut_contain;
diff --git a/source/api/equal.syn b/source/api/equal.syn
index 71ba58b53..0d81fcf6f 100644
--- a/source/api/equal.syn
+++ b/source/api/equal.syn
@@ -1 +1 @@
-create synonym equal for ut_equal;
+create noneditionable synonym equal for ut_equal;
diff --git a/source/api/have_count.syn b/source/api/have_count.syn
index a406d47ec..9cbf8ebf2 100644
--- a/source/api/have_count.syn
+++ b/source/api/have_count.syn
@@ -1 +1 @@
-create synonym have_count for ut_have_count;
+create noneditionable synonym have_count for ut_have_count;
diff --git a/source/api/match.syn b/source/api/match.syn
index ffbda35b1..13e8cc97d 100644
--- a/source/api/match.syn
+++ b/source/api/match.syn
@@ -1 +1 @@
-create synonym match for ut_match;
+create noneditionable synonym match for ut_match;
diff --git a/source/api/ut.pkb b/source/api/ut.pkb
index cff35b771..0a847cfaa 100644
--- a/source/api/ut.pkb
+++ b/source/api/ut.pkb
@@ -1,8 +1,8 @@
-create or replace package body ut is
+create or replace noneditionable package body ut is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut.pks b/source/api/ut.pks
index f72c82a0c..fdba6b019 100644
--- a/source/api/ut.pks
+++ b/source/api/ut.pks
@@ -1,8 +1,8 @@
-create or replace package ut authid current_user as
+create or replace noneditionable package ut authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_runner.pkb b/source/api/ut_runner.pkb
index 3ec2a5393..0db1d6e96 100644
--- a/source/api/ut_runner.pkb
+++ b/source/api/ut_runner.pkb
@@ -1,8 +1,8 @@
-create or replace package body ut_runner is
+create or replace noneditionable package body ut_runner is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_runner.pks b/source/api/ut_runner.pks
index 85eff1c93..17bd0fa7a 100644
--- a/source/api/ut_runner.pks
+++ b/source/api/ut_runner.pks
@@ -1,8 +1,8 @@
-create or replace package ut_runner authid current_user is
+create or replace noneditionable package ut_runner authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_item_info.tpb b/source/api/ut_suite_item_info.tpb
index 3315f7a16..d18f078ee 100644
--- a/source/api/ut_suite_item_info.tpb
+++ b/source/api/ut_suite_item_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_item_info is
+create or replace noneditionable type body ut_suite_item_info is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_item_info.tps b/source/api/ut_suite_item_info.tps
index 2c92f261d..4b4f9d52c 100644
--- a/source/api/ut_suite_item_info.tps
+++ b/source/api/ut_suite_item_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_item_info as object (
+create or replace noneditionable type ut_suite_item_info as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/api/ut_suite_items_info.tps b/source/api/ut_suite_items_info.tps
index 208098f9d..5a04c9a74 100644
--- a/source/api/ut_suite_items_info.tps
+++ b/source/api/ut_suite_items_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_items_info as
+create or replace noneditionable type ut_suite_items_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/check_object_grants.sql b/source/check_object_grants.sql
index 5f560e6b1..0e7a9b4c9 100644
--- a/source/check_object_grants.sql
+++ b/source/check_object_grants.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
declare
$if dbms_db_version.version >= 18 $then
c_expected_grants constant dbmsoutput_linesarray := dbmsoutput_linesarray('DBMS_CRYPTO');
diff --git a/source/check_sys_grants.sql b/source/check_sys_grants.sql
index 79b657328..f81157183 100644
--- a/source/check_sys_grants.sql
+++ b/source/check_sys_grants.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
define expected_grants = "&1"
declare
c_expected_grants constant dbmsoutput_linesarray := dbmsoutput_linesarray( &expected_grants );
diff --git a/source/core/annotations/ut_annotated_object.tps b/source/core/annotations/ut_annotated_object.tps
index 3fda363fe..ca327d7fc 100644
--- a/source/core/annotations/ut_annotated_object.tps
+++ b/source/core/annotations/ut_annotated_object.tps
@@ -1,7 +1,7 @@
-create type ut_annotated_object as object(
+create or replace noneditionable type ut_annotated_object as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotated_objects.tps b/source/core/annotations/ut_annotated_objects.tps
index c67c1bd53..2b338e7d9 100644
--- a/source/core/annotations/ut_annotated_objects.tps
+++ b/source/core/annotations/ut_annotated_objects.tps
@@ -1,7 +1,7 @@
-create type ut_annotated_objects as
+create or replace noneditionable type ut_annotated_objects as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation.tps b/source/core/annotations/ut_annotation.tps
index 3d0311571..cc1f90e86 100644
--- a/source/core/annotations/ut_annotation.tps
+++ b/source/core/annotations/ut_annotation.tps
@@ -1,7 +1,7 @@
-create type ut_annotation as object(
+create or replace noneditionable type ut_annotation as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache.sql b/source/core/annotations/ut_annotation_cache.sql
index 67149ce60..7d69b1db6 100644
--- a/source/core/annotations/ut_annotation_cache.sql
+++ b/source/core/annotations/ut_annotation_cache.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_info.sql b/source/core/annotations/ut_annotation_cache_info.sql
index 167973a04..6248f4fbc 100644
--- a/source/core/annotations/ut_annotation_cache_info.sql
+++ b/source/core/annotations/ut_annotation_cache_info.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache_info (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_manager.pkb b/source/core/annotations/ut_annotation_cache_manager.pkb
index e1131b3bd..afc473404 100644
--- a/source/core/annotations/ut_annotation_cache_manager.pkb
+++ b/source/core/annotations/ut_annotation_cache_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_cache_manager as
+create or replace noneditionable package body ut_annotation_cache_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache_manager.pks b/source/core/annotations/ut_annotation_cache_manager.pks
index 1e9734934..1aa4cb501 100644
--- a/source/core/annotations/ut_annotation_cache_manager.pks
+++ b/source/core/annotations/ut_annotation_cache_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_cache_manager authid definer as
+create or replace noneditionable package ut_annotation_cache_manager authid definer as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_cache_schema.sql b/source/core/annotations/ut_annotation_cache_schema.sql
index 8889b9abf..b8ebaa40b 100644
--- a/source/core/annotations/ut_annotation_cache_schema.sql
+++ b/source/core/annotations/ut_annotation_cache_schema.sql
@@ -1,7 +1,7 @@
create table ut_annotation_cache_schema (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_cache_seq.sql b/source/core/annotations/ut_annotation_cache_seq.sql
index b371b382b..f0f1f17d7 100644
--- a/source/core/annotations/ut_annotation_cache_seq.sql
+++ b/source/core/annotations/ut_annotation_cache_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_annotation_cache_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/annotations/ut_annotation_manager.pkb b/source/core/annotations/ut_annotation_manager.pkb
index 65f7b3e40..b35f40075 100644
--- a/source/core/annotations/ut_annotation_manager.pkb
+++ b/source/core/annotations/ut_annotation_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_manager as
+create or replace noneditionable package body ut_annotation_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -121,6 +121,7 @@ create or replace package body ut_annotation_manager as
and s.type = r.object_type
where s.owner = ']'||ut_utils.qualified_sql_name(a_object_owner)||q'['
and s.type = ']'||ut_utils.qualified_sql_name(a_object_type)||q'['
+ and s.origin_con_id = sys_context('userenv', 'con_id')
) x
where x.is_annotated = 'Y'
order by x.name, x.line]'
@@ -143,34 +144,37 @@ create or replace package body ut_annotation_manager as
l_parse_time date := sysdate;
pragma autonomous_transaction;
begin
- loop
- fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
- for i in 1 .. l_names.count loop
- if l_names(i) != l_name then
- l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
- ut_annotation_cache_manager.update_cache(
- ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
- );
- l_object_lines.delete;
- end if;
-
- l_name := l_names(i);
- l_object_lines(l_object_lines.count+1) := l_lines(i);
- end loop;
- exit when a_sources_cursor%notfound;
+ begin
+ loop
+ fetch a_sources_cursor bulk collect into l_names, l_lines limit c_lines_fetch_limit;
+ for i in 1 .. l_names.count loop
+ if l_names(i) != l_name then
+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
+ ut_annotation_cache_manager.update_cache(
+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
+ );
+ l_object_lines.delete;
+ end if;
+
+ l_name := l_names(i);
+ l_object_lines(l_object_lines.count+1) := l_lines(i);
+ end loop;
+ exit when a_sources_cursor%notfound;
- end loop;
- if a_sources_cursor%rowcount > 0 then
- l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
- ut_annotation_cache_manager.update_cache(
- ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
- );
- l_object_lines.delete;
+ end loop;
+ if a_sources_cursor%rowcount > 0 then
+ l_annotations := ut_annotation_parser.parse_object_annotations(l_object_lines, a_object_type);
+ ut_annotation_cache_manager.update_cache(
+ ut_annotated_object(a_object_owner, l_name, a_object_type, l_parse_time, l_annotations)
+ );
+ l_object_lines.delete;
+ end if;
+ end;
+ if a_sources_cursor%isopen then
+ close a_sources_cursor;
end if;
- close a_sources_cursor;
end;
-
procedure validate_annotation_cache(
a_object_owner varchar2,
a_object_type varchar2,
@@ -231,23 +235,24 @@ create or replace package body ut_annotation_manager as
function get_source_from_sql_text(a_object_name varchar2, a_sql_text ora_name_list_t, a_parts binary_integer) return sys_refcursor is
l_sql_clob clob;
- l_sql_lines ut_varchar2_rows := ut_varchar2_rows();
+ l_sql_lines dbms_preprocessor.source_lines_t := dbms_preprocessor.source_lines_t();
+ l_sql_lines_clob ut_varchar2_list := ut_varchar2_list();
l_result sys_refcursor;
begin
if a_parts > 0 then
for i in 1..a_parts loop
ut_utils.append_to_clob(l_sql_clob, a_sql_text(i));
end loop;
- l_sql_clob := ut_utils.replace_multiline_comments(l_sql_clob);
- -- replace comment lines that contain "-- create or replace"
- l_sql_clob := regexp_replace(l_sql_clob, '^.*[-]{2,}\s*create(\s+or\s+replace).*$', modifier => 'mi');
- -- remove the "create [or replace] [[non]editionable] " so that we have only "type|package" for parsing
- -- needed for dbms_preprocessor
- l_sql_clob := regexp_replace(l_sql_clob, '^(.*?\s*create(\s+or\s+replace)?(\s+(editionable|noneditionable))?\s+?)((package|type).*)', '\5', 1, 1, 'ni');
- -- remove "OWNER." from create or replace statement.
- -- Owner is not supported along with AUTHID - see issue https://github.com/utPLSQL/utPLSQL/issues/1088
- l_sql_clob := regexp_replace(l_sql_clob, '^(package|type)\s+("?[[:alpha:]][[:alnum:]$#_]*"?\.)(.*)', '\1 \3', 1, 1, 'ni');
- l_sql_lines := ut_utils.convert_collection( ut_utils.clob_to_table(l_sql_clob) );
+
+ l_sql_lines_clob := ut_utils.clob_to_table(l_sql_clob);
+ for i in 1..l_sql_lines_clob.count loop
+ l_sql_lines(i) := l_sql_lines_clob(i);
+ end loop;
+
+ -- replace multiline comments that contain "-- create or replace" with single line comment to avoid parsing issues with dbms_preprocessor
+ l_sql_lines := ut_utils.replace_multiline_comments(l_sql_lines);
+ -- strip CREATE header (possibly split across lines) while preserving line numbers
+ l_sql_lines := ut_utils.strip_create_header_lines(l_sql_lines);
end if;
open l_result for
select /*+ no_parallel */ a_object_name as name, column_value||chr(10) as text from table(l_sql_lines);
@@ -264,6 +269,7 @@ create or replace package body ut_annotation_manager as
where s.type = :a_object_type
and s.owner = :a_object_owner
and s.name = :a_object_name
+ and s.origin_con_id = sys_context('userenv', 'con_id')
order by s.line]'
using a_object_name, a_object_type, a_object_owner, a_object_name;
return l_result;
diff --git a/source/core/annotations/ut_annotation_manager.pks b/source/core/annotations/ut_annotation_manager.pks
index 20fcd810f..eedef002a 100644
--- a/source/core/annotations/ut_annotation_manager.pks
+++ b/source/core/annotations/ut_annotation_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_manager authid current_user as
+create or replace noneditionable package ut_annotation_manager authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_obj_cache_info.tps b/source/core/annotations/ut_annotation_obj_cache_info.tps
index 1db3fd190..5436a11ed 100644
--- a/source/core/annotations/ut_annotation_obj_cache_info.tps
+++ b/source/core/annotations/ut_annotation_obj_cache_info.tps
@@ -1,7 +1,7 @@
-create type ut_annotation_obj_cache_info as object(
+create or replace noneditionable type ut_annotation_obj_cache_info as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_objs_cache_info.tps b/source/core/annotations/ut_annotation_objs_cache_info.tps
index fc96e7d25..c29b7d208 100644
--- a/source/core/annotations/ut_annotation_objs_cache_info.tps
+++ b/source/core/annotations/ut_annotation_objs_cache_info.tps
@@ -1,7 +1,7 @@
-create type ut_annotation_objs_cache_info as
+create or replace noneditionable type ut_annotation_objs_cache_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_annotation_parser.pkb b/source/core/annotations/ut_annotation_parser.pkb
index 10bb76b3c..5680d3cd2 100644
--- a/source/core/annotations/ut_annotation_parser.pkb
+++ b/source/core/annotations/ut_annotation_parser.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_annotation_parser as
+create or replace noneditionable package body ut_annotation_parser as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@ create or replace package body ut_annotation_parser as
type tt_comment_list is table of varchar2(32767) index by binary_integer;
gc_annotation_qualifier constant varchar2(1) := '%';
- gc_annot_comment_pattern constant varchar2(30) := '^( |'||chr(09)||')*-- *('||gc_annotation_qualifier||'.*?)$'; -- chr(09) is a tab character
gc_comment_replacer_patter constant varchar2(50) := '{COMMENT#%N%}';
gc_comment_replacer_regex_ptrn constant varchar2(25) := '{COMMENT#(\d+)}';
gc_regexp_identifier constant varchar2(50) := '[[:alpha:]][[:alnum:]$#_]*';
- gc_annotation_block_pattern constant varchar2(200) := '(({COMMENT#.+}'||chr(10)||')+)( |'||chr(09)||')*(procedure|function)\s+(' ||
- gc_regexp_identifier || ')';
+
gc_annotation_pattern constant varchar2(50) := gc_annotation_qualifier || gc_regexp_identifier || '[ '||chr(9)||']*(\(.*?\)\s*?$)?';
@@ -72,133 +70,144 @@ create or replace package body ut_annotation_parser as
a_subobject_name varchar2 := null
) is
l_loop_index binary_integer := 1;
- l_annotation_index binary_integer;
+ l_annotation_index binary_integer := 1;
begin
- -- loop while there are unprocessed comment blocks
- while 0 != nvl(regexp_instr(srcstr => a_source
- ,pattern => gc_comment_replacer_regex_ptrn
- ,occurrence => l_loop_index
- ,subexpression => 1)
- ,0) loop
+ -- loop while there are unprocessed comment blocks
+ while l_annotation_index is not null loop
-- define index of the comment block and get it's content from cache
l_annotation_index := regexp_substr( a_source ,gc_comment_replacer_regex_ptrn ,1 ,l_loop_index ,subexpression => 1);
- add_annotation( a_annotations, l_annotation_index, a_comments( l_annotation_index ), a_subobject_name );
- l_loop_index := l_loop_index + 1;
+ if l_annotation_index is not null then
+ add_annotation( a_annotations, l_annotation_index, a_comments( l_annotation_index ), a_subobject_name );
+ l_loop_index := l_loop_index + 1;
+ end if;
end loop;
end add_annotations;
- procedure add_procedure_annotations(a_annotations in out nocopy ut_annotations, a_source clob, a_comments in out nocopy tt_comment_list) is
- l_proc_comments varchar2(32767);
- l_proc_name varchar2(250);
- l_annot_proc_ind number;
- l_annot_proc_block varchar2(32767);
+ procedure add_procedure_annotations(
+ a_annotations in out nocopy ut_annotations,
+ a_source in dbms_preprocessor.source_lines_t,
+ a_comments in out nocopy tt_comment_list
+ ) is
+ l_proc_comments varchar2(32767);
+ l_proc_name varchar2(250);
+ l_line varchar2(32767);
+ l_in_comment_block boolean := false;
+ l_i binary_integer;
begin
- -- loop through procedures and functions of the package and get all the comment blocks just before it's declaration
- l_annot_proc_ind := 1;
- loop
- --find annotated procedure index
- l_annot_proc_ind := regexp_instr(srcstr => a_source
- ,pattern => gc_annotation_block_pattern
- ,occurrence => 1
- ,modifier => 'i'
- ,position => l_annot_proc_ind);
- exit when l_annot_proc_ind = 0;
-
- --get the annotations with procedure name
- l_annot_proc_block := regexp_substr(srcstr => a_source
- ,pattern => gc_annotation_block_pattern
- ,position => l_annot_proc_ind
- ,occurrence => 1
- ,modifier => 'i');
-
- --extract the annotations
- l_proc_comments := trim(regexp_substr(srcstr => l_annot_proc_block
- ,pattern => gc_annotation_block_pattern
- ,modifier => 'i'
- ,subexpression => 1));
- --extract the procedure name
- l_proc_name := trim(regexp_substr(srcstr => l_annot_proc_block
- ,pattern => gc_annotation_block_pattern
- ,modifier => 'i'
- ,subexpression => 5));
-
- -- parse the comment block for the syntactically correct annotations and store them as an array
- add_annotations(a_annotations, l_proc_comments, a_comments, l_proc_name);
-
- l_annot_proc_ind := instr(a_source, ';', l_annot_proc_ind + length(l_annot_proc_block) );
+ l_i := 1;
+ while l_i <= a_source.count loop
+ l_line := a_source(l_i);
+ -- Comment placeholder line: start/continue accumulating a block
+ if instr(l_line, chr(123) ||'COMMENT#') > 0 then
+ if l_in_comment_block then
+ l_proc_comments := l_proc_comments || l_line || chr(10);
+ else
+ l_in_comment_block := true;
+ l_proc_comments := l_line || chr(10);
+ end if;
+ l_i := l_i + 1;
+ -- Whitespace-only line: allowed between comment block and proc decl
+ elsif l_in_comment_block and trim(replace(l_line, chr(9))) is null then
+ l_i := l_i + 1;
+ -- procedure/function declaration following a comment block
+ elsif l_in_comment_block
+ and regexp_like(l_line, '^\s*(procedure|function)\s+', 'i')
+ then
+ -- extract just the identifier name (subexpression 2)
+ l_proc_name := trim(regexp_substr(srcstr =>l_line
+ ,pattern => '^\s*(procedure|function)\s+('||gc_regexp_identifier||')'
+ ,modifier => 'i'
+ ,subexpression => 2));
+
+ -- pass accumulated comment placeholders + proc name to add_annotations
+ add_annotations(a_annotations, l_proc_comments, a_comments, l_proc_name);
+
+ -- reset comment block state
+ l_in_comment_block := false;
+ l_proc_comments := null;
+
+ -- advance past proc header to the terminating ';'
+ -- the header may span multiple lines e.g. with multi-line parameter lists
+ while l_i <= a_source.count loop
+ exit when instr(a_source(l_i), ';') > 0;
+ l_i := l_i + 1;
+ end loop;
+ l_i := l_i + 1; -- step past the ';' line itself
+ -- Any other line: reset comment block accumulator
+ else
+ l_in_comment_block := false;
+ l_proc_comments := null;
+ l_i := l_i + 1;
+ end if;
end loop;
end add_procedure_annotations;
- function extract_and_replace_comments(a_source in out nocopy clob) return tt_comment_list is
- l_comments tt_comment_list;
- l_comment_pos binary_integer;
- l_comment_line binary_integer;
+ function extract_and_replace_comments(
+ a_source in out nocopy dbms_preprocessor.source_lines_t
+ ) return tt_comment_list is
+ l_comments tt_comment_list;
+ l_line varchar2(32767);
+ l_comment_pos binary_integer;
l_comment_replacer varchar2(50);
- l_source clob := a_source;
begin
- l_comment_pos := 1;
- loop
-
- l_comment_pos := regexp_instr(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,occurrence => 1
- ,modifier => 'm'
- ,position => l_comment_pos);
-
- exit when l_comment_pos = 0;
-
- -- position index is shifted by 1 because gc_annot_comment_pattern contains ^ as first sign
- -- but after instr index already points to the char on that line
- l_comment_pos := l_comment_pos-1;
- l_comment_line := length(substr(a_source,1,l_comment_pos))-length(replace(substr(a_source,1,l_comment_pos),chr(10)))+1;
- l_comments(l_comment_line) := trim(regexp_substr(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,occurrence => 1
- ,position => l_comment_pos
- ,modifier => 'm'
- ,subexpression => 2));
-
- l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', l_comment_line);
-
- l_source := regexp_replace(srcstr => a_source
- ,pattern => gc_annot_comment_pattern
- ,replacestr => l_comment_replacer
- ,position => l_comment_pos
- ,occurrence => 1
- ,modifier => 'm');
- dbms_lob.freetemporary(a_source);
- a_source := l_source;
- dbms_lob.freetemporary(l_source);
- l_comment_pos := l_comment_pos + length(l_comment_replacer);
+ for i in 1 .. a_source.count loop
+ l_line := a_source(i);
+
+ -- fast path: skip lines that can't possibly match
+ -- must contain '--' and '%' to be an annotation comment
+ if instr(l_line, '--') = 0 or instr(l_line, gc_annotation_qualifier) = 0 then
+ continue;
+ end if;
+
+ -- find '--' on the line
+ l_comment_pos := instr(l_line, '--');
+
+ -- verify everything before '--' is only spaces/tabs (matches ^ *( |\t)*--)
+ if trim(replace(substr(l_line, 1, l_comment_pos - 1), chr(9))) is not null then
+ continue;
+ end if;
+
+ -- skip '--' and any spaces after it, then check for annotation qualifier '%'
+ l_comment_pos := l_comment_pos + 2;
+ -- skip optional spaces between -- and %
+ while l_comment_pos <= length(l_line)
+ and substr(l_line, l_comment_pos, 1) = ' '
+ loop
+ l_comment_pos := l_comment_pos + 1;
+ end loop;
+
+ -- must start with annotation qualifier at this position
+ if substr(l_line, l_comment_pos, 1) != gc_annotation_qualifier then
+ continue;
+ end if;
+
+ -- extract annotation text (from % to end of line, trimmed)
+ l_comments(i) := trim(substr(l_line, l_comment_pos));
+
+ -- replace line with placeholder, preserving line number in token
+ l_comment_replacer := replace(gc_comment_replacer_patter, '%N%', i);
+ a_source(i) := l_comment_replacer;
end loop;
- ut_utils.debug_log(a_source);
return l_comments;
end extract_and_replace_comments;
------------------------------------------------------------
--public definitions
------------------------------------------------------------
-
- function parse_object_annotations(a_source clob) return ut_annotations is
- l_source clob := a_source;
+ function parse_object_annotations(a_source dbms_preprocessor.source_lines_t) return ut_annotations is
+ l_source dbms_preprocessor.source_lines_t := a_source;
l_comments tt_comment_list;
l_annotations ut_annotations := ut_annotations();
l_result ut_annotations;
l_comment_index positive;
begin
-
- l_source := ut_utils.replace_multiline_comments(l_source);
-
- -- replace all single line comments with {COMMENT#12} element and store it's content for easier processing
- -- this call modifies l_source
+ l_source := ut_utils.replace_multiline_comments(l_source);
l_comments := extract_and_replace_comments(l_source);
-
add_procedure_annotations(l_annotations, l_source, l_comments);
-
delete_processed_comments(l_comments, l_annotations);
--at this point, only the comments not related to procedures are left, so we process them all as top-level
@@ -208,16 +217,15 @@ create or replace package body ut_annotation_parser as
l_comment_index := l_comments.next(l_comment_index);
end loop;
- dbms_lob.freetemporary(l_source);
-
- select /*+ no_parallel */ value(x) bulk collect into l_result from table(l_annotations) x order by x.position;
+ select /*+ no_parallel */ value(x) bulk collect into l_result from table(l_annotations) x order by x.position asc;
return l_result;
+
end parse_object_annotations;
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t, a_object_type varchar2) return ut_annotations is
l_processed_lines dbms_preprocessor.source_lines_t;
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_annotations ut_annotations := ut_annotations();
ex_package_is_wrapped exception;
pragma exception_init(ex_package_is_wrapped, -24241);
@@ -233,13 +241,11 @@ create or replace package body ut_annotation_parser as
else
l_processed_lines := sys.dbms_preprocessor.get_post_processed_source(a_source_lines);
end if;
- --convert to clob
for i in 1..l_processed_lines.count loop
- ut_utils.append_to_clob(l_source, replace(l_processed_lines(i), chr(13)||chr(10), chr(10)));
+ l_source(i) := replace(l_processed_lines(i), chr(13)||chr(10), chr(10));
end loop;
--parse annotations
l_annotations := parse_object_annotations(l_source);
- dbms_lob.freetemporary(l_source);
exception
when ex_package_is_wrapped or source_text_is_empty then
null;
diff --git a/source/core/annotations/ut_annotation_parser.pks b/source/core/annotations/ut_annotation_parser.pks
index 2f474c883..3e0eaf84c 100644
--- a/source/core/annotations/ut_annotation_parser.pks
+++ b/source/core/annotations/ut_annotation_parser.pks
@@ -1,7 +1,7 @@
-create or replace package ut_annotation_parser authid current_user as
+create or replace noneditionable package ut_annotation_parser authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -29,16 +29,5 @@ create or replace package ut_annotation_parser authid current_user as
*/
function parse_object_annotations(a_source_lines dbms_preprocessor.source_lines_t, a_object_type varchar2) return ut_annotations;
-
- /**
- *
- * @private
- * Parses source code and converts it to annotations
- *
- * @param a_source_lines ordered lines of source code to be parsed
- * @return array containing annotations
- */
- function parse_object_annotations(a_source clob) return ut_annotations;
-
end;
/
diff --git a/source/core/annotations/ut_annotations.tps b/source/core/annotations/ut_annotations.tps
index a6579d236..9e4adc5ae 100644
--- a/source/core/annotations/ut_annotations.tps
+++ b/source/core/annotations/ut_annotations.tps
@@ -1,7 +1,7 @@
-create type ut_annotations
+create or replace noneditionable type ut_annotations
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/annotations/ut_trigger_annotation_parsing.trg b/source/core/annotations/ut_trigger_annotation_parsing.trg
index 437b7742d..75caea5e8 100644
--- a/source/core/annotations/ut_trigger_annotation_parsing.trg
+++ b/source/core/annotations/ut_trigger_annotation_parsing.trg
@@ -2,6 +2,22 @@ create or replace trigger ut_trigger_annotation_parsing
after create or alter or drop
on database
begin
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
if (ora_dict_obj_owner = UPPER('&&UT3_OWNER')
and ora_dict_obj_name = 'UT3_TRIGGER_ALIVE'
and ora_dict_obj_type = 'SYNONYM')
diff --git a/source/core/annotations/ut_trigger_check.pkb b/source/core/annotations/ut_trigger_check.pkb
index 34e43ba46..463243c5e 100644
--- a/source/core/annotations/ut_trigger_check.pkb
+++ b/source/core/annotations/ut_trigger_check.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_trigger_check is
+create or replace noneditionable package body ut_trigger_check is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ create or replace package body ut_trigger_check is
function is_alive return boolean is
pragma autonomous_transaction;
begin
- execute immediate 'create or replace synonym '||ut_utils.ut_owner||'.'||gc_check_object_name||' for no_object';
+ execute immediate 'create or replace noneditionable synonym '||ut_utils.ut_owner||'.'||gc_check_object_name||' for no_object';
return g_is_trigger_live;
end;
diff --git a/source/core/annotations/ut_trigger_check.pks b/source/core/annotations/ut_trigger_check.pks
index cee0b06fd..dae59f3aa 100644
--- a/source/core/annotations/ut_trigger_check.pks
+++ b/source/core/annotations/ut_trigger_check.pks
@@ -1,7 +1,7 @@
-create or replace package ut_trigger_check authid definer is
+create or replace noneditionable package ut_trigger_check authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage.pkb b/source/core/coverage/ut_coverage.pkb
index 7eb5a34c2..be9b4ad5d 100644
--- a/source/core/coverage/ut_coverage.pkb
+++ b/source/core/coverage/ut_coverage.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage is
+create or replace noneditionable package body ut_coverage is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -55,10 +55,11 @@ create or replace package body ut_coverage is
s.text
from {sources_view} s {join_file_mappings}
where s.type in ('PACKAGE BODY', 'TYPE BODY', 'PROCEDURE', 'FUNCTION', 'TRIGGER')
+ and s.origin_con_id = sys_context('userenv', 'con_id')
{filters}
{regex_exc_filters}
and not exists (
- select /*+ cardinality(el {excuded_objects_cardinality})*/ 1
+ select /*+ cardinality(el {excluded_objects_cardinality})*/ 1
from table(:l_excluded_objects) el
where s.owner = el.owner and s.name = el.name
)
@@ -152,7 +153,7 @@ create or replace package body ut_coverage is
l_result := replace(l_result, '{filters}', l_filters);
l_result := replace(l_result, '{mappings_cardinality}', l_mappings_cardinality);
l_result := replace(l_result, '{skipped_objects_cardinality}', ut_utils.scale_cardinality(cardinality(a_skip_objects)));
- l_result := replace(l_result, '{excuded_objects_cardinality}', ut_utils.scale_cardinality(cardinality(coalesce(a_coverage_options.exclude_objects, ut_object_names()))));
+ l_result := replace(l_result, '{excluded_objects_cardinality}', ut_utils.scale_cardinality(cardinality(coalesce(a_coverage_options.exclude_objects, ut_object_names()))));
l_result := replace(l_result, '{regex_exc_filters}', l_regex_exc_filters);
return l_result;
diff --git a/source/core/coverage/ut_coverage.pks b/source/core/coverage/ut_coverage.pks
index 21f3b1f9e..b8bc4e169 100644
--- a/source/core/coverage/ut_coverage.pks
+++ b/source/core/coverage/ut_coverage.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage authid current_user is
+create or replace noneditionable package ut_coverage authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_block.pkb b/source/core/coverage/ut_coverage_block.pkb
index a906b81a3..bfdf13274 100644
--- a/source/core/coverage/ut_coverage_block.pkb
+++ b/source/core/coverage/ut_coverage_block.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_block is
+create or replace noneditionable package body ut_coverage_block is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_block.pks b/source/core/coverage/ut_coverage_block.pks
index 01caca035..9fccb3272 100644
--- a/source/core/coverage/ut_coverage_block.pks
+++ b/source/core/coverage/ut_coverage_block.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_block authid current_user is
+create or replace noneditionable package ut_coverage_block authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper.pkb b/source/core/coverage/ut_coverage_helper.pkb
index e249b3381..ed1bea2ce 100644
--- a/source/core/coverage/ut_coverage_helper.pkb
+++ b/source/core/coverage/ut_coverage_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper is
+create or replace noneditionable package body ut_coverage_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper.pks b/source/core/coverage/ut_coverage_helper.pks
index cd6ed9ec7..11988d935 100644
--- a/source/core/coverage/ut_coverage_helper.pks
+++ b/source/core/coverage/ut_coverage_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper authid definer is
+create or replace noneditionable package ut_coverage_helper authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_block.pkb b/source/core/coverage/ut_coverage_helper_block.pkb
index fb4d4812e..3abbd54fc 100644
--- a/source/core/coverage/ut_coverage_helper_block.pkb
+++ b/source/core/coverage/ut_coverage_helper_block.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper_block is
+create or replace noneditionable package body ut_coverage_helper_block is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_block.pks b/source/core/coverage/ut_coverage_helper_block.pks
index a147d9f4f..dd8c451d7 100644
--- a/source/core/coverage/ut_coverage_helper_block.pks
+++ b/source/core/coverage/ut_coverage_helper_block.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper_block authid current_user is
+create or replace noneditionable package ut_coverage_helper_block authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_profiler.pkb b/source/core/coverage/ut_coverage_helper_profiler.pkb
index f29291efb..f98631593 100644
--- a/source/core/coverage/ut_coverage_helper_profiler.pkb
+++ b/source/core/coverage/ut_coverage_helper_profiler.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_helper_profiler is
+create or replace noneditionable package body ut_coverage_helper_profiler is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_helper_profiler.pks b/source/core/coverage/ut_coverage_helper_profiler.pks
index 0c54a83bf..ca2a44a64 100644
--- a/source/core/coverage/ut_coverage_helper_profiler.pks
+++ b/source/core/coverage/ut_coverage_helper_profiler.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_helper_profiler authid definer is
+create or replace noneditionable package ut_coverage_helper_profiler authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_profiler.pkb b/source/core/coverage/ut_coverage_profiler.pkb
index 663ceab7f..4e874dabf 100644
--- a/source/core/coverage/ut_coverage_profiler.pkb
+++ b/source/core/coverage/ut_coverage_profiler.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_profiler is
+create or replace noneditionable package body ut_coverage_profiler is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_profiler.pks b/source/core/coverage/ut_coverage_profiler.pks
index 9ce9a27f0..788005e15 100644
--- a/source/core/coverage/ut_coverage_profiler.pks
+++ b/source/core/coverage/ut_coverage_profiler.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_profiler authid current_user is
+create or replace noneditionable package ut_coverage_profiler authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_reporter_base.tpb b/source/core/coverage/ut_coverage_reporter_base.tpb
index da2bd27ad..e86af3795 100644
--- a/source/core/coverage/ut_coverage_reporter_base.tpb
+++ b/source/core/coverage/ut_coverage_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_reporter_base is
+create or replace noneditionable type body ut_coverage_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_reporter_base.tps b/source/core/coverage/ut_coverage_reporter_base.tps
index 305c5d757..c4afe389b 100644
--- a/source/core/coverage/ut_coverage_reporter_base.tps
+++ b/source/core/coverage/ut_coverage_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_reporter_base under ut_output_reporter_base(
+create or replace noneditionable type ut_coverage_reporter_base under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/coverage/ut_coverage_sources_tmp.sql b/source/core/coverage/ut_coverage_sources_tmp.sql
index c091d5955..35eb05510 100644
--- a/source/core/coverage/ut_coverage_sources_tmp.sql
+++ b/source/core/coverage/ut_coverage_sources_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_coverage_sources_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/events/ut_event_item.tps b/source/core/events/ut_event_item.tps
index c0ea653ea..d9e1b84fc 100644
--- a/source/core/events/ut_event_item.tps
+++ b/source/core/events/ut_event_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_event_item authid current_user as object (
+create or replace noneditionable type ut_event_item authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_listener.tps b/source/core/events/ut_event_listener.tps
index bbcdbf218..7236fd512 100644
--- a/source/core/events/ut_event_listener.tps
+++ b/source/core/events/ut_event_listener.tps
@@ -1,7 +1,7 @@
-create or replace type ut_event_listener authid current_user as object (
+create or replace noneditionable type ut_event_listener authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_manager.pkb b/source/core/events/ut_event_manager.pkb
index f51019421..50c500d13 100644
--- a/source/core/events/ut_event_manager.pkb
+++ b/source/core/events/ut_event_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_event_manager as
+create or replace noneditionable package body ut_event_manager as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/events/ut_event_manager.pks b/source/core/events/ut_event_manager.pks
index 03b18b728..08db7f5da 100644
--- a/source/core/events/ut_event_manager.pks
+++ b/source/core/events/ut_event_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_event_manager authid current_user as
+create or replace noneditionable package ut_event_manager authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_buffer_base.tpb b/source/core/output_buffers/ut_output_buffer_base.tpb
index 20cec335e..8b9c236ef 100644
--- a/source/core/output_buffers/ut_output_buffer_base.tpb
+++ b/source/core/output_buffers/ut_output_buffer_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_buffer_base is
+create or replace noneditionable type body ut_output_buffer_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -18,18 +18,20 @@ create or replace type body ut_output_buffer_base is
member procedure init(self in out nocopy ut_output_buffer_base, a_output_id raw := null, a_self_type varchar2 := null) is
pragma autonomous_transaction;
- l_exists int;
begin
cleanup_buffer();
self.self_type := coalesce(a_self_type,self.self_type);
self.output_id := coalesce(a_output_id, self.output_id, sys_guid());
self.start_date := coalesce(self.start_date, sysdate);
- select /*+ no_parallel */ count(*) into l_exists from ut_output_buffer_info_tmp where output_id = self.output_id;
- if ( l_exists > 0 ) then
- update /*+ no_parallel */ ut_output_buffer_info_tmp set start_date = self.start_date where output_id = self.output_id;
- else
- insert /*+ no_parallel */ into ut_output_buffer_info_tmp(output_id, start_date) values (self.output_id, self.start_date);
- end if;
+ merge /*+ no_parallel */ into ut_output_buffer_info_tmp dst
+ using (select 1 from dual) src
+ on (dst.output_id = self.output_id)
+ when matched then
+ update
+ set dst.start_date = self.start_date
+ when not matched then
+ insert (output_id, start_date)
+ values (self.output_id, self.start_date);
commit;
dbms_lock.allocate_unique( self.output_id, self.lock_handle);
self.is_closed := 0;
diff --git a/source/core/output_buffers/ut_output_buffer_base.tps b/source/core/output_buffers/ut_output_buffer_base.tps
index f2d9ec686..da2bc9143 100644
--- a/source/core/output_buffers/ut_output_buffer_base.tps
+++ b/source/core/output_buffers/ut_output_buffer_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_buffer_base force authid definer as object(
+create or replace noneditionable type ut_output_buffer_base force authid definer as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_buffer_info_tmp.sql b/source/core/output_buffers/ut_output_buffer_info_tmp.sql
index af730d394..2aba5a55c 100644
--- a/source/core/output_buffers/ut_output_buffer_info_tmp.sql
+++ b/source/core/output_buffers/ut_output_buffer_info_tmp.sql
@@ -1,7 +1,7 @@
create table ut_output_buffer_info_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/output_buffers/ut_output_buffer_tmp.sql b/source/core/output_buffers/ut_output_buffer_tmp.sql
index 1ab19e534..68b738d3f 100644
--- a/source/core/output_buffers/ut_output_buffer_tmp.sql
+++ b/source/core/output_buffers/ut_output_buffer_tmp.sql
@@ -1,7 +1,7 @@
create table ut_output_buffer_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/output_buffers/ut_output_bulk_buffer.tpb b/source/core/output_buffers/ut_output_bulk_buffer.tpb
index cfc173e95..4f6698eaf 100644
--- a/source/core/output_buffers/ut_output_bulk_buffer.tpb
+++ b/source/core/output_buffers/ut_output_bulk_buffer.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_bulk_buffer is
+create or replace noneditionable type body ut_output_bulk_buffer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_bulk_buffer.tps b/source/core/output_buffers/ut_output_bulk_buffer.tps
index d74d4ee14..538bc12a5 100644
--- a/source/core/output_buffers/ut_output_bulk_buffer.tps
+++ b/source/core/output_buffers/ut_output_bulk_buffer.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_bulk_buffer under ut_output_buffer_base (
+create or replace noneditionable type ut_output_bulk_buffer under ut_output_buffer_base (
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_clob_buffer_tmp.sql b/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
index 9ff9f7413..fa61191ce 100644
--- a/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
+++ b/source/core/output_buffers/ut_output_clob_buffer_tmp.sql
@@ -6,7 +6,7 @@ begin
v_table_sql := 'create table ut_output_clob_buffer_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/output_buffers/ut_output_clob_table_buffer.tpb b/source/core/output_buffers/ut_output_clob_table_buffer.tpb
index 3d49ab08d..f6d7c9a66 100644
--- a/source/core/output_buffers/ut_output_clob_table_buffer.tpb
+++ b/source/core/output_buffers/ut_output_clob_table_buffer.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_clob_table_buffer is
+create or replace noneditionable type body ut_output_clob_table_buffer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_clob_table_buffer.tps b/source/core/output_buffers/ut_output_clob_table_buffer.tps
index 191e64c01..b254c1f47 100644
--- a/source/core/output_buffers/ut_output_clob_table_buffer.tps
+++ b/source/core/output_buffers/ut_output_clob_table_buffer.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_clob_table_buffer under ut_output_buffer_base (
+create or replace noneditionable type ut_output_clob_table_buffer under ut_output_buffer_base (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_data_row.tps b/source/core/output_buffers/ut_output_data_row.tps
index c5dd95e98..2eed2ee1f 100644
--- a/source/core/output_buffers/ut_output_data_row.tps
+++ b/source/core/output_buffers/ut_output_data_row.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_data_row as object (
+create or replace noneditionable type ut_output_data_row as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_data_rows.tps b/source/core/output_buffers/ut_output_data_rows.tps
index 097e9beff..a10440617 100644
--- a/source/core/output_buffers/ut_output_data_rows.tps
+++ b/source/core/output_buffers/ut_output_data_rows.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_data_rows as
+create or replace noneditionable type ut_output_data_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_table_buffer.tpb b/source/core/output_buffers/ut_output_table_buffer.tpb
index e8e2442a7..d87362572 100644
--- a/source/core/output_buffers/ut_output_table_buffer.tpb
+++ b/source/core/output_buffers/ut_output_table_buffer.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_table_buffer is
+create or replace noneditionable type body ut_output_table_buffer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/output_buffers/ut_output_table_buffer.tps b/source/core/output_buffers/ut_output_table_buffer.tps
index 154ce4de6..3f13e736d 100644
--- a/source/core/output_buffers/ut_output_table_buffer.tps
+++ b/source/core/output_buffers/ut_output_table_buffer.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_table_buffer under ut_output_buffer_base (
+create or replace noneditionable type ut_output_table_buffer under ut_output_buffer_base (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_context.pkb b/source/core/session_context/ut_session_context.pkb
index a97505e9c..12d104eed 100644
--- a/source/core/session_context/ut_session_context.pkb
+++ b/source/core/session_context/ut_session_context.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_session_context as
+create or replace noneditionable package body ut_session_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_context.pks b/source/core/session_context/ut_session_context.pks
index 63da3399e..a5e4038a0 100644
--- a/source/core/session_context/ut_session_context.pks
+++ b/source/core/session_context/ut_session_context.pks
@@ -1,7 +1,7 @@
-create or replace package ut_session_context as
+create or replace noneditionable package ut_session_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_info.tpb b/source/core/session_context/ut_session_info.tpb
index 7d469651a..14f52b003 100644
--- a/source/core/session_context/ut_session_info.tpb
+++ b/source/core/session_context/ut_session_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_session_info as
+create or replace noneditionable type body ut_session_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/session_context/ut_session_info.tps b/source/core/session_context/ut_session_info.tps
index 17e596d88..d682a6bad 100644
--- a/source/core/session_context/ut_session_info.tps
+++ b/source/core/session_context/ut_session_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_session_info under ut_event_listener (
+create or replace noneditionable type ut_session_info under ut_event_listener (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_console_reporter_base.tpb b/source/core/types/ut_console_reporter_base.tpb
index 909e9355a..0825b8ba2 100644
--- a/source/core/types/ut_console_reporter_base.tpb
+++ b/source/core/types/ut_console_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_console_reporter_base is
+create or replace noneditionable type body ut_console_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_console_reporter_base.tps b/source/core/types/ut_console_reporter_base.tps
index a2c4b6b8c..46b344e6e 100644
--- a/source/core/types/ut_console_reporter_base.tps
+++ b/source/core/types/ut_console_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_console_reporter_base under ut_output_reporter_base(
+create or replace noneditionable type ut_console_reporter_base under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_coverage_options.tpb b/source/core/types/ut_coverage_options.tpb
index a091802af..2accd960a 100644
--- a/source/core/types/ut_coverage_options.tpb
+++ b/source/core/types/ut_coverage_options.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_options as
+create or replace noneditionable type body ut_coverage_options as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_coverage_options.tps b/source/core/types/ut_coverage_options.tps
index a8e3d5129..f2db1dafe 100644
--- a/source/core/types/ut_coverage_options.tps
+++ b/source/core/types/ut_coverage_options.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_options force as object (
+create or replace noneditionable type ut_coverage_options force as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_executable.tpb b/source/core/types/ut_executable.tpb
index d2ce9b79d..2fa3c1b5d 100644
--- a/source/core/types/ut_executable.tpb
+++ b/source/core/types/ut_executable.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_executable is
+create or replace noneditionable type body ut_executable is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -38,20 +38,30 @@ create or replace type body ut_executable is
return ut_metadata.form_name(l_owner_name, object_name, procedure_name);
end;
- member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) is
+ member procedure do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null)
+ is
l_completed_without_errors boolean;
begin
- l_completed_without_errors := self.do_execute(a_item);
+ l_completed_without_errors := self.do_execute(a_item, a_ignored_exception_names, a_ignored_exception_numbers);
end do_execute;
- member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) return boolean is
- l_statement varchar2(4000);
- l_status number;
- l_cursor_number number;
- l_completed_without_errors boolean := true;
- l_failed_with_invalid_pck boolean := true;
- l_start_transaction_id varchar2(250);
- l_end_transaction_id varchar2(250);
+ member function do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null)
+ return boolean is
+ l_statement varchar2(4000);
+ l_status number;
+ l_cursor_number number;
+ l_completed_without_errors boolean := true;
+ l_failed_with_invalid_pck boolean := true;
+ l_start_transaction_id varchar2(250);
+ l_end_transaction_id varchar2(250);
function is_defined return boolean is
l_result boolean := false;
@@ -111,19 +121,33 @@ create or replace type body ut_executable is
if l_completed_without_errors then
l_statement :=
'declare' || chr(10) ||
- ' l_error_stack varchar2(32767);' || chr(10) ||
- ' l_error_backtrace varchar2(32767);' || chr(10) ||
+ ' l_error_stack varchar2(32767);' || chr(10) ||
+ ' l_error_backtrace varchar2(32767);' || chr(10) ||
+ ' l_ignored_exception_detected integer := 0;' || chr(10) ||
'begin' || chr(10) ||
' begin' || chr(10) ||
' ' || self.form_name( a_skip_current_user_schema => true ) || ';' || chr(10) ||
' exception' || chr(10) ||
+ case when a_ignored_exception_names is not empty then
+ ' when ' || ut_utils.table_to_clob( a_ignored_exception_names, ' or ' ) || ' then ' || chr(10) ||
+ ' l_ignored_exception_detected := 1;'
+ end ||
' when others then ' || chr(10) ||
+ case when a_ignored_exception_numbers is not empty then
+ ' if sqlcode in (' || ut_utils.table_to_clob( a_ignored_exception_numbers, ', ' ) || ') then ' || chr(10) ||
+ ' l_ignored_exception_detected := 1; ' || chr(10) ||
+ ' else ' || chr(10) ||
+ ' l_error_stack := dbms_utility.format_error_stack;' || chr(10) ||
+ ' l_error_backtrace := dbms_utility.format_error_backtrace;' || chr(10) ||
+ ' end if;'
+ else
' l_error_stack := dbms_utility.format_error_stack;' || chr(10) ||
- ' l_error_backtrace := dbms_utility.format_error_backtrace;' || chr(10) ||
- ' --raise on ORA-04068, ORA-04061: existing state of packages has been discarded to avoid unrecoverable session exception' || chr(10) ||
+ ' l_error_backtrace := dbms_utility.format_error_backtrace;'
+ end || chr(10) ||
' end;' || chr(10) ||
' :a_error_stack := l_error_stack;' || chr(10) ||
' :a_error_backtrace := l_error_backtrace;' || chr(10) ||
+ ' :a_ignored_exception_detected := l_ignored_exception_detected;' || chr(10) ||
'end;';
ut_utils.debug_log('ut_executable.do_execute l_statement: ' || l_statement);
@@ -139,9 +163,11 @@ create or replace type body ut_executable is
dbms_sql.parse(l_cursor_number, statement => l_statement, language_flag => dbms_sql.native);
dbms_sql.bind_variable(l_cursor_number, 'a_error_stack', to_char(null), 32767);
dbms_sql.bind_variable(l_cursor_number, 'a_error_backtrace', to_char(null), 32767);
+ dbms_sql.bind_variable(l_cursor_number, 'a_ignored_exception_detected', to_number(null));
l_status := dbms_sql.execute(l_cursor_number);
dbms_sql.variable_value(l_cursor_number, 'a_error_stack', self.error_stack);
dbms_sql.variable_value(l_cursor_number, 'a_error_backtrace', self.error_backtrace);
+ dbms_sql.variable_value(l_cursor_number, 'a_ignored_exception_detected', self.ignored_exception_detected);
dbms_sql.close_cursor(l_cursor_number);
exception
when ut_utils.ex_invalid_package then
diff --git a/source/core/types/ut_executable.tps b/source/core/types/ut_executable.tps
index aaa5a3a72..0945a8996 100644
--- a/source/core/types/ut_executable.tps
+++ b/source/core/types/ut_executable.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executable under ut_event_item(
+create or replace noneditionable type ut_executable under ut_event_item(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -18,26 +18,37 @@ create or replace type ut_executable under ut_event_item(
/**
* The name of the event to be executed before and after the executable is invoked
*/
- executable_type varchar2(250 char),
- owner_name varchar2(250 char),
- object_name varchar2(250 char),
- procedure_name varchar2(250 char),
- error_backtrace varchar2(4000),
- error_stack varchar2(4000),
- serveroutput clob,
+ executable_type varchar2(250 char),
+ owner_name varchar2(250 char),
+ object_name varchar2(250 char),
+ procedure_name varchar2(250 char),
+ error_backtrace varchar2(4000),
+ error_stack varchar2(4000),
+ ignored_exception_detected integer,
+ serveroutput clob,
/**
* Used for ordering of executables, as Oracle doesn not guarantee ordering of items in a nested table.
*/
seq_no integer,
constructor function ut_executable( self in out nocopy ut_executable, a_owner varchar2, a_package varchar2, a_procedure_name varchar2, a_executable_type varchar2) return self as result,
member function form_name(a_skip_current_user_schema boolean := false) return varchar2,
- member procedure do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item),
+ member procedure do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows := null
+ ),
/**
* executes the defines executable
* returns true if executed without exceptions
* returns false if exceptions were raised
*/
- member function do_execute(self in out nocopy ut_executable, a_item in out nocopy ut_suite_item) return boolean,
+ member function do_execute(
+ self in out nocopy ut_executable,
+ a_item in out nocopy ut_suite_item,
+ a_ignored_exception_names in ut_varchar2_rows := null,
+ a_ignored_exception_numbers in ut_varchar2_rows :=null
+ ) return boolean,
member function get_error_stack_trace return varchar2
) not final
/
diff --git a/source/core/types/ut_executable_test.tpb b/source/core/types/ut_executable_test.tpb
index fa5872e04..8e48bd70a 100644
--- a/source/core/types/ut_executable_test.tpb
+++ b/source/core/types/ut_executable_test.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_executable_test as
+create or replace noneditionable type body ut_executable_test as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -31,141 +31,129 @@ create or replace type body ut_executable_test as
member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) is
l_completed_without_errors boolean;
begin
- l_completed_without_errors := self.do_execute(a_item, a_expected_error_codes);
+ l_completed_without_errors := self.do_execute(a_item, a_expected_errors);
end do_execute;
member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) return boolean is
- l_expected_except_message varchar2(4000);
- l_expected_error_numbers ut_integer_list;
-
- function build_exception_numbers_list(
- a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
- ) return ut_integer_list is
+ l_failure_message varchar2(32767);
+ l_expected_error_names ut_varchar2_rows;
+ l_expected_error_numbers ut_varchar2_rows;
+ l_all_expected_errors ut_varchar2_rows;
+
+ procedure build_expected_exceptions(
+ a_item in out nocopy ut_suite_item,
+ a_exception_definitions in ut_varchar2_rows,
+ a_exception_names_list out ut_varchar2_rows,
+ a_exception_numbers_list out ut_varchar2_rows
+ ) is
l_exception_number integer;
- l_exception_number_list ut_integer_list := ut_integer_list();
- c_regexp_for_exception_no constant varchar2(30) := '^-?[[:digit:]]{1,5}$';
-
- c_integer_exception constant varchar2(1) := 'I';
- c_named_exception constant varchar2(1) := 'N';
-
- function is_valid_qualified_name (a_name varchar2) return boolean is
- l_name varchar2(500);
- begin
- l_name := dbms_assert.qualified_sql_name(a_name);
- return true;
- exception when others then
- return false;
- end;
-
- function check_exception_type(a_exception_name in varchar2) return varchar2 is
- l_exception_type varchar2(50);
- begin
- --check if it is a predefined exception
+ l_exception_name varchar2(128);
+ function to_exception_number (a_exception_var in varchar2, a_item ut_suite_item) return integer is
+ function get_exception_no(a_exception_var in varchar2) return integer is
+ l_exc_no integer;
begin
- execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
- l_exception_type := c_named_exception;
+ execute immediate 'declare l_exception integer; begin :l_exception := '||a_exception_var||'; end;'
+ using out l_exc_no;
+ return l_exc_no;
exception
when others then
- if dbms_utility.format_error_stack() like '%PLS-00485%' then
- declare
- e_invalid_number exception;
- pragma exception_init ( e_invalid_number, -6502 );
- begin
- execute immediate 'declare x integer := '||a_exception_name||'; begin null; end;';
- l_exception_type := c_integer_exception;
- exception
- when others then
- null;
- end;
- end if;
+ return null;
end;
- return l_exception_type;
- end;
-
- function get_exception_number (a_exception_var in varchar2) return integer is
- l_exc_no integer;
- l_exc_type varchar2(50);
function remap_no_data_found (a_number integer) return integer is
begin
return case a_number when 100 then -1403 else a_number end;
end;
begin
- l_exc_type := check_exception_type(a_exception_var);
-
- execute immediate
- case l_exc_type
- when c_integer_exception then
- 'declare l_exception number; begin :l_exception := '||a_exception_var||'; end;'
- when c_named_exception then
- 'begin raise '||a_exception_var||'; exception when others then :l_exception := sqlcode; end;'
- else
- 'begin :l_exception := null; end;'
- end
- using out l_exc_no;
+ return remap_no_data_found(
+ coalesce(
+ get_exception_no(a_exception_var),
+ get_exception_no(a_item.object_name||'.'||a_exception_var),
+ get_exception_no(a_item.object_owner||'.'||a_exception_var),
+ get_exception_no(a_item.object_owner||'.'||a_item.object_name||'.'||a_exception_var)
+ )
+ );
+ end;
+
+ function to_exception_name (a_exception_var in varchar2, a_item ut_suite_item) return varchar2 is
+ function verify_name(a_exception_name in varchar2) return varchar2 is
+ begin
+ --check if it is an existing, named exception
+ execute immediate 'begin null; exception when '||a_exception_name||' then null; end;';
+ return a_exception_name;
+ exception
+ when others then
+ return null;
+ end;
+ begin
+ return coalesce(
+ verify_name(a_exception_var),
+ verify_name(a_item.object_name||'.'||a_exception_var),
+ verify_name(a_item.object_owner||'.'||a_exception_var),
+ verify_name(a_item.object_owner||'.'||a_item.object_name||'.'||a_exception_var)
+ );
- return remap_no_data_found(l_exc_no);
end;
begin
- if a_expected_error_codes is not empty then
- for i in 1 .. a_expected_error_codes.count loop
- /**
- * Check if its a valid qualified name and if so try to resolve name to an exception number
- */
- if is_valid_qualified_name(a_expected_error_codes(i)) then
- l_exception_number := get_exception_number(a_expected_error_codes(i));
- elsif regexp_like(a_expected_error_codes(i), c_regexp_for_exception_no) then
- l_exception_number := a_expected_error_codes(i);
- end if;
-
- if l_exception_number is null then
+ a_exception_names_list := ut_varchar2_rows();
+ a_exception_numbers_list := ut_varchar2_rows();
+ if a_exception_definitions is not empty then
+ for i in 1 .. a_exception_definitions.count loop
+ l_exception_number :=
+ coalesce(
+ to_exception_number(a_exception_definitions(i), a_item),
+ to_number(a_exception_definitions(i) default null on conversion error )
+ );
+ l_exception_name := to_exception_name(a_exception_definitions(i), a_item);
+
+ if l_exception_number is null and l_exception_name is null then
a_item.put_warning(
- 'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Parameter ignored.',
+ 'Invalid parameter value "'||a_exception_definitions(i)||'" for "--%throws" annotation. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
elsif l_exception_number >= 0 then
a_item.put_warning(
- 'Invalid parameter value "'||a_expected_error_codes(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
+ 'Invalid parameter value "'||a_exception_definitions(i)||'" for "--%throws" annotation. Exception value must be a negative integer. Parameter ignored.',
self.procedure_name,
a_item.line_no
);
- else
- l_exception_number_list.extend;
- l_exception_number_list(l_exception_number_list.last) := l_exception_number;
+ elsif l_exception_number is not null then
+ a_exception_numbers_list.extend;
+ a_exception_numbers_list(a_exception_numbers_list.last) := l_exception_number;
+ elsif l_exception_name is not null then
+ a_exception_names_list.extend;
+ a_exception_names_list(a_exception_names_list.last) := l_exception_name;
end if;
- l_exception_number := null;
end loop;
end if;
-
- return l_exception_number_list;
end;
- function failed_expec_errnum_message(a_expected_error_codes in ut_integer_list) return varchar is
+
+ function get_exception_failure_message(a_expected_errors_list ut_varchar2_rows) return varchar2 is
l_actual_error_no integer;
- l_expected_error_codes varchar2(4000);
+ l_expected_errors varchar2(4000);
l_fail_message varchar2(4000);
begin
--Convert the ut_varchar2_list to string to can construct the message
- l_expected_error_codes := ut_utils.table_to_clob(a_expected_error_codes, ', ');
+ l_expected_errors := ut_utils.table_to_clob(a_expected_errors_list, ', ');
if self.error_stack is null then
- l_fail_message := 'Expected one of exceptions ('||l_expected_error_codes||') but nothing was raised.';
+ l_fail_message := 'Expected one of exceptions ('|| l_expected_errors|| ') but nothing was raised.';
else
l_actual_error_no := regexp_substr(self.error_stack, '^[[:alpha:]]{3}(-[0-9]+)', subexpression=>1);
- if not l_actual_error_no member of a_expected_error_codes or l_actual_error_no is null then
+ if not l_actual_error_no member of a_expected_errors_list or l_actual_error_no is null then
l_fail_message := 'Actual: '||l_actual_error_no||' was expected to ';
- if cardinality(a_expected_error_codes) > 1 then
- l_fail_message := l_fail_message || 'be one of: ('||l_expected_error_codes||')';
+ if cardinality(a_expected_errors_list) > 1 then
+ l_fail_message := l_fail_message || 'be one of: ('|| l_expected_errors|| ')';
else
- l_fail_message := l_fail_message || 'equal: '||l_expected_error_codes;
+ l_fail_message := l_fail_message || 'equal: '||l_expected_errors;
end if;
l_fail_message := substr( l_fail_message||chr(10)||self.error_stack||chr(10)||self.error_backtrace, 1, 4000 );
end if;
@@ -175,14 +163,16 @@ create or replace type body ut_executable_test as
end;
begin
--Create a ut_executable object and call do_execute after that get the data to know the test's execution result
- self.do_execute(a_item);
- l_expected_error_numbers := build_exception_numbers_list(a_item, a_expected_error_codes);
- if l_expected_error_numbers is not null and l_expected_error_numbers is not empty then
- l_expected_except_message := failed_expec_errnum_message( l_expected_error_numbers );
+ build_expected_exceptions(a_item, a_expected_errors, l_expected_error_names, l_expected_error_numbers );
+
+ self.do_execute(a_item, l_expected_error_names, l_expected_error_numbers);
+ l_all_expected_errors := l_expected_error_names multiset union all l_expected_error_numbers;
+ if l_all_expected_errors is not empty and self.ignored_exception_detected = 0 then
+ l_failure_message := get_exception_failure_message( l_all_expected_errors);
- if l_expected_except_message is not null then
+ if l_failure_message is not null then
ut_expectation_processor.add_expectation_result(
- ut_expectation_result(ut_utils.gc_failure, null, l_expected_except_message, false)
+ ut_expectation_result(ut_utils.gc_failure, null, l_failure_message, false)
);
end if;
self.error_stack := null;
diff --git a/source/core/types/ut_executable_test.tps b/source/core/types/ut_executable_test.tps
index 42b6080df..d477456f6 100644
--- a/source/core/types/ut_executable_test.tps
+++ b/source/core/types/ut_executable_test.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executable_test authid current_user under ut_executable (
+create or replace noneditionable type ut_executable_test authid current_user under ut_executable (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@ create or replace type ut_executable_test authid current_user under ut_executabl
member procedure do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
),
member function do_execute(
self in out nocopy ut_executable_test, a_item in out nocopy ut_suite_item,
- a_expected_error_codes in ut_varchar2_rows
+ a_expected_errors in ut_varchar2_rows
) return boolean
) final;
diff --git a/source/core/types/ut_executables.tps b/source/core/types/ut_executables.tps
index d6d52b3d2..7718c44b8 100644
--- a/source/core/types/ut_executables.tps
+++ b/source/core/types/ut_executables.tps
@@ -1,7 +1,7 @@
-create or replace type ut_executables as
+create or replace noneditionable type ut_executables as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_result.tpb b/source/core/types/ut_expectation_result.tpb
index 0b3adf983..3ffd11789 100644
--- a/source/core/types/ut_expectation_result.tpb
+++ b/source/core/types/ut_expectation_result.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_result is
+create or replace noneditionable type body ut_expectation_result is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_result.tps b/source/core/types/ut_expectation_result.tps
index d4b4c7548..e7eedd5ce 100644
--- a/source/core/types/ut_expectation_result.tps
+++ b/source/core/types/ut_expectation_result.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_result under ut_event_item(
+create or replace noneditionable type ut_expectation_result under ut_event_item(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_expectation_results.tps b/source/core/types/ut_expectation_results.tps
index e5e4c6223..168941112 100644
--- a/source/core/types/ut_expectation_results.tps
+++ b/source/core/types/ut_expectation_results.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_results as
+create or replace noneditionable type ut_expectation_results as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mapping.tpb b/source/core/types/ut_file_mapping.tpb
index dab1e35c5..d693ac633 100644
--- a/source/core/types/ut_file_mapping.tpb
+++ b/source/core/types/ut_file_mapping.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_file_mapping as
+create or replace noneditionable type body ut_file_mapping as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mapping.tps b/source/core/types/ut_file_mapping.tps
index 941d95283..d28ef40ae 100644
--- a/source/core/types/ut_file_mapping.tps
+++ b/source/core/types/ut_file_mapping.tps
@@ -1,7 +1,7 @@
-create or replace type ut_file_mapping as object(
+create or replace noneditionable type ut_file_mapping as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_file_mappings.tps b/source/core/types/ut_file_mappings.tps
index 240fb8dd7..715530ee0 100644
--- a/source/core/types/ut_file_mappings.tps
+++ b/source/core/types/ut_file_mappings.tps
@@ -1,7 +1,7 @@
-create or replace type ut_file_mappings as
+create or replace noneditionable type ut_file_mappings as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_integer_list.tps b/source/core/types/ut_integer_list.tps
index ec9a2a78f..b15cf743c 100644
--- a/source/core/types/ut_integer_list.tps
+++ b/source/core/types/ut_integer_list.tps
@@ -1,7 +1,7 @@
-create or replace type ut_integer_list as
+create or replace noneditionable type ut_integer_list as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_key_value_pair.tps b/source/core/types/ut_key_value_pair.tps
index 5a337e608..e26fff031 100644
--- a/source/core/types/ut_key_value_pair.tps
+++ b/source/core/types/ut_key_value_pair.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_value_pair force as object(
+create or replace noneditionable type ut_key_value_pair force as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_key_value_pairs.tps b/source/core/types/ut_key_value_pairs.tps
index 24bdded36..d9e829dc9 100644
--- a/source/core/types/ut_key_value_pairs.tps
+++ b/source/core/types/ut_key_value_pairs.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_value_pairs as
+create or replace noneditionable type ut_key_value_pairs as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_logical_suite.tpb b/source/core/types/ut_logical_suite.tpb
index 036d40d51..c91320d8a 100644
--- a/source/core/types/ut_logical_suite.tpb
+++ b/source/core/types/ut_logical_suite.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_logical_suite as
+create or replace noneditionable type body ut_logical_suite as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_logical_suite.tps b/source/core/types/ut_logical_suite.tps
index c4f2f699b..245c422a1 100644
--- a/source/core/types/ut_logical_suite.tps
+++ b/source/core/types/ut_logical_suite.tps
@@ -1,7 +1,7 @@
-create or replace type ut_logical_suite force under ut_suite_item (
+create or replace noneditionable type ut_logical_suite force under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_name.tpb b/source/core/types/ut_object_name.tpb
index 76acc15bf..67834a9ed 100644
--- a/source/core/types/ut_object_name.tpb
+++ b/source/core/types/ut_object_name.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_object_name as
+create or replace noneditionable type body ut_object_name as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_name.tps b/source/core/types/ut_object_name.tps
index 5f8f724c4..7f6341a32 100644
--- a/source/core/types/ut_object_name.tps
+++ b/source/core/types/ut_object_name.tps
@@ -1,7 +1,7 @@
-create or replace type ut_object_name as object (
+create or replace noneditionable type ut_object_name as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_object_names.tps b/source/core/types/ut_object_names.tps
index 03830be17..879493a63 100644
--- a/source/core/types/ut_object_names.tps
+++ b/source/core/types/ut_object_names.tps
@@ -1,7 +1,7 @@
-create or replace type ut_object_names as
+create or replace noneditionable type ut_object_names as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb
index 48970be5a..4553f1780 100644
--- a/source/core/types/ut_output_reporter_base.tpb
+++ b/source/core/types/ut_output_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_output_reporter_base is
+create or replace noneditionable type body ut_output_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps
index 21eed9957..b9ec4f7cd 100644
--- a/source/core/types/ut_output_reporter_base.tps
+++ b/source/core/types/ut_output_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_output_reporter_base under ut_reporter_base(
+create or replace noneditionable type ut_output_reporter_base under ut_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_path_item.tpb b/source/core/types/ut_path_item.tpb
index 6cdb2b8ad..486fde865 100644
--- a/source/core/types/ut_path_item.tpb
+++ b/source/core/types/ut_path_item.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_path_item as
+create or replace noneditionable type body ut_path_item as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_path_item.tps b/source/core/types/ut_path_item.tps
index c8ec81be5..fdc1e8ac2 100644
--- a/source/core/types/ut_path_item.tps
+++ b/source/core/types/ut_path_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_path_item as object (
+create or replace noneditionable type ut_path_item as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_path_items.tps b/source/core/types/ut_path_items.tps
index 0c87cf28c..64f8dd5fe 100644
--- a/source/core/types/ut_path_items.tps
+++ b/source/core/types/ut_path_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_path_items as
+create or replace noneditionable type ut_path_items as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporter_base.tpb b/source/core/types/ut_reporter_base.tpb
index 017dc8971..e457645f4 100644
--- a/source/core/types/ut_reporter_base.tpb
+++ b/source/core/types/ut_reporter_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_reporter_base is
+create or replace noneditionable type body ut_reporter_base is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporter_base.tps b/source/core/types/ut_reporter_base.tps
index de157136e..af0472dc5 100644
--- a/source/core/types/ut_reporter_base.tps
+++ b/source/core/types/ut_reporter_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporter_base under ut_event_listener (
+create or replace noneditionable type ut_reporter_base under ut_event_listener (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporter_info.tps b/source/core/types/ut_reporter_info.tps
index f09c42e07..29c7559f1 100644
--- a/source/core/types/ut_reporter_info.tps
+++ b/source/core/types/ut_reporter_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporter_info as object (
+create or replace noneditionable type ut_reporter_info as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporters.tps b/source/core/types/ut_reporters.tps
index a2802bb26..fba22480f 100644
--- a/source/core/types/ut_reporters.tps
+++ b/source/core/types/ut_reporters.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporters as
+create or replace noneditionable type ut_reporters as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_reporters_info.tps b/source/core/types/ut_reporters_info.tps
index 82c264f36..4f6f054a3 100644
--- a/source/core/types/ut_reporters_info.tps
+++ b/source/core/types/ut_reporters_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_reporters_info as
+create or replace noneditionable type ut_reporters_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_results_counter.tpb b/source/core/types/ut_results_counter.tpb
index 811389e0e..54f9e0b48 100644
--- a/source/core/types/ut_results_counter.tpb
+++ b/source/core/types/ut_results_counter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_results_counter as
+create or replace noneditionable type body ut_results_counter as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_results_counter.tps b/source/core/types/ut_results_counter.tps
index 913ae0967..477d4b217 100644
--- a/source/core/types/ut_results_counter.tps
+++ b/source/core/types/ut_results_counter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_results_counter as object(
+create or replace noneditionable type ut_results_counter as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run.tpb b/source/core/types/ut_run.tpb
index 660c88791..80621b5ad 100644
--- a/source/core/types/ut_run.tpb
+++ b/source/core/types/ut_run.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_run as
+create or replace noneditionable type body ut_run as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run.tps b/source/core/types/ut_run.tps
index 1878a2d46..551e56ac4 100644
--- a/source/core/types/ut_run.tps
+++ b/source/core/types/ut_run.tps
@@ -1,7 +1,7 @@
-create or replace type ut_run under ut_suite_item (
+create or replace noneditionable type ut_run under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run_info.tpb b/source/core/types/ut_run_info.tpb
index 6edc0f109..3de74b2b4 100644
--- a/source/core/types/ut_run_info.tpb
+++ b/source/core/types/ut_run_info.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_run_info as
+create or replace noneditionable type body ut_run_info as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_run_info.tps b/source/core/types/ut_run_info.tps
index 4a3da691f..00919b172 100644
--- a/source/core/types/ut_run_info.tps
+++ b/source/core/types/ut_run_info.tps
@@ -1,7 +1,7 @@
-create or replace type ut_run_info under ut_event_item (
+create or replace noneditionable type ut_run_info under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_stack.tpb b/source/core/types/ut_stack.tpb
index b5f4e8747..4298ae35c 100644
--- a/source/core/types/ut_stack.tpb
+++ b/source/core/types/ut_stack.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_stack as
+create or replace noneditionable type body ut_stack as
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_stack.tps b/source/core/types/ut_stack.tps
index 23112fdde..ed79bea55 100644
--- a/source/core/types/ut_stack.tps
+++ b/source/core/types/ut_stack.tps
@@ -1,9 +1,9 @@
-create or replace type ut_stack as object (
+create or replace noneditionable type ut_stack as object (
top integer,
tokens ut_varchar2_list,
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite.tpb b/source/core/types/ut_suite.tpb
index e3a4687d8..b4e3eabf0 100644
--- a/source/core/types/ut_suite.tpb
+++ b/source/core/types/ut_suite.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite as
+create or replace noneditionable type body ut_suite as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite.tps b/source/core/types/ut_suite.tps
index ff7f3e171..edce778f1 100644
--- a/source/core/types/ut_suite.tps
+++ b/source/core/types/ut_suite.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite under ut_logical_suite (
+create or replace noneditionable type ut_suite under ut_logical_suite (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_cache_row.tps b/source/core/types/ut_suite_cache_row.tps
index c147a8757..1ee371a88 100644
--- a/source/core/types/ut_suite_cache_row.tps
+++ b/source/core/types/ut_suite_cache_row.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_cache_row as object (
+create or replace noneditionable type ut_suite_cache_row as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_cache_rows.tps b/source/core/types/ut_suite_cache_rows.tps
index 9b6919df5..84bcc9f75 100644
--- a/source/core/types/ut_suite_cache_rows.tps
+++ b/source/core/types/ut_suite_cache_rows.tps
@@ -1,7 +1,7 @@
-create type ut_suite_cache_rows as
+create or replace noneditionable type ut_suite_cache_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_context.tpb b/source/core/types/ut_suite_context.tpb
index be92e6fc9..dad24e42e 100644
--- a/source/core/types/ut_suite_context.tpb
+++ b/source/core/types/ut_suite_context.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_context as
+create or replace noneditionable type body ut_suite_context as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_context.tps b/source/core/types/ut_suite_context.tps
index 5e3d20f87..b890e2633 100644
--- a/source/core/types/ut_suite_context.tps
+++ b/source/core/types/ut_suite_context.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_context under ut_suite (
+create or replace noneditionable type ut_suite_context under ut_suite (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_item.tpb b/source/core/types/ut_suite_item.tpb
index 648f10dd1..8e8c6fd90 100644
--- a/source/core/types/ut_suite_item.tpb
+++ b/source/core/types/ut_suite_item.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_suite_item as
+create or replace noneditionable type body ut_suite_item as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_item.tps b/source/core/types/ut_suite_item.tps
index 8184f2a63..2e990353f 100644
--- a/source/core/types/ut_suite_item.tps
+++ b/source/core/types/ut_suite_item.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_item force under ut_event_item (
+create or replace noneditionable type ut_suite_item force under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_suite_items.tps b/source/core/types/ut_suite_items.tps
index 615283446..b7ce9873c 100644
--- a/source/core/types/ut_suite_items.tps
+++ b/source/core/types/ut_suite_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_suite_items as
+create or replace noneditionable type ut_suite_items as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_test.tpb b/source/core/types/ut_test.tpb
index 946f8990d..61a1e39f8 100644
--- a/source/core/types/ut_test.tpb
+++ b/source/core/types/ut_test.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_test as
+create or replace noneditionable type body ut_test as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_test.tps b/source/core/types/ut_test.tps
index dbba64961..cb50c2fd4 100644
--- a/source/core/types/ut_test.tps
+++ b/source/core/types/ut_test.tps
@@ -1,7 +1,7 @@
-create or replace type ut_test force under ut_suite_item (
+create or replace noneditionable type ut_test force under ut_suite_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_varchar2_list.tps b/source/core/types/ut_varchar2_list.tps
index f0b5df509..8203a4bab 100644
--- a/source/core/types/ut_varchar2_list.tps
+++ b/source/core/types/ut_varchar2_list.tps
@@ -1,7 +1,7 @@
-create or replace type ut_varchar2_list as
+create or replace noneditionable type ut_varchar2_list as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/types/ut_varchar2_rows.tps b/source/core/types/ut_varchar2_rows.tps
index e7fa29c29..a2e25e9fb 100644
--- a/source/core/types/ut_varchar2_rows.tps
+++ b/source/core/types/ut_varchar2_rows.tps
@@ -1,7 +1,7 @@
-create or replace type ut_varchar2_rows as
+create or replace noneditionable type ut_varchar2_rows as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_dbms_output_cache.sql b/source/core/ut_dbms_output_cache.sql
index e61b403c8..802f30942 100644
--- a/source/core/ut_dbms_output_cache.sql
+++ b/source/core/ut_dbms_output_cache.sql
@@ -1,15 +1,16 @@
/*
-utPLSQL - Version 3
-Copyright 2016 - 2021 utPLSQL Project
-Licensed under the Apache License, Version 2.0 (the "License"):
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
/*
* This table is not a global temporary table as it needs to allow cross-session data exchange
diff --git a/source/core/ut_expectation_processor.pkb b/source/core/ut_expectation_processor.pkb
index c165a9ee5..3fb39a5b9 100644
--- a/source/core/ut_expectation_processor.pkb
+++ b/source/core/ut_expectation_processor.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_expectation_processor as
+create or replace noneditionable package body ut_expectation_processor as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_expectation_processor.pks b/source/core/ut_expectation_processor.pks
index dd9187526..5349ee70a 100644
--- a/source/core/ut_expectation_processor.pks
+++ b/source/core/ut_expectation_processor.pks
@@ -1,7 +1,7 @@
-create or replace package ut_expectation_processor authid current_user as
+create or replace noneditionable package ut_expectation_processor authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_file_mapper.pkb b/source/core/ut_file_mapper.pkb
index 425360533..40204a5da 100644
--- a/source/core/ut_file_mapper.pkb
+++ b/source/core/ut_file_mapper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_file_mapper is
+create or replace noneditionable package body ut_file_mapper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_file_mapper.pks b/source/core/ut_file_mapper.pks
index adc4c983f..1363e81ec 100644
--- a/source/core/ut_file_mapper.pks
+++ b/source/core/ut_file_mapper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_file_mapper authid current_user is
+create or replace noneditionable package ut_file_mapper authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_metadata.pkb b/source/core/ut_metadata.pkb
index 360b7b97d..d9939ad45 100644
--- a/source/core/ut_metadata.pkb
+++ b/source/core/ut_metadata.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_metadata as
+create or replace noneditionable package body ut_metadata as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_metadata.pks b/source/core/ut_metadata.pks
index 27bfa5d30..42f136504 100644
--- a/source/core/ut_metadata.pks
+++ b/source/core/ut_metadata.pks
@@ -1,7 +1,7 @@
-create or replace package ut_metadata authid current_user as
+create or replace noneditionable package ut_metadata authid current_user as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_savepoint_seq.sql b/source/core/ut_savepoint_seq.sql
index 5b0cda35e..2026ab0e3 100644
--- a/source/core/ut_savepoint_seq.sql
+++ b/source/core/ut_savepoint_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_savepoint_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_builder.pkb b/source/core/ut_suite_builder.pkb
index ebb113370..4f0e28606 100644
--- a/source/core/ut_suite_builder.pkb
+++ b/source/core/ut_suite_builder.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_builder is
+create or replace noneditionable package body ut_suite_builder is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -754,7 +754,7 @@ create or replace package body ut_suite_builder is
l_used_context_names(l_context_name) := true;
l_context := ut_suite_context(a_parent.object_owner, a_parent.object_name, l_context_name, l_context_pos );
- l_context.path := a_parent.path||'.'||l_context_name;
+ l_context.path := a_parent.path||'.'||l_context.name;
l_context.description := coalesce( a_annotations.by_line( l_context_pos ).text, l_context_name );
l_context.parse_time := a_annotations.parse_time;
diff --git a/source/core/ut_suite_builder.pks b/source/core/ut_suite_builder.pks
index 352601a6d..35f207ea4 100644
--- a/source/core/ut_suite_builder.pks
+++ b/source/core/ut_suite_builder.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_builder authid current_user is
+create or replace noneditionable package ut_suite_builder authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_cache.sql b/source/core/ut_suite_cache.sql
index 182caabd0..1d7389e9f 100644
--- a/source/core/ut_suite_cache.sql
+++ b/source/core/ut_suite_cache.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_manager.pkb b/source/core/ut_suite_cache_manager.pkb
index e5fdae7ac..9aa3cf63d 100644
--- a/source/core/ut_suite_cache_manager.pkb
+++ b/source/core/ut_suite_cache_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_cache_manager is
+create or replace noneditionable package body ut_suite_cache_manager is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_cache_manager.pks b/source/core/ut_suite_cache_manager.pks
index 81b1e0136..6ac1d7bd6 100644
--- a/source/core/ut_suite_cache_manager.pks
+++ b/source/core/ut_suite_cache_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_cache_manager authid definer is
+create or replace noneditionable package ut_suite_cache_manager authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_cache_package.sql b/source/core/ut_suite_cache_package.sql
index 7a146ff83..40b7b8dec 100644
--- a/source/core/ut_suite_cache_package.sql
+++ b/source/core/ut_suite_cache_package.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache_package (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_schema.sql b/source/core/ut_suite_cache_schema.sql
index 636816e65..cace332e3 100644
--- a/source/core/ut_suite_cache_schema.sql
+++ b/source/core/ut_suite_cache_schema.sql
@@ -1,7 +1,7 @@
create table ut_suite_cache_schema (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_cache_seq.sql b/source/core/ut_suite_cache_seq.sql
index e1e560286..020c25c4d 100644
--- a/source/core/ut_suite_cache_seq.sql
+++ b/source/core/ut_suite_cache_seq.sql
@@ -1,7 +1,7 @@
create sequence ut_suite_cache_seq
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/core/ut_suite_manager.pkb b/source/core/ut_suite_manager.pkb
index c418de638..fa60be59e 100644
--- a/source/core/ut_suite_manager.pkb
+++ b/source/core/ut_suite_manager.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_manager is
+create or replace noneditionable package body ut_suite_manager is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_manager.pks b/source/core/ut_suite_manager.pks
index 07539139a..60c3595bb 100644
--- a/source/core/ut_suite_manager.pks
+++ b/source/core/ut_suite_manager.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_manager authid current_user is
+create or replace noneditionable package ut_suite_manager authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_suite_tag_filter.pkb b/source/core/ut_suite_tag_filter.pkb
index 2d9436301..447ba47d5 100644
--- a/source/core/ut_suite_tag_filter.pkb
+++ b/source/core/ut_suite_tag_filter.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_suite_tag_filter is
+create or replace noneditionable package body ut_suite_tag_filter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -19,29 +19,28 @@ create or replace package body ut_suite_tag_filter is
/**
* Constants use in postfix and infix transformations
*/
- gc_operators constant ut_varchar2_list := ut_varchar2_list('|','&','!');
+ gc_operators constant ut_varchar2_list := ut_varchar2_list('|','&','!');
gc_unary_operators constant ut_varchar2_list := ut_varchar2_list('!'); -- right side associative operator
gc_binary_operators constant ut_varchar2_list := ut_varchar2_list('|','&'); -- left side associative operator
gc_reserved_tag_words constant ut_varchar2_list := ut_varchar2_list('none','any');
- gc_tags_column_name constant varchar2(250) := 'tags';
gc_exception_msg constant varchar2(200) := 'Invalid tag expression';
-
- type t_precedence_table is table of number index by varchar2(1);
- g_precedence t_precedence_table;
+
+ type t_precedence_table is table of number index by varchar2(1);
+ g_precedence t_precedence_table;
function tokenize_tags_string(a_tags in varchar2) return ut_varchar2_list is
- l_tags_tokens ut_varchar2_list := ut_varchar2_list();
+ l_tags_tokens ut_varchar2_list := ut_varchar2_list();
begin
--Tokenize a string into operators and tags
select regexp_substr(a_tags,'([^!()|&]+)|([!()|&])', 1, level) as string_parts
bulk collect into l_tags_tokens
from dual connect by regexp_substr (a_tags, '([^!()|&]+)|([!()|&])', 1, level) is not null;
-
+
return l_tags_tokens;
end;
/*
- To support a legact tag notation
+ To support a legact tag notation
, = OR
- = NOT
we will perform a replace of that characters into
@@ -57,36 +56,36 @@ create or replace package body ut_suite_tag_filter is
l_tags_exclude varchar2(4000);
l_return_tag varchar2(4000);
begin
- if instr(a_tags,',') > 0 or instr(a_tags,'-') > 0 then
+ if instr(a_tags,',') > 0 or instr(a_tags,'-') > 0 then
select '('||listagg( t.column_value,'|')
- within group( order by column_value)||')'
+ within group( order by column_value)||')'
into l_tags_include
from table(l_tags) t
where t.column_value not like '-%';
-
+
select '('||listagg( replace(t.column_value,'-','!'),' & ')
within group( order by column_value)||')'
into l_tags_exclude
from table(l_tags) t
- where t.column_value like '-%';
-
+ where t.column_value like '-%';
+
l_return_tag:=
- case
+ case
when l_tags_include <> '()' and l_tags_exclude <> '()'
then l_tags_include || ' & ' || l_tags_exclude
when l_tags_include <> '()'
then l_tags_include
when l_tags_exclude <> '()'
- then l_tags_exclude
+ then l_tags_exclude
end;
- else
+ else
l_return_tag := a_tags;
- end if;
+ end if;
return l_return_tag;
end;
-
+
/*
https://stackoverflow.com/questions/29634992/shunting-yard-validate-expression
*/
@@ -97,14 +96,14 @@ create or replace package body ut_suite_tag_filter is
l_expect_operand boolean := true;
l_expect_operator boolean := false;
l_idx pls_integer;
- begin
+ begin
l_idx := a_tags.first;
--Exuecute modified shunting algorithm
WHILE (l_idx is not null) loop
l_token := a_tags(l_idx);
if (l_token member of gc_operators and l_token member of gc_binary_operators) then
- if not(l_expect_operator) then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ if not(l_expect_operator) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
end if;
while l_operator_stack.top > 0 and (g_precedence(l_operator_stack.peek) > g_precedence(l_token)) loop
l_rnp_tokens.extend;
@@ -113,56 +112,56 @@ create or replace package body ut_suite_tag_filter is
l_operator_stack.push(a_tags(l_idx));
l_expect_operand := true;
l_expect_operator:= false;
- elsif (l_token member of gc_operators and l_token member of gc_unary_operators) then
- if not(l_expect_operand) then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
- end if;
+ elsif (l_token member of gc_operators and l_token member of gc_unary_operators) then
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
l_operator_stack.push(a_tags(l_idx));
l_expect_operand := true;
- l_expect_operator:= false;
+ l_expect_operator:= false;
elsif l_token = '(' then
- if not(l_expect_operand) then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
- end if;
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
l_operator_stack.push(a_tags(l_idx));
l_expect_operand := true;
- l_expect_operator:= false;
+ l_expect_operator:= false;
elsif l_token = ')' then
- if not(l_expect_operator) then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
- end if;
+ if not(l_expect_operator) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
while l_operator_stack.peek <> '(' loop
l_rnp_tokens.extend;
l_rnp_tokens(l_rnp_tokens.last) := l_operator_stack.pop;
end loop;
l_operator_stack.pop; --Pop the open bracket and discard it
l_expect_operand := false;
- l_expect_operator:= true;
+ l_expect_operator:= true;
else
- if not(l_expect_operand) then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ if not(l_expect_operand) then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
end if;
l_rnp_tokens.extend;
l_rnp_tokens(l_rnp_tokens.last) :=l_token;
l_expect_operator := true;
l_expect_operand := false;
end if;
-
+
l_idx := a_tags.next(l_idx);
end loop;
-
+
while l_operator_stack.peek is not null loop
- if l_operator_stack.peek in ('(',')') then
- raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
- end if;
+ if l_operator_stack.peek in ('(',')') then
+ raise_application_error(ut_utils.gc_invalid_tag_expression, gc_exception_msg);
+ end if;
l_rnp_tokens.extend;
- l_rnp_tokens(l_rnp_tokens.last):=l_operator_stack.pop;
+ l_rnp_tokens(l_rnp_tokens.last):=l_operator_stack.pop;
end loop;
-
+
return l_rnp_tokens;
end shunt_logical_expression;
-
- function conv_postfix_to_infix_sql(a_postfix_exp in ut_varchar2_list,a_tags_column_name in varchar2)
+
+ function conv_postfix_to_infix_sql(a_postfix_exp in ut_varchar2_list,a_tags_column_name in varchar2)
return varchar2 is
l_infix_stack ut_stack := ut_stack();
l_right_side varchar2(32767);
@@ -175,9 +174,9 @@ create or replace package body ut_suite_tag_filter is
while ( l_idx is not null) loop
--If the token we got is a none or any keyword
if a_postfix_exp(l_idx) member of gc_reserved_tag_words then
-
- l_infix_stack.push(
- case
+
+ l_infix_stack.push(
+ case
when a_postfix_exp(l_idx) = 'none' then '('||a_tags_column_name||' is empty or '||a_tags_column_name||' is null)'
else a_tags_column_name||' is not empty'
end
@@ -185,12 +184,12 @@ create or replace package body ut_suite_tag_filter is
--If token is operand but also single tag
elsif regexp_count(a_postfix_exp(l_idx),'[!()|&]') = 0 then
l_infix_stack.push(q'[']'||a_postfix_exp(l_idx)||q'[']'||l_member_token);
- --If token is unary operator not
+ --If token is unary operator not
elsif a_postfix_exp(l_idx) member of gc_unary_operators then
l_right_side := l_infix_stack.pop;
l_infix_exp := a_postfix_exp(l_idx)||'('||l_right_side||')';
l_infix_stack.push(l_infix_exp);
- --If token is binary operator
+ --If token is binary operator
elsif a_postfix_exp(l_idx) member of gc_binary_operators then
l_right_side := l_infix_stack.pop;
l_left_side := l_infix_stack.pop;
@@ -199,7 +198,7 @@ create or replace package body ut_suite_tag_filter is
end if;
l_idx := a_postfix_exp.next(l_idx);
end loop;
-
+
return l_infix_stack.pop;
end conv_postfix_to_infix_sql;
@@ -208,73 +207,69 @@ create or replace package body ut_suite_tag_filter is
l_tags varchar2(4000);
begin
l_tags := replace(replace_legacy_tag_notation(a_tags),' ');
- l_tags := conv_postfix_to_infix_sql(shunt_logical_expression(tokenize_tags_string(l_tags)),gc_tags_column_name);
+ l_tags := conv_postfix_to_infix_sql(shunt_logical_expression(tokenize_tags_string(l_tags)),'tags');
l_tags := replace(l_tags, '|',' or ');
l_tags := replace(l_tags ,'&',' and ');
l_tags := replace(l_tags ,'!','not');
- return l_tags;
- end;
+ return l_tags;
+ end;
/*
Having a base set of suites we will do a further filter down if there are
any tags defined.
- */
+ */
function get_tags_suites (
a_suite_items ut_suite_cache_rows,
a_tags varchar2
) return ut_suite_cache_rows is
- l_suite_tags ut_suite_cache_rows := ut_suite_cache_rows();
+ l_results ut_suite_cache_rows;
l_sql varchar2(32000);
- l_tags varchar2(4000):= create_where_filter(a_tags);
+ l_tags_filter_clause varchar2(4000):= create_where_filter(a_tags);
begin
l_sql :=
q'[
-with
- suites_mv as (
- select c.id,value(c) as obj,c.path as path,c.self_type,c.object_owner,c.tags as ]'||gc_tags_column_name||q'[
- from table(:suite_items) c
- ),
- suites_matching_expr as (
- select c.id,c.path as path,c.self_type,c.object_owner,c.tags
- from suites_mv c
- where c.self_type in ('UT_SUITE','UT_CONTEXT')
- and ]'||l_tags||q'[
- ),
- tests_matching_expr as (
- select c.id,c.path as path,c.self_type,c.object_owner,c.tags as ]'||gc_tags_column_name||q'[
- from suites_mv c where c.self_type in ('UT_TEST')
- and ]'||l_tags||q'[
- ),
- tests_with_tags_inh_from_suite as (
- select c.id,c.self_type,c.path,c.tags multiset union distinct t.tags as ]'||gc_tags_column_name||q'[ ,c.object_owner
- from suites_mv c join suites_matching_expr t
- on (c.path||'.' like t.path || '.%' /*all descendants and self*/ and c.object_owner = t.object_owner)
- ),
- tests_with_tags_prom_to_suite as (
- select c.id,c.self_type,c.path,c.tags multiset union distinct t.tags as ]'||gc_tags_column_name||q'[ ,c.object_owner
- from suites_mv c join tests_matching_expr t
- on (t.path||'.' like c.path || '.%' /*all ancestors and self*/ and c.object_owner = t.object_owner)
- )
- select obj from suites_mv c,
- (select id,row_number() over (partition by id order by id) r_num from
- (select id
- from tests_with_tags_prom_to_suite tst
- where ]'||l_tags||q'[
- union all
- select id from tests_with_tags_inh_from_suite tst
- where ]'||l_tags||q'[
- )
- ) t where c.id = t.id and r_num = 1 ]';
- execute immediate l_sql bulk collect into l_suite_tags using a_suite_items;
- return l_suite_tags;
+ with
+ suites_mv as (
+ select c.id,value(c) as obj,c.path as path,c.self_type,c.object_owner,c.tags as tags
+ from table(:suite_items) c
+ ),
+ propagate_tags_from_ancestors as (
+ select c.id, c.self_type, c.path, c.object_owner, cast(collect(c_tags.tag) as ut_varchar2_rows) as tags
+ from suites_mv c
+ left join suites_mv t
+ on t.self_type in ('UT_SUITE','UT_SUITE_CONTEXT')
+ and c.path like t.path||'.%' /* all descendants */
+ and c.object_owner = t.object_owner
+ outer apply (select column_value tag from table(c.tags) union select column_value tag from table(t.tags) ) c_tags
+ group by c.id, c.self_type, c.path, c.object_owner
+ ),
+ filter_by_tags as (
+ select *
+ from propagate_tags_from_ancestors x
+ where ( ]'||l_tags_filter_clause||q'[ )
+ ),
+ only_items_with_tests as (
+ select item.obj
+ from suites_mv item
+ where exists (
+ select 1
+ from filter_by_tags tst
+ where tst.self_type in ('UT_TEST')
+ and (tst.path||'.' like item.path || '.%' /*all descendants and self*/ and item.object_owner = tst.object_owner)
+ )
+ )
+ select obj from only_items_with_tests]';
+ execute immediate l_sql bulk collect into l_results using a_suite_items;
+
+ return l_results;
end;
function apply(
a_unfiltered_rows ut_suite_cache_rows,
a_tags varchar2 := null
) return ut_suite_cache_rows is
- l_suite_items ut_suite_cache_rows := a_unfiltered_rows;
+ l_suite_items ut_suite_cache_rows := a_unfiltered_rows;
begin
if length(a_tags) > 0 then
l_suite_items := get_tags_suites(l_suite_items,a_tags);
diff --git a/source/core/ut_suite_tag_filter.pks b/source/core/ut_suite_tag_filter.pks
index e824ae275..bb3d4ad73 100644
--- a/source/core/ut_suite_tag_filter.pks
+++ b/source/core/ut_suite_tag_filter.pks
@@ -1,7 +1,7 @@
-create or replace package ut_suite_tag_filter authid definer is
+create or replace noneditionable package ut_suite_tag_filter authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2023 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/core/ut_utils.pkb b/source/core/ut_utils.pkb
index 81d47221b..c8ced3bb9 100644
--- a/source/core/ut_utils.pkb
+++ b/source/core/ut_utils.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_utils is
+create or replace noneditionable package body ut_utils is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -23,8 +23,10 @@ create or replace package body ut_utils is
gc_invalid_xml_char constant varchar2(50) := '[^_[:alnum:]\.-]';
gc_full_valid_xml_name constant varchar2(50) := '^([[:alpha:]])([_[:alnum:]\.-])*$';
gc_owner_hash constant integer(11) := dbms_utility.get_hash_value( ut_owner(), 0, power(2,31)-1);
+ gc_open_chars constant varchar2(4):= '[{(<';
+ gc_close_chars constant varchar2(4):= ']})>';
+ gc_max_plsql_source_len constant integer := 32767;
-
function surround_with(a_value varchar2, a_quote_char varchar2) return varchar2 is
begin
return case when a_quote_char is not null then a_quote_char||a_value||a_quote_char else a_value end;
@@ -658,94 +660,234 @@ create or replace package body ut_utils is
return l_result;
end;
- function replace_multiline_comments(a_source clob) return clob is
- l_result clob;
- l_ml_comment_start binary_integer := 1;
- l_comment_start binary_integer := 1;
- l_text_start binary_integer := 1;
- l_escaped_text_start binary_integer := 1;
- l_escaped_text_end_char varchar2(1 char);
- l_end binary_integer := 1;
- l_ml_comment clob;
- l_newlines_count binary_integer;
- l_offset binary_integer := 1;
- l_length binary_integer := coalesce(dbms_lob.getlength(a_source), 0);
- begin
- l_ml_comment_start := instr(a_source,'/*');
- l_comment_start := instr(a_source,'--');
- l_text_start := instr(a_source,'''');
- l_escaped_text_start := instr(a_source,q'[q']');
- while l_offset > 0 and l_ml_comment_start > 0 loop
-
- if l_ml_comment_start > 0 and (l_ml_comment_start < l_comment_start or l_comment_start = 0)
- and (l_ml_comment_start < l_text_start or l_text_start = 0)and (l_ml_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,'*/',l_ml_comment_start+2);
- append_to_clob(l_result, dbms_lob.substr(a_source, l_ml_comment_start-l_offset, l_offset));
+ function scan_line(a_line in varchar2, a_in_ml_comment in out boolean) return varchar2 is
+ -- Normal scan
+ l_remaining varchar2(32767) := a_line;
+ l_line varchar2(32767);
+ l_ml_start binary_integer;
+ l_comment_start binary_integer;
+ l_text_start binary_integer;
+ l_eq_text_start binary_integer;
+ l_eq_end_char varchar2(1 char);
+ l_pos binary_integer;
+ l_end binary_integer;
+ l_ml_end binary_integer;
+ begin
+ if a_in_ml_comment then
+ l_ml_end := instr(l_remaining, '*/');
+ if l_ml_end > 0 then
+ a_in_ml_comment := false;
+ l_remaining := substr(l_remaining, l_ml_end + 2);
+ else
+ return null;
+ end if;
+ end if;
+
+ loop
+ exit when l_remaining is null;
+ l_ml_start := instr(l_remaining, '/*');
+ l_comment_start := instr(l_remaining, '--');
+ l_text_start := instr(l_remaining, '''');
+ -- q' always puts ' at l_text_start; just check the char immediately before it
+ l_eq_text_start := case
+ when l_text_start > 1 and substr(l_remaining, l_text_start - 1, 1) = 'q'
+ then l_text_start - 1
+ else 0
+ end;
+ -- Sentinel gc_max_plsql_source_len means "not present"; 32767 is beyond any VARCHAR2 position
+ l_pos := least(
+ case when l_ml_start > 0 then l_ml_start else gc_max_plsql_source_len end,
+ case when l_comment_start > 0 then l_comment_start else gc_max_plsql_source_len end,
+ case when l_text_start > 0 then l_text_start else gc_max_plsql_source_len end,
+ case when l_eq_text_start > 0 then l_eq_text_start else gc_max_plsql_source_len end
+ );
+
+ if l_pos = gc_max_plsql_source_len then
+ l_line := l_line || l_remaining;
+ exit;
+ end if;
+
+ l_line := l_line || substr(l_remaining, 1, l_pos - 1);
+ l_remaining := substr(l_remaining, l_pos);
+ -- l_remaining now starts exactly at the token; all branch offsets below are relative to 1
+ if l_pos = l_eq_text_start then
+ -- q-quoted string: l_remaining starts at 'q', delimiter is at position 3
+ l_eq_end_char := translate(substr(l_remaining, 3, 1), gc_open_chars, gc_close_chars);
+ l_end := instr(l_remaining, l_eq_end_char || '''', 4);
if l_end > 0 then
- l_ml_comment := substr(a_source, l_ml_comment_start, l_end-l_ml_comment_start);
- l_newlines_count := length( l_ml_comment ) - length( translate( l_ml_comment, 'a'||chr(10), 'a') );
- if l_newlines_count > 0 then
- append_to_clob(l_result, lpad( chr(10), l_newlines_count, chr(10) ) );
- end if;
- l_end := l_end + 2;
+ l_line := l_line || substr(l_remaining, 1, l_end + 1);
+ l_remaining := substr(l_remaining, l_end + 2);
+ else
+ l_line := l_line || l_remaining;
+ exit;
end if;
- else
- if l_comment_start > 0 and (l_comment_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_comment_start < l_text_start or l_text_start = 0) and (l_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,chr(10),l_comment_start+2);
- if l_end > 0 then
- l_end := l_end + 1;
- end if;
- elsif l_text_start > 0 and (l_text_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_text_start < l_comment_start or l_comment_start = 0) and (l_text_start < l_escaped_text_start or l_escaped_text_start = 0)
- then
- l_end := instr(a_source,q'[']',l_text_start+1);
-
- --skip double quotes while searching for end of quoted text
- while l_end > 0 and l_end = instr(a_source,q'['']',l_text_start+1) loop
- l_end := instr(a_source,q'[']',l_end+1);
- end loop;
- if l_end > 0 then
- l_end := l_end + 1;
+ elsif l_pos = l_ml_start then
+ -- Multi-line comment: l_remaining starts at '/*', so end search starts at 3
+ l_ml_end := instr(l_remaining, '*/', 3);
+ if l_ml_end > 0 then
+ l_remaining := substr(l_remaining, l_ml_end + 2);
+ else
+ a_in_ml_comment := true;
+ -- preserve trailing newline if present β it belongs to this line, not the comment
+ if substr(l_remaining, -1) = chr(10) then
+ l_line := l_line || chr(10);
end if;
+ return l_line;
+ end if;
+
+ elsif l_pos = l_comment_start then
+ -- Single-line comment: everything from here is comment, keep and stop
+ l_line := l_line || l_remaining;
+ return l_line;
- elsif l_escaped_text_start > 0 and (l_escaped_text_start < l_ml_comment_start or l_ml_comment_start = 0)
- and (l_escaped_text_start < l_comment_start or l_comment_start = 0) and (l_escaped_text_start < l_text_start or l_text_start = 0)
- then
- --translate char "[" from the start of quoted text "q'[someting]'" into "]"
- l_escaped_text_end_char := translate( substr(a_source, l_escaped_text_start + 2, 1), '[{(<', ']})>');
- l_end := instr(a_source,l_escaped_text_end_char||'''',l_escaped_text_start + 3 );
- if l_end > 0 then
- l_end := l_end + 2;
+ else
+ -- Regular string literal: l_remaining starts at the opening quote
+ -- scan from position 2 to skip the opening quote
+ l_end := 2;
+ loop
+ l_end := instr(l_remaining, '''', l_end);
+ exit when l_end = 0;
+ if substr(l_remaining, l_end, 2) = '''''' then
+ l_end := l_end + 2; -- skip escaped quote pair
+ else
+ exit; -- real closing quote
end if;
- end if;
+ end loop;
- if l_end = 0 then
- append_to_clob(l_result, substr(a_source, l_offset, l_length-l_offset));
+ if l_end > 0 then
+ l_line := l_line || substr(l_remaining, 1, l_end);
+ l_remaining := substr(l_remaining, l_end + 1);
else
- append_to_clob(l_result, substr(a_source, l_offset, l_end-l_offset));
+ l_line := l_line || l_remaining;
+ exit;
end if;
+
end if;
- l_offset := l_end;
- if l_offset >= l_ml_comment_start then
- l_ml_comment_start := instr(a_source,'/*',l_offset);
+ end loop;
+
+ return l_line;
+ end;
+
+ function replace_multiline_comments(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t
+ is
+ l_result dbms_preprocessor.source_lines_t;
+ l_line varchar2(32767);
+ l_remaining varchar2(32767);
+ l_in_ml_comment boolean := false;
+ l_ml_end binary_integer;
+ l_has_ml_comment boolean := false;
+ begin
+ if a_source.count = 0 then
+ return a_source;
+ end if;
+
+ -- Fast pre-scan to check for presence of multi-line comments; if none, return original source unmodified
+ for i in 1 .. a_source.count loop
+ if instr(a_source(i), '/*') > 0 then
+ l_has_ml_comment := true;
+ exit;
end if;
- if l_offset >= l_comment_start then
- l_comment_start := instr(a_source,'--',l_offset);
+ end loop;
+
+ if not l_has_ml_comment then
+ return a_source;
+ end if;
+
+ for i in 1 .. a_source.count loop
+ l_line := a_source(i);
+
+ -- Fast path: inside multi-line comment
+ if l_in_ml_comment then
+ l_ml_end := instr(l_line, '*/');
+ if l_ml_end > 0 then
+ l_in_ml_comment := false;
+ l_line := substr(l_line, l_ml_end + 2);
+ -- fall through to normal scan
+ else
+ l_result(i) := '';
+ continue;
+ end if;
end if;
- if l_offset >= l_text_start then
- l_text_start := instr(a_source,'''',l_offset);
+
+ -- Fast path: no special tokens on this line
+ if instr(l_line, '/') = 0
+ and instr(l_line, '-') = 0
+ and instr(l_line, '''') = 0
+ then
+ l_result(i) := l_line;
+ continue;
end if;
- if l_offset >= l_escaped_text_start then
- l_escaped_text_start := instr(a_source,q'[q']',l_offset);
+
+ -- Normal scan
+ l_remaining := l_line;
+ l_line := scan_line(l_remaining, l_in_ml_comment);
+ if l_line is null then
+ l_line := '';
end if;
+ l_result(i) := l_line;
end loop;
- append_to_clob(l_result, substr(a_source, l_end));
+
return l_result;
- end;
+ end replace_multiline_comments;
+
+ function strip_create_header_lines(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t
+ is
+ l_result dbms_preprocessor.source_lines_t := a_source;
+ l_rebased dbms_preprocessor.source_lines_t;
+ l_create_line pls_integer;
+ l_header_line pls_integer;
+ l_header_pos pls_integer := 0;
+ begin
+ if l_result.count = 0 then
+ return l_result;
+ end if;
+
+ -- remove comment lines that contain "-- create or replace" and find first CREATE
+ for i in 1..l_result.count loop
+ l_result(i) := regexp_replace(l_result(i), '^.*[-]{2,}\s*create(\s+or\s+replace).*$', null, 1, 1, 'i');
+ if l_create_line is null and regexp_like(l_result(i), '(^|[[:space:]])create([[:space:]]|$)', 'i') then
+ l_create_line := i;
+ end if;
+ end loop;
+
+ -- find first occurrence of object keyword after CREATE (may be on later line)
+ if l_create_line is not null then
+ for i in l_create_line..l_result.count loop
+ l_header_pos := regexp_instr(
+ l_result(i),
+ '(^|[[:space:]])(package|type|procedure|function)([[:space:]]|$)',
+ 1, 1, 0, 'i', 2
+ );
+ if l_header_pos > 0 then
+ l_header_line := i;
+ exit;
+ end if;
+ end loop;
+
+ if l_header_line is not null then
+ -- keep from keyword onward on the header line
+ l_result(l_header_line) := substr(l_result(l_header_line), l_header_pos);
+ -- remove "OWNER." from create or replace statement.
+ -- Owner is not supported along with AUTHID - see issue https://github.com/utPLSQL/utPLSQL/issues/1088
+ l_result(l_header_line) := regexp_replace(
+ l_result(l_header_line),
+ '^(package|type|procedure|function)\s+("?[[:alpha:]][[:alnum:]$#_]*"?\.)(.*)',
+ '\1 \3', 1, 1, 'ni'
+ );
+
+ -- rebase so header line becomes line 1 (matches preprocessor expectations)
+ for i in l_header_line .. l_result.count loop
+ l_rebased(i - l_header_line + 1) := l_result(i);
+ end loop;
+ return l_rebased;
+ end if;
+ end if;
+
+ return l_result;
+ end strip_create_header_lines;
function get_child_reporters(a_for_reporters ut_reporters_info := null) return ut_reporters_info is
l_for_reporters ut_reporters_info := a_for_reporters;
@@ -882,13 +1024,13 @@ create or replace package body ut_utils is
return regexp_replace(a_item,a_prefix||a_connector);
end;
- function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash is
+ function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash is
begin
--We cannot run hash on null
return case when a_data is null then null else dbms_crypto.hash(a_data, a_hash_type) end;
end;
- function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash is
+ function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash is
begin
--We cannot run hash on null
return case when a_data is null then null else dbms_crypto.hash(a_data, a_hash_type) end;
diff --git a/source/core/ut_utils.pks b/source/core/ut_utils.pks
index 9615c7b4d..559dde03d 100644
--- a/source/core/ut_utils.pks
+++ b/source/core/ut_utils.pks
@@ -1,7 +1,7 @@
-create or replace package ut_utils authid definer is
+create or replace noneditionable package ut_utils authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ create or replace package ut_utils authid definer is
*
*/
- gc_version constant varchar2(50) := 'v3.1.14.4342-develop';
+ gc_version constant varchar2(50) := 'v3.2.01.4488-develop';
subtype t_executable_type is varchar2(30);
gc_before_all constant t_executable_type := 'beforeall';
@@ -405,7 +405,15 @@ create or replace package ut_utils authid definer is
/**
* Replaces multi-line comments in given source-code with empty lines
*/
- function replace_multiline_comments(a_source clob) return clob;
+ function replace_multiline_comments(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t;
+
+ /**
+ * Strips the CREATE header (possibly split across lines) so source starts at
+ * package/type/procedure/function keyword, preserving line numbers.
+ */
+ function strip_create_header_lines(a_source dbms_preprocessor.source_lines_t)
+ return dbms_preprocessor.source_lines_t;
/**
* Returns list of sub-type reporters for given list of super-type reporters
@@ -449,12 +457,12 @@ create or replace package ut_utils authid definer is
/*
* Wrapper function for calling dbms_crypto.hash
*/
- function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash;
+ function get_hash(a_data raw, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash;
/*
* Wrapper function for calling dbms_crypto.hash
*/
- function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh1) return t_hash;
+ function get_hash(a_data clob, a_hash_type binary_integer := dbms_crypto.hash_sh256) return t_hash;
/*
* Returns a hash value of suitepath based on input path and random seed
diff --git a/source/create_grants.sql b/source/create_grants.sql
index 2cdea9970..9318a7220 100644
--- a/source/create_grants.sql
+++ b/source/create_grants.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -108,7 +108,6 @@ 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;
-grant execute on &&ut3_owner..ut_coveralls_reporter to &ut3_user;
grant execute on &&ut3_owner..ut_coverage_cobertura_reporter to &ut3_user;
--reporters - debug
grant execute on &&ut3_owner..ut_debug_reporter to &ut3_user;
diff --git a/source/create_synonyms.sql b/source/create_synonyms.sql
index d839e11b7..ab338f4f7 100644
--- a/source/create_synonyms.sql
+++ b/source/create_synonyms.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -36,10 +36,10 @@ set termout off
spool params.sql.tmp
select
case
- when upper('&&ut3_user') = 'PUBLIC' then q'[define action_type='or replace public'
+ when upper('&&ut3_user') = 'PUBLIC' then q'[define action_type='or replace noneditionable public'
]'||q'[define ut3_user=''
]'||q'[define grantee='PUBLIC']'
- else q'[define action_type='or replace'
+ else q'[define action_type='or replace noneditionable'
]'||q'[define grantee='&&ut3_user']
]'||q'[define ut3_user='&&ut3_user..']'
end
@@ -123,7 +123,6 @@ create &action_type. synonym &ut3_user.ut_tap_reporter for &&ut3_owner..ut_tap_r
--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;
-create &action_type. synonym &ut3_user.ut_coveralls_reporter for &&ut3_owner..ut_coveralls_reporter;
create &action_type. synonym &ut3_user.ut_coverage_cobertura_reporter for &&ut3_owner..ut_coverage_cobertura_reporter;
--reporters - debug
create &action_type. synonym &ut3_user.ut_debug_reporter for &&ut3_owner..ut_debug_reporter;
diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql
index 050162d72..25f14217e 100644
--- a/source/create_synonyms_and_grants_for_public.sql
+++ b/source/create_synonyms_and_grants_for_public.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql
index 83e594884..c1b81efa4 100644
--- a/source/create_user_grants.sql
+++ b/source/create_user_grants.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql
index a1e7a6acc..7b0e49553 100644
--- a/source/create_user_synonyms.sql
+++ b/source/create_user_synonyms.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/create_utplsql_owner.sql b/source/create_utplsql_owner.sql
index d7e4f3040..a5b70ffda 100644
--- a/source/create_utplsql_owner.sql
+++ b/source/create_utplsql_owner.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/define_ut3_owner_param.sql b/source/define_ut3_owner_param.sql
index 259b49712..192e810b7 100644
--- a/source/define_ut3_owner_param.sql
+++ b/source/define_ut3_owner_param.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_diff_tmp.sql b/source/expectations/data_values/ut_compound_data_diff_tmp.sql
index c10e8d2e8..edd27f766 100644
--- a/source/expectations/data_values/ut_compound_data_diff_tmp.sql
+++ b/source/expectations/data_values/ut_compound_data_diff_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_compound_data_diff_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_compound_data_helper.pkb b/source/expectations/data_values/ut_compound_data_helper.pkb
index 875ec760a..763c133d7 100644
--- a/source/expectations/data_values/ut_compound_data_helper.pkb
+++ b/source/expectations/data_values/ut_compound_data_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_compound_data_helper is
+create or replace noneditionable package body ut_compound_data_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_helper.pks b/source/expectations/data_values/ut_compound_data_helper.pks
index 451cd9bac..6069920c9 100644
--- a/source/expectations/data_values/ut_compound_data_helper.pks
+++ b/source/expectations/data_values/ut_compound_data_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_compound_data_helper authid definer is
+create or replace noneditionable package ut_compound_data_helper authid definer is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_tmp.sql b/source/expectations/data_values/ut_compound_data_tmp.sql
index 1bfa77fca..01cedd97b 100644
--- a/source/expectations/data_values/ut_compound_data_tmp.sql
+++ b/source/expectations/data_values/ut_compound_data_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_compound_data_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_compound_data_value.tpb b/source/expectations/data_values/ut_compound_data_value.tpb
index 2c52ff8fa..7db47827e 100644
--- a/source/expectations/data_values/ut_compound_data_value.tpb
+++ b/source/expectations/data_values/ut_compound_data_value.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_compound_data_value as
+create or replace noneditionable type body ut_compound_data_value as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_compound_data_value.tps b/source/expectations/data_values/ut_compound_data_value.tps
index c14dadceb..c84a59db6 100644
--- a/source/expectations/data_values/ut_compound_data_value.tps
+++ b/source/expectations/data_values/ut_compound_data_value.tps
@@ -1,7 +1,7 @@
-create or replace type ut_compound_data_value force under ut_data_value(
+create or replace noneditionable type ut_compound_data_value force under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_column.tpb b/source/expectations/data_values/ut_cursor_column.tpb
index a9fb6b0f4..3513de23e 100644
--- a/source/expectations/data_values/ut_cursor_column.tpb
+++ b/source/expectations/data_values/ut_cursor_column.tpb
@@ -1,5 +1,21 @@
-create or replace type body ut_cursor_column as
-
+create or replace noneditionable type body ut_cursor_column as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member procedure init(
self in out nocopy ut_cursor_column,
a_col_name varchar2, a_col_schema_name varchar2,
diff --git a/source/expectations/data_values/ut_cursor_column.tps b/source/expectations/data_values/ut_cursor_column.tps
index 77bf78f01..fcf3fe002 100644
--- a/source/expectations/data_values/ut_cursor_column.tps
+++ b/source/expectations/data_values/ut_cursor_column.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_column authid current_user as object (
+create or replace noneditionable type ut_cursor_column authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_column_tab.tps b/source/expectations/data_values/ut_cursor_column_tab.tps
index 106023d96..169ba3ce4 100644
--- a/source/expectations/data_values/ut_cursor_column_tab.tps
+++ b/source/expectations/data_values/ut_cursor_column_tab.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_column_tab as
+create or replace noneditionable type ut_cursor_column_tab as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_cursor_details.tpb b/source/expectations/data_values/ut_cursor_details.tpb
index b823ff944..ff204e3bd 100644
--- a/source/expectations/data_values/ut_cursor_details.tpb
+++ b/source/expectations/data_values/ut_cursor_details.tpb
@@ -1,4 +1,21 @@
-create or replace type body ut_cursor_details as
+create or replace noneditionable type body ut_cursor_details as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member function equals( a_other ut_cursor_details, a_match_options ut_matcher_options ) return boolean is
l_diffs integer;
diff --git a/source/expectations/data_values/ut_cursor_details.tps b/source/expectations/data_values/ut_cursor_details.tps
index e7f9405eb..c50ed16d3 100644
--- a/source/expectations/data_values/ut_cursor_details.tps
+++ b/source/expectations/data_values/ut_cursor_details.tps
@@ -1,7 +1,7 @@
-create or replace type ut_cursor_details authid current_user as object (
+create or replace noneditionable type ut_cursor_details authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value.tpb b/source/expectations/data_values/ut_data_value.tpb
index 6b1763dd0..05eb3022e 100644
--- a/source/expectations/data_values/ut_data_value.tpb
+++ b/source/expectations/data_values/ut_data_value.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value as
+create or replace noneditionable type body ut_data_value as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value.tps b/source/expectations/data_values/ut_data_value.tps
index beda3d911..6e362a56d 100644
--- a/source/expectations/data_values/ut_data_value.tps
+++ b/source/expectations/data_values/ut_data_value.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value force authid current_user as object (
+create or replace noneditionable type ut_data_value force authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_anydata.tpb b/source/expectations/data_values/ut_data_value_anydata.tpb
index f6fbdc840..9fccb7582 100644
--- a/source/expectations/data_values/ut_data_value_anydata.tpb
+++ b/source/expectations/data_values/ut_data_value_anydata.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_anydata as
+create or replace noneditionable type body ut_data_value_anydata as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_anydata.tps b/source/expectations/data_values/ut_data_value_anydata.tps
index 60dba5515..6ad692d31 100644
--- a/source/expectations/data_values/ut_data_value_anydata.tps
+++ b/source/expectations/data_values/ut_data_value_anydata.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_anydata under ut_data_value_refcursor(
+create or replace noneditionable type ut_data_value_anydata under ut_data_value_refcursor(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_blob.tpb b/source/expectations/data_values/ut_data_value_blob.tpb
index e145a8d4f..c961ebaab 100644
--- a/source/expectations/data_values/ut_data_value_blob.tpb
+++ b/source/expectations/data_values/ut_data_value_blob.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_blob as
+create or replace noneditionable type body ut_data_value_blob as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_blob.tps b/source/expectations/data_values/ut_data_value_blob.tps
index 6df3f3273..94124bfec 100644
--- a/source/expectations/data_values/ut_data_value_blob.tps
+++ b/source/expectations/data_values/ut_data_value_blob.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_blob under ut_data_value(
+create or replace noneditionable type ut_data_value_blob under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_boolean.tpb b/source/expectations/data_values/ut_data_value_boolean.tpb
index 867c3c19c..dd253442c 100644
--- a/source/expectations/data_values/ut_data_value_boolean.tpb
+++ b/source/expectations/data_values/ut_data_value_boolean.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_boolean as
+create or replace noneditionable type body ut_data_value_boolean as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_boolean.tps b/source/expectations/data_values/ut_data_value_boolean.tps
index e25b6e0fd..b6df4e0b4 100644
--- a/source/expectations/data_values/ut_data_value_boolean.tps
+++ b/source/expectations/data_values/ut_data_value_boolean.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_boolean under ut_data_value(
+create or replace noneditionable type ut_data_value_boolean under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_clob.tpb b/source/expectations/data_values/ut_data_value_clob.tpb
index f8a53a035..76a55545e 100644
--- a/source/expectations/data_values/ut_data_value_clob.tpb
+++ b/source/expectations/data_values/ut_data_value_clob.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_clob as
+create or replace noneditionable type body ut_data_value_clob as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_clob.tps b/source/expectations/data_values/ut_data_value_clob.tps
index 6869798d1..686757e85 100644
--- a/source/expectations/data_values/ut_data_value_clob.tps
+++ b/source/expectations/data_values/ut_data_value_clob.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_clob under ut_data_value(
+create or replace noneditionable type ut_data_value_clob under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_date.tpb b/source/expectations/data_values/ut_data_value_date.tpb
index 20424d193..2a1232a1c 100644
--- a/source/expectations/data_values/ut_data_value_date.tpb
+++ b/source/expectations/data_values/ut_data_value_date.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_date as
+create or replace noneditionable type body ut_data_value_date as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_date.tps b/source/expectations/data_values/ut_data_value_date.tps
index f64a577e0..0bb9a17cf 100644
--- a/source/expectations/data_values/ut_data_value_date.tps
+++ b/source/expectations/data_values/ut_data_value_date.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_date under ut_data_value(
+create or replace noneditionable type ut_data_value_date under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tpb b/source/expectations/data_values/ut_data_value_dsinterval.tpb
index 026d4970f..adad0ef6d 100644
--- a/source/expectations/data_values/ut_data_value_dsinterval.tpb
+++ b/source/expectations/data_values/ut_data_value_dsinterval.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_dsinterval as
+create or replace noneditionable type body ut_data_value_dsinterval as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_dsinterval.tps b/source/expectations/data_values/ut_data_value_dsinterval.tps
index 6f5cb708c..3d15e2e09 100644
--- a/source/expectations/data_values/ut_data_value_dsinterval.tps
+++ b/source/expectations/data_values/ut_data_value_dsinterval.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_dsinterval under ut_data_value(
+create or replace noneditionable type ut_data_value_dsinterval under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_json.tpb b/source/expectations/data_values/ut_data_value_json.tpb
index b703af181..e1b5aa995 100644
--- a/source/expectations/data_values/ut_data_value_json.tpb
+++ b/source/expectations/data_values/ut_data_value_json.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_json as
+create or replace noneditionable type body ut_data_value_json as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_json.tps b/source/expectations/data_values/ut_data_value_json.tps
index 3b77e54eb..c89088564 100644
--- a/source/expectations/data_values/ut_data_value_json.tps
+++ b/source/expectations/data_values/ut_data_value_json.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_json under ut_compound_data_value(
+create or replace noneditionable type ut_data_value_json under ut_compound_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_number.tpb b/source/expectations/data_values/ut_data_value_number.tpb
index 382e6e9aa..3ea08bbd4 100644
--- a/source/expectations/data_values/ut_data_value_number.tpb
+++ b/source/expectations/data_values/ut_data_value_number.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_number as
+create or replace noneditionable type body ut_data_value_number as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_number.tps b/source/expectations/data_values/ut_data_value_number.tps
index 86d68f356..e7031de72 100644
--- a/source/expectations/data_values/ut_data_value_number.tps
+++ b/source/expectations/data_values/ut_data_value_number.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_number under ut_data_value(
+create or replace noneditionable type ut_data_value_number under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_refcursor.tpb b/source/expectations/data_values/ut_data_value_refcursor.tpb
index a4f0cf7a0..b7f79ac52 100644
--- a/source/expectations/data_values/ut_data_value_refcursor.tpb
+++ b/source/expectations/data_values/ut_data_value_refcursor.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_refcursor as
+create or replace noneditionable type body ut_data_value_refcursor as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_refcursor.tps b/source/expectations/data_values/ut_data_value_refcursor.tps
index 594695e32..90a305d32 100644
--- a/source/expectations/data_values/ut_data_value_refcursor.tps
+++ b/source/expectations/data_values/ut_data_value_refcursor.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_refcursor under ut_compound_data_value(
+create or replace noneditionable type ut_data_value_refcursor under ut_compound_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp.tpb b/source/expectations/data_values/ut_data_value_timestamp.tpb
index 318f799a3..c6aabf7a3 100644
--- a/source/expectations/data_values/ut_data_value_timestamp.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp as
+create or replace noneditionable type body ut_data_value_timestamp as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp.tps b/source/expectations/data_values/ut_data_value_timestamp.tps
index c047e3c79..938b0d63c 100644
--- a/source/expectations/data_values/ut_data_value_timestamp.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
index 6127de5f1..025314f4b 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp_ltz as
+create or replace noneditionable type body ut_data_value_timestamp_ltz as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
index 7bb296bc9..e7c61a878 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp_ltz.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp_ltz under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp_ltz under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
index d5d5cdd13..6af5fea4d 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
+++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_timestamp_tz as
+create or replace noneditionable type body ut_data_value_timestamp_tz as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_timestamp_tz.tps b/source/expectations/data_values/ut_data_value_timestamp_tz.tps
index 01cf11124..ad190d197 100644
--- a/source/expectations/data_values/ut_data_value_timestamp_tz.tps
+++ b/source/expectations/data_values/ut_data_value_timestamp_tz.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_timestamp_tz under ut_data_value(
+create or replace noneditionable type ut_data_value_timestamp_tz under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_varchar2.tpb b/source/expectations/data_values/ut_data_value_varchar2.tpb
index d04398697..7a26d7571 100644
--- a/source/expectations/data_values/ut_data_value_varchar2.tpb
+++ b/source/expectations/data_values/ut_data_value_varchar2.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_varchar2 as
+create or replace noneditionable type body ut_data_value_varchar2 as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_varchar2.tps b/source/expectations/data_values/ut_data_value_varchar2.tps
index 3fbeb378b..56effd460 100644
--- a/source/expectations/data_values/ut_data_value_varchar2.tps
+++ b/source/expectations/data_values/ut_data_value_varchar2.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_varchar2 under ut_data_value(
+create or replace noneditionable type ut_data_value_varchar2 under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_xmltype.tpb b/source/expectations/data_values/ut_data_value_xmltype.tpb
index 4b21a8937..f5ffcbc9a 100644
--- a/source/expectations/data_values/ut_data_value_xmltype.tpb
+++ b/source/expectations/data_values/ut_data_value_xmltype.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_xmltype as
+create or replace noneditionable type body ut_data_value_xmltype as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_xmltype.tps b/source/expectations/data_values/ut_data_value_xmltype.tps
index 9ba738b88..2d0257918 100644
--- a/source/expectations/data_values/ut_data_value_xmltype.tps
+++ b/source/expectations/data_values/ut_data_value_xmltype.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_xmltype under ut_data_value(
+create or replace noneditionable type ut_data_value_xmltype under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_yminterval.tpb b/source/expectations/data_values/ut_data_value_yminterval.tpb
index a3a1e7a2f..8d12d3544 100644
--- a/source/expectations/data_values/ut_data_value_yminterval.tpb
+++ b/source/expectations/data_values/ut_data_value_yminterval.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_data_value_yminterval as
+create or replace noneditionable type body ut_data_value_yminterval as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_data_value_yminterval.tps b/source/expectations/data_values/ut_data_value_yminterval.tps
index c9ad2e776..8c3ad8079 100644
--- a/source/expectations/data_values/ut_data_value_yminterval.tps
+++ b/source/expectations/data_values/ut_data_value_yminterval.tps
@@ -1,7 +1,7 @@
-create or replace type ut_data_value_yminterval under ut_data_value(
+create or replace noneditionable type ut_data_value_yminterval under ut_data_value(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_data_diff_tmp.sql b/source/expectations/data_values/ut_json_data_diff_tmp.sql
index 5ff3440d8..4eda07d7c 100644
--- a/source/expectations/data_values/ut_json_data_diff_tmp.sql
+++ b/source/expectations/data_values/ut_json_data_diff_tmp.sql
@@ -1,7 +1,7 @@
create global temporary table ut_json_data_diff_tmp(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/source/expectations/data_values/ut_json_leaf.tpb b/source/expectations/data_values/ut_json_leaf.tpb
index 83f1009ef..d6c862286 100644
--- a/source/expectations/data_values/ut_json_leaf.tpb
+++ b/source/expectations/data_values/ut_json_leaf.tpb
@@ -1,5 +1,21 @@
-create or replace type body ut_json_leaf as
-
+create or replace noneditionable type body ut_json_leaf as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
member procedure init( self in out nocopy ut_json_leaf,
a_element_name varchar2, a_element_value varchar2,a_parent_name varchar2,
a_access_path varchar2, a_hierarchy_level integer, a_index_position integer, a_json_type in varchar2,
diff --git a/source/expectations/data_values/ut_json_leaf.tps b/source/expectations/data_values/ut_json_leaf.tps
index 8aa8afd6a..ac478e34e 100644
--- a/source/expectations/data_values/ut_json_leaf.tps
+++ b/source/expectations/data_values/ut_json_leaf.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_leaf authid current_user as object (
+create or replace noneditionable type ut_json_leaf authid current_user as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_leaf_tab.tps b/source/expectations/data_values/ut_json_leaf_tab.tps
index 395ab5d9e..c00f2a3a1 100644
--- a/source/expectations/data_values/ut_json_leaf_tab.tps
+++ b/source/expectations/data_values/ut_json_leaf_tab.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_leaf_tab as
+create or replace noneditionable type ut_json_leaf_tab as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_json_tree_details.tpb b/source/expectations/data_values/ut_json_tree_details.tpb
index a333ea71c..0d457b2c5 100644
--- a/source/expectations/data_values/ut_json_tree_details.tpb
+++ b/source/expectations/data_values/ut_json_tree_details.tpb
@@ -1,4 +1,20 @@
-create or replace type body ut_json_tree_details as
+create or replace noneditionable type body ut_json_tree_details as
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
member function get_json_type(a_json_piece json_element_t) return varchar2 is
begin
diff --git a/source/expectations/data_values/ut_json_tree_details.tps b/source/expectations/data_values/ut_json_tree_details.tps
index 20ac2fdcc..4f7e891be 100644
--- a/source/expectations/data_values/ut_json_tree_details.tps
+++ b/source/expectations/data_values/ut_json_tree_details.tps
@@ -1,7 +1,7 @@
-create or replace type ut_json_tree_details force as object (
+create or replace noneditionable type ut_json_tree_details force as object (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyval_pair.tps b/source/expectations/data_values/ut_key_anyval_pair.tps
index d1068f109..6ed63ae7e 100644
--- a/source/expectations/data_values/ut_key_anyval_pair.tps
+++ b/source/expectations/data_values/ut_key_anyval_pair.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyval_pair force as object(
+create or replace noneditionable type ut_key_anyval_pair force as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyval_pairs.tps b/source/expectations/data_values/ut_key_anyval_pairs.tps
index 7e10bf50f..a75305f79 100644
--- a/source/expectations/data_values/ut_key_anyval_pairs.tps
+++ b/source/expectations/data_values/ut_key_anyval_pairs.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyval_pairs as
+create or replace noneditionable type ut_key_anyval_pairs as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyvalues.tpb b/source/expectations/data_values/ut_key_anyvalues.tpb
index d30d8a841..4e6dd2c0f 100644
--- a/source/expectations/data_values/ut_key_anyvalues.tpb
+++ b/source/expectations/data_values/ut_key_anyvalues.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_key_anyvalues as
+create or replace noneditionable type body ut_key_anyvalues as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/data_values/ut_key_anyvalues.tps b/source/expectations/data_values/ut_key_anyvalues.tps
index 8c672bd00..21a9a5c72 100644
--- a/source/expectations/data_values/ut_key_anyvalues.tps
+++ b/source/expectations/data_values/ut_key_anyvalues.tps
@@ -1,7 +1,7 @@
-create or replace type ut_key_anyvalues under ut_event_item (
+create or replace noneditionable type ut_key_anyvalues under ut_event_item (
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/json_objects_specs.sql b/source/expectations/json_objects_specs.sql
index a5d936afb..c0fc15ed6 100644
--- a/source/expectations/json_objects_specs.sql
+++ b/source/expectations/json_objects_specs.sql
@@ -2,13 +2,13 @@ BEGIN
null;
$if dbms_db_version.version < 21 $then
dbms_output.put_line('Installing json structures specs for native json.');
- execute immediate q'[create or replace TYPE JSON FORCE AUTHID CURRENT_USER AS OBJECT(
+ execute immediate q'[create or replace noneditionable TYPE JSON FORCE AUTHID CURRENT_USER AS OBJECT(
dummyobjt NUMBER
) NOT FINAL NOT INSTANTIABLE;]';
$end
$if dbms_db_version.version = 12 and dbms_db_version.release = 1 or dbms_db_version.version < 12 $then
dbms_output.put_line('Installing json structures specs.');
- execute immediate q'[create or replace TYPE JSON_Element_T FORCE AUTHID CURRENT_USER AS OBJECT(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Element_T FORCE AUTHID CURRENT_USER AS OBJECT(
dummyobjt NUMBER,
STATIC FUNCTION parse(jsn VARCHAR2) RETURN JSON_Element_T,
STATIC FUNCTION parse(jsn CLOB) RETURN JSON_Element_T,
@@ -34,9 +34,9 @@ BEGIN
MEMBER FUNCTION get_Size(self IN JSON_ELEMENT_T) RETURN NUMBER
) NOT FINAL NOT INSTANTIABLE;]';
- execute immediate q'[create or replace TYPE JSON_KEY_LIST FORCE AS VARRAY(32767) OF VARCHAR2(4000);]';
+ execute immediate q'[create or replace noneditionable TYPE JSON_KEY_LIST FORCE AS VARRAY(32767) OF VARCHAR2(4000);]';
- execute immediate q'[create or replace TYPE JSON_Array_T FORCE AUTHID CURRENT_USER UNDER JSON_Element_T(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Array_T FORCE AUTHID CURRENT_USER UNDER JSON_Element_T(
CONSTRUCTOR FUNCTION JSON_Array_T RETURN SELF AS RESULT,
MEMBER FUNCTION get(pos NUMBER) RETURN JSON_Element_T,
MEMBER FUNCTION get_String(pos NUMBER) RETURN VARCHAR2,
@@ -51,7 +51,7 @@ BEGIN
MEMBER FUNCTION get_Type(pos NUMBER) RETURN VARCHAR2
) FINAL;]';
- execute immediate q'[create or replace TYPE JSON_Object_T AUTHID CURRENT_USER UNDER JSON_Element_T(
+ execute immediate q'[create or replace noneditionable TYPE JSON_Object_T AUTHID CURRENT_USER UNDER JSON_Element_T(
CONSTRUCTOR FUNCTION JSON_Object_T RETURN SELF AS RESULT,
MEMBER FUNCTION get(key VARCHAR2) RETURN JSON_Element_T,
MEMBER FUNCTION get_Object(key VARCHAR2) RETURN JSON_OBJECT_T,
diff --git a/source/expectations/matchers/ut_be_between.tpb b/source/expectations/matchers/ut_be_between.tpb
index 6aea96f55..83dfc4c25 100644
--- a/source/expectations/matchers/ut_be_between.tpb
+++ b/source/expectations/matchers/ut_be_between.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_between is
+create or replace noneditionable type body ut_be_between is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_between.tps b/source/expectations/matchers/ut_be_between.tps
index 9e984085b..7f1403847 100644
--- a/source/expectations/matchers/ut_be_between.tps
+++ b/source/expectations/matchers/ut_be_between.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_between under ut_matcher(
+create or replace noneditionable type ut_be_between under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_empty.tpb b/source/expectations/matchers/ut_be_empty.tpb
index e5e02f6b2..af233aa8f 100644
--- a/source/expectations/matchers/ut_be_empty.tpb
+++ b/source/expectations/matchers/ut_be_empty.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_empty as
+create or replace noneditionable type body ut_be_empty as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_empty.tps b/source/expectations/matchers/ut_be_empty.tps
index 9e9f899d0..a5672ba78 100644
--- a/source/expectations/matchers/ut_be_empty.tps
+++ b/source/expectations/matchers/ut_be_empty.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_empty under ut_matcher(
+create or replace noneditionable type ut_be_empty under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_false.tpb b/source/expectations/matchers/ut_be_false.tpb
index 4cc88600a..a02ac58cb 100644
--- a/source/expectations/matchers/ut_be_false.tpb
+++ b/source/expectations/matchers/ut_be_false.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_false as
+create or replace noneditionable type body ut_be_false as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_false.tps b/source/expectations/matchers/ut_be_false.tps
index ede510719..d793844c1 100644
--- a/source/expectations/matchers/ut_be_false.tps
+++ b/source/expectations/matchers/ut_be_false.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_false under ut_matcher(
+create or replace noneditionable type ut_be_false under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tpb b/source/expectations/matchers/ut_be_greater_or_equal.tpb
index 1c2a19c09..6e564a90c 100644
--- a/source/expectations/matchers/ut_be_greater_or_equal.tpb
+++ b/source/expectations/matchers/ut_be_greater_or_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_greater_or_equal AS
+create or replace noneditionable type body ut_be_greater_or_equal AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_or_equal.tps b/source/expectations/matchers/ut_be_greater_or_equal.tps
index b3ab54ff1..d3e651958 100644
--- a/source/expectations/matchers/ut_be_greater_or_equal.tps
+++ b/source/expectations/matchers/ut_be_greater_or_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_greater_or_equal under ut_comparison_matcher(
+create or replace noneditionable type ut_be_greater_or_equal under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_than.tpb b/source/expectations/matchers/ut_be_greater_than.tpb
index 9cce79119..08628ae3a 100644
--- a/source/expectations/matchers/ut_be_greater_than.tpb
+++ b/source/expectations/matchers/ut_be_greater_than.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_greater_than AS
+create or replace noneditionable type body ut_be_greater_than AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_greater_than.tps b/source/expectations/matchers/ut_be_greater_than.tps
index a5a44692d..745b19f08 100644
--- a/source/expectations/matchers/ut_be_greater_than.tps
+++ b/source/expectations/matchers/ut_be_greater_than.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_greater_than under ut_comparison_matcher(
+create or replace noneditionable type ut_be_greater_than under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_or_equal.tpb b/source/expectations/matchers/ut_be_less_or_equal.tpb
index 6acec1dda..2df06a078 100644
--- a/source/expectations/matchers/ut_be_less_or_equal.tpb
+++ b/source/expectations/matchers/ut_be_less_or_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_less_or_equal AS
+create or replace noneditionable type body ut_be_less_or_equal AS
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_or_equal.tps b/source/expectations/matchers/ut_be_less_or_equal.tps
index 118611a41..f0e297ad1 100644
--- a/source/expectations/matchers/ut_be_less_or_equal.tps
+++ b/source/expectations/matchers/ut_be_less_or_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_less_or_equal under ut_comparison_matcher(
+create or replace noneditionable type ut_be_less_or_equal under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_than.tpb b/source/expectations/matchers/ut_be_less_than.tpb
index 7608e4917..c0b059231 100644
--- a/source/expectations/matchers/ut_be_less_than.tpb
+++ b/source/expectations/matchers/ut_be_less_than.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_less_than as
+create or replace noneditionable type body ut_be_less_than as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_less_than.tps b/source/expectations/matchers/ut_be_less_than.tps
index b652de789..594df9b71 100644
--- a/source/expectations/matchers/ut_be_less_than.tps
+++ b/source/expectations/matchers/ut_be_less_than.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_less_than under ut_comparison_matcher(
+create or replace noneditionable type ut_be_less_than under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_like.tpb b/source/expectations/matchers/ut_be_like.tpb
index 6865c2942..b94c3fa91 100644
--- a/source/expectations/matchers/ut_be_like.tpb
+++ b/source/expectations/matchers/ut_be_like.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_like as
+create or replace noneditionable type body ut_be_like as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_like.tps b/source/expectations/matchers/ut_be_like.tps
index dae93a1d9..ca9ad45de 100644
--- a/source/expectations/matchers/ut_be_like.tps
+++ b/source/expectations/matchers/ut_be_like.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_like under ut_matcher(
+create or replace noneditionable type ut_be_like under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_not_null.tpb b/source/expectations/matchers/ut_be_not_null.tpb
index 194e2ea32..d291d2e35 100644
--- a/source/expectations/matchers/ut_be_not_null.tpb
+++ b/source/expectations/matchers/ut_be_not_null.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_not_null as
+create or replace noneditionable type body ut_be_not_null as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_not_null.tps b/source/expectations/matchers/ut_be_not_null.tps
index 196aac9fb..61f6c871d 100644
--- a/source/expectations/matchers/ut_be_not_null.tps
+++ b/source/expectations/matchers/ut_be_not_null.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_not_null under ut_matcher(
+create or replace noneditionable type ut_be_not_null under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_null.tpb b/source/expectations/matchers/ut_be_null.tpb
index 8c672791b..89fbaf563 100644
--- a/source/expectations/matchers/ut_be_null.tpb
+++ b/source/expectations/matchers/ut_be_null.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_null as
+create or replace noneditionable type body ut_be_null as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_null.tps b/source/expectations/matchers/ut_be_null.tps
index 3b2d6ac84..063c7db29 100644
--- a/source/expectations/matchers/ut_be_null.tps
+++ b/source/expectations/matchers/ut_be_null.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_null under ut_matcher(
+create or replace noneditionable type ut_be_null under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_true.tpb b/source/expectations/matchers/ut_be_true.tpb
index fe78b4e22..59368f342 100644
--- a/source/expectations/matchers/ut_be_true.tpb
+++ b/source/expectations/matchers/ut_be_true.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_true as
+create or replace noneditionable type body ut_be_true as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_true.tps b/source/expectations/matchers/ut_be_true.tps
index 8b5491e39..19d397371 100644
--- a/source/expectations/matchers/ut_be_true.tps
+++ b/source/expectations/matchers/ut_be_true.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_true under ut_matcher(
+create or replace noneditionable type ut_be_true under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within.tpb b/source/expectations/matchers/ut_be_within.tpb
index e2aa792d0..f8f880ace 100644
--- a/source/expectations/matchers/ut_be_within.tpb
+++ b/source/expectations/matchers/ut_be_within.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_within as
+create or replace noneditionable type body ut_be_within as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within.tps b/source/expectations/matchers/ut_be_within.tps
index 576f9ff37..276c529df 100644
--- a/source/expectations/matchers/ut_be_within.tps
+++ b/source/expectations/matchers/ut_be_within.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_within force under ut_be_within_pct(
+create or replace noneditionable type ut_be_within force under ut_be_within_pct(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_helper.pkb b/source/expectations/matchers/ut_be_within_helper.pkb
index 5dd82baa2..635c1b111 100644
--- a/source/expectations/matchers/ut_be_within_helper.pkb
+++ b/source/expectations/matchers/ut_be_within_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_be_within_helper as
+create or replace noneditionable package body ut_be_within_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_helper.pks b/source/expectations/matchers/ut_be_within_helper.pks
index 41737cc8f..5a59eea9e 100644
--- a/source/expectations/matchers/ut_be_within_helper.pks
+++ b/source/expectations/matchers/ut_be_within_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_be_within_helper authid definer as
+create or replace noneditionable package ut_be_within_helper authid definer as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_pct.tpb b/source/expectations/matchers/ut_be_within_pct.tpb
index 8b280ffff..82ce8e84e 100644
--- a/source/expectations/matchers/ut_be_within_pct.tpb
+++ b/source/expectations/matchers/ut_be_within_pct.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_be_within_pct as
+create or replace noneditionable type body ut_be_within_pct as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_be_within_pct.tps b/source/expectations/matchers/ut_be_within_pct.tps
index 499e9a2d8..810eaa5b3 100644
--- a/source/expectations/matchers/ut_be_within_pct.tps
+++ b/source/expectations/matchers/ut_be_within_pct.tps
@@ -1,7 +1,7 @@
-create or replace type ut_be_within_pct force under ut_comparison_matcher(
+create or replace noneditionable type ut_be_within_pct force under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@ create or replace type ut_be_within_pct force under ut_comparison_matcher(
limitations under the License.
*/
-
/**
* Holds information about mather options
*/
diff --git a/source/expectations/matchers/ut_comparison_matcher.tpb b/source/expectations/matchers/ut_comparison_matcher.tpb
index 20ed35927..d6c47855d 100644
--- a/source/expectations/matchers/ut_comparison_matcher.tpb
+++ b/source/expectations/matchers/ut_comparison_matcher.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_comparison_matcher as
+create or replace noneditionable type body ut_comparison_matcher as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_comparison_matcher.tps b/source/expectations/matchers/ut_comparison_matcher.tps
index 68ecb4462..b1ed08a84 100644
--- a/source/expectations/matchers/ut_comparison_matcher.tps
+++ b/source/expectations/matchers/ut_comparison_matcher.tps
@@ -1,7 +1,7 @@
-create or replace type ut_comparison_matcher under ut_matcher(
+create or replace noneditionable type ut_comparison_matcher under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_contain.tpb b/source/expectations/matchers/ut_contain.tpb
index c9691f731..bcc3806b7 100644
--- a/source/expectations/matchers/ut_contain.tpb
+++ b/source/expectations/matchers/ut_contain.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_contain as
+create or replace noneditionable type body ut_contain as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_contain.tps b/source/expectations/matchers/ut_contain.tps
index e572edf62..bd67113c9 100644
--- a/source/expectations/matchers/ut_contain.tps
+++ b/source/expectations/matchers/ut_contain.tps
@@ -1,7 +1,7 @@
-create or replace type ut_contain under ut_equal(
+create or replace noneditionable type ut_contain under ut_equal(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_equal.tpb b/source/expectations/matchers/ut_equal.tpb
index d514e34d0..f999995d1 100644
--- a/source/expectations/matchers/ut_equal.tpb
+++ b/source/expectations/matchers/ut_equal.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_equal as
+create or replace noneditionable type body ut_equal as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_equal.tps b/source/expectations/matchers/ut_equal.tps
index e48b797ed..eeb715a58 100644
--- a/source/expectations/matchers/ut_equal.tps
+++ b/source/expectations/matchers/ut_equal.tps
@@ -1,7 +1,7 @@
-create or replace type ut_equal force under ut_comparison_matcher(
+create or replace noneditionable type ut_equal force under ut_comparison_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_have_count.tpb b/source/expectations/matchers/ut_have_count.tpb
index 457cd6272..f6d3d2682 100644
--- a/source/expectations/matchers/ut_have_count.tpb
+++ b/source/expectations/matchers/ut_have_count.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_have_count as
+create or replace noneditionable type body ut_have_count as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_have_count.tps b/source/expectations/matchers/ut_have_count.tps
index d48dc44c8..85cdf4393 100644
--- a/source/expectations/matchers/ut_have_count.tps
+++ b/source/expectations/matchers/ut_have_count.tps
@@ -1,7 +1,7 @@
-create or replace type ut_have_count under ut_matcher(
+create or replace noneditionable type ut_have_count under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_match.tpb b/source/expectations/matchers/ut_match.tpb
index 3c7a71402..1836298e7 100644
--- a/source/expectations/matchers/ut_match.tpb
+++ b/source/expectations/matchers/ut_match.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_match as
+create or replace noneditionable type body ut_match as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_match.tps b/source/expectations/matchers/ut_match.tps
index ee51a4c28..3f840545f 100644
--- a/source/expectations/matchers/ut_match.tps
+++ b/source/expectations/matchers/ut_match.tps
@@ -1,7 +1,7 @@
-create or replace type ut_match under ut_matcher(
+create or replace noneditionable type ut_match under ut_matcher(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher.tpb b/source/expectations/matchers/ut_matcher.tpb
index 6b5b98465..828e1ac51 100644
--- a/source/expectations/matchers/ut_matcher.tpb
+++ b/source/expectations/matchers/ut_matcher.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher as
+create or replace noneditionable type body ut_matcher as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher.tps b/source/expectations/matchers/ut_matcher.tps
index a034e4ed2..ee7f1b5dd 100644
--- a/source/expectations/matchers/ut_matcher.tps
+++ b/source/expectations/matchers/ut_matcher.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher under ut_matcher_base(
+create or replace noneditionable type ut_matcher under ut_matcher_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_base.tps b/source/expectations/matchers/ut_matcher_base.tps
index ef7fd98a2..ba79a6aed 100644
--- a/source/expectations/matchers/ut_matcher_base.tps
+++ b/source/expectations/matchers/ut_matcher_base.tps
@@ -1,4 +1,21 @@
-create or replace type ut_matcher_base force authid current_user as object(
+create or replace noneditionable type ut_matcher_base force authid current_user as object(
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
self_type varchar2(250)
)
not final not instantiable
diff --git a/source/expectations/matchers/ut_matcher_options.tpb b/source/expectations/matchers/ut_matcher_options.tpb
index 8730c204b..57aca2617 100644
--- a/source/expectations/matchers/ut_matcher_options.tpb
+++ b/source/expectations/matchers/ut_matcher_options.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher_options as
+create or replace noneditionable type body ut_matcher_options as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options.tps b/source/expectations/matchers/ut_matcher_options.tps
index 276cad2ec..db076fd99 100644
--- a/source/expectations/matchers/ut_matcher_options.tps
+++ b/source/expectations/matchers/ut_matcher_options.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher_options authid current_user as object(
+create or replace noneditionable type ut_matcher_options authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options_items.tpb b/source/expectations/matchers/ut_matcher_options_items.tpb
index 92da588ce..6e4841870 100644
--- a/source/expectations/matchers/ut_matcher_options_items.tpb
+++ b/source/expectations/matchers/ut_matcher_options_items.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_matcher_options_items is
+create or replace noneditionable type body ut_matcher_options_items is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/matchers/ut_matcher_options_items.tps b/source/expectations/matchers/ut_matcher_options_items.tps
index 53787070d..045a7ece7 100644
--- a/source/expectations/matchers/ut_matcher_options_items.tps
+++ b/source/expectations/matchers/ut_matcher_options_items.tps
@@ -1,7 +1,7 @@
-create or replace type ut_matcher_options_items authid current_user as object(
+create or replace noneditionable type ut_matcher_options_items authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation.tpb b/source/expectations/ut_expectation.tpb
index 309759d48..5f7c9cce0 100644
--- a/source/expectations/ut_expectation.tpb
+++ b/source/expectations/ut_expectation.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation as
+create or replace noneditionable type body ut_expectation as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation.tps b/source/expectations/ut_expectation.tps
index 30fe985d3..a423c39a4 100644
--- a/source/expectations/ut_expectation.tps
+++ b/source/expectations/ut_expectation.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation force under ut_expectation_base(
+create or replace noneditionable type ut_expectation force under ut_expectation_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_base.tpb b/source/expectations/ut_expectation_base.tpb
index 20b3e7a95..5ed630c63 100644
--- a/source/expectations/ut_expectation_base.tpb
+++ b/source/expectations/ut_expectation_base.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_base as
+create or replace noneditionable type body ut_expectation_base as
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@ create or replace type body ut_expectation_base as
See the License for the specific language governing permissions and
limitations under the License.
*/
+
member procedure to_(self in ut_expectation_base, a_matcher ut_matcher_base) is
l_expectation_result boolean;
l_matcher ut_matcher := treat(a_matcher as ut_matcher);
diff --git a/source/expectations/ut_expectation_base.tps b/source/expectations/ut_expectation_base.tps
index a542d26ea..86f274495 100644
--- a/source/expectations/ut_expectation_base.tps
+++ b/source/expectations/ut_expectation_base.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_base authid current_user as object(
+create or replace noneditionable type ut_expectation_base authid current_user as object(
/*
utPLSQL - Version 3
- Copyright 2016 - 2019 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@ create or replace type ut_expectation_base authid current_user as object(
See the License for the specific language governing permissions and
limitations under the License.
*/
+
actual_data ut_data_value,
description varchar2(4000 char),
diff --git a/source/expectations/ut_expectation_compound.tpb b/source/expectations/ut_expectation_compound.tpb
index 6fc2e2647..d76010f80 100644
--- a/source/expectations/ut_expectation_compound.tpb
+++ b/source/expectations/ut_expectation_compound.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_compound as
+create or replace noneditionable type body ut_expectation_compound as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_compound.tps b/source/expectations/ut_expectation_compound.tps
index 46da23fea..54de48dd4 100644
--- a/source/expectations/ut_expectation_compound.tps
+++ b/source/expectations/ut_expectation_compound.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_compound under ut_expectation(
+create or replace noneditionable type ut_expectation_compound under ut_expectation(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_json.tpb b/source/expectations/ut_expectation_json.tpb
index b71e8ea83..68d4085ef 100644
--- a/source/expectations/ut_expectation_json.tpb
+++ b/source/expectations/ut_expectation_json.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_expectation_json as
+create or replace noneditionable type body ut_expectation_json as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/expectations/ut_expectation_json.tps b/source/expectations/ut_expectation_json.tps
index 561c5d11f..c75154bc8 100644
--- a/source/expectations/ut_expectation_json.tps
+++ b/source/expectations/ut_expectation_json.tps
@@ -1,7 +1,7 @@
-create or replace type ut_expectation_json under ut_expectation(
+create or replace noneditionable type ut_expectation_json under ut_expectation(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install.sql b/source/install.sql
index 22ce75365..9af0a4f66 100644
--- a/source/install.sql
+++ b/source/install.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -355,8 +355,6 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema
@@install_component.sql 'reporters/ut_coverage_html_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_sonar_reporter.tpb'
-@@install_component.sql 'reporters/ut_coveralls_reporter.tps'
-@@install_component.sql 'reporters/ut_coveralls_reporter.tpb'
@@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tps'
@@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tpb'
@@install_component.sql 'reporters/ut_realtime_reporter.tps'
diff --git a/source/install_above_12_1.sql b/source/install_above_12_1.sql
index 69e47ce9a..5a1943358 100644
--- a/source/install_above_12_1.sql
+++ b/source/install_above_12_1.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
def FILE_NAME = '&&1'
column SCRIPT_NAME new_value SCRIPT_NAME noprint
diff --git a/source/install_component.sql b/source/install_component.sql
index 373c85c54..1189df496 100644
--- a/source/install_component.sql
+++ b/source/install_component.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_ddl_trigger.sql b/source/install_ddl_trigger.sql
index bc147c2be..b23b4bc63 100644
--- a/source/install_ddl_trigger.sql
+++ b/source/install_ddl_trigger.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_headless.sql b/source/install_headless.sql
index 183262675..be1e5becf 100644
--- a/source/install_headless.sql
+++ b/source/install_headless.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/install_headless_with_trigger.sql b/source/install_headless_with_trigger.sql
index 76ae48ccb..2c05403c5 100644
--- a/source/install_headless_with_trigger.sql
+++ b/source/install_headless_with_trigger.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_ansiconsole_helper.pkb b/source/reporters/ut_ansiconsole_helper.pkb
index 53e6bc6aa..e8ee34531 100644
--- a/source/reporters/ut_ansiconsole_helper.pkb
+++ b/source/reporters/ut_ansiconsole_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_ansiconsole_helper as
+create or replace noneditionable package body ut_ansiconsole_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_ansiconsole_helper.pks b/source/reporters/ut_ansiconsole_helper.pks
index 217d36a49..e882de293 100644
--- a/source/reporters/ut_ansiconsole_helper.pks
+++ b/source/reporters/ut_ansiconsole_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_ansiconsole_helper as
+create or replace noneditionable package ut_ansiconsole_helper as
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_cobertura_reporter.tpb b/source/reporters/ut_coverage_cobertura_reporter.tpb
index d833ac0aa..45c1935b1 100644
--- a/source/reporters/ut_coverage_cobertura_reporter.tpb
+++ b/source/reporters/ut_coverage_cobertura_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_cobertura_reporter is
+create or replace noneditionable type body ut_coverage_cobertura_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_cobertura_reporter.tps b/source/reporters/ut_coverage_cobertura_reporter.tps
index 1292e60fb..799840a55 100644
--- a/source/reporters/ut_coverage_cobertura_reporter.tps
+++ b/source/reporters/ut_coverage_cobertura_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_cobertura_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_coverage_cobertura_reporter under ut_coverage_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_html_reporter.tpb b/source/reporters/ut_coverage_html_reporter.tpb
index b1f9f6651..90419371a 100644
--- a/source/reporters/ut_coverage_html_reporter.tpb
+++ b/source/reporters/ut_coverage_html_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_html_reporter is
+create or replace noneditionable type body ut_coverage_html_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_html_reporter.tps b/source/reporters/ut_coverage_html_reporter.tps
index 42f2fd4e3..23cf45c0b 100644
--- a/source/reporters/ut_coverage_html_reporter.tps
+++ b/source/reporters/ut_coverage_html_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_html_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_coverage_html_reporter under ut_coverage_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_report_html_helper.pkb b/source/reporters/ut_coverage_report_html_helper.pkb
index f7e0b5ed0..99c36ab73 100644
--- a/source/reporters/ut_coverage_report_html_helper.pkb
+++ b/source/reporters/ut_coverage_report_html_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_coverage_report_html_helper is
+create or replace noneditionable package body ut_coverage_report_html_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
@@ -90,7 +90,7 @@ create or replace package body ut_coverage_report_html_helper is
function object_id(a_object_full_name varchar2) return varchar2 is
begin
- return rawtohex(dbms_crypto.hash(src => utl_raw.cast_to_raw(a_object_full_name), typ => dbms_crypto.hash_md5));
+ return rawtohex(dbms_crypto.hash(src => utl_raw.cast_to_raw(a_object_full_name), typ => dbms_crypto.HASH_SH256));
end;
function link_to_source_file(a_object_full_name varchar2) return varchar2 is
@@ -231,7 +231,7 @@ create or replace package body ut_coverage_report_html_helper is
l_title varchar2(100) := 'All files';
l_coverage_pct number(5, 2);
l_result ut_varchar2_rows;
- l_id varchar2(50) := object_id(a_title);
+ l_id varchar2(100) := object_id(a_title);
l_unit_coverage ut_coverage.t_unit_coverage;
l_unit ut_coverage.t_object_name;
begin
diff --git a/source/reporters/ut_coverage_report_html_helper.pks b/source/reporters/ut_coverage_report_html_helper.pks
index 42a59c123..8463e3e89 100644
--- a/source/reporters/ut_coverage_report_html_helper.pks
+++ b/source/reporters/ut_coverage_report_html_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_coverage_report_html_helper authid current_user is
+create or replace noneditionable package ut_coverage_report_html_helper authid current_user is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_sonar_reporter.tpb b/source/reporters/ut_coverage_sonar_reporter.tpb
index 1861a9be3..a070572b7 100644
--- a/source/reporters/ut_coverage_sonar_reporter.tpb
+++ b/source/reporters/ut_coverage_sonar_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_coverage_sonar_reporter is
+create or replace noneditionable type body ut_coverage_sonar_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coverage_sonar_reporter.tps b/source/reporters/ut_coverage_sonar_reporter.tps
index 715bdefd2..fd160bdb5 100644
--- a/source/reporters/ut_coverage_sonar_reporter.tps
+++ b/source/reporters/ut_coverage_sonar_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_coverage_sonar_reporter under ut_coverage_reporter_base(
+create or replace noneditionable type ut_coverage_sonar_reporter under ut_coverage_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_coveralls_reporter.tpb b/source/reporters/ut_coveralls_reporter.tpb
deleted file mode 100644
index 14672303e..000000000
--- a/source/reporters/ut_coveralls_reporter.tpb
+++ /dev/null
@@ -1,104 +0,0 @@
-create or replace type body ut_coveralls_reporter is
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- constructor function ut_coveralls_reporter(
- self in out nocopy ut_coveralls_reporter
- ) return self as result is
- begin
- self.init($$plsql_unit,ut_output_bulk_buffer());
- return;
- end;
-
- overriding member procedure after_calling_run(self in out nocopy ut_coveralls_reporter, a_run in ut_run) as
-
- function get_lines_json(a_unit_coverage ut_coverage.t_unit_coverage) return ut_varchar2_rows is
- l_file_part varchar2(32767);
- l_result ut_varchar2_rows := ut_varchar2_rows();
- l_last_line_no binary_integer;
- c_coverage_header constant varchar2(30) := '"coverage": [';
- c_null constant varchar2(4) := 'null';
- begin
- ut_utils.append_to_list(l_result, c_coverage_header);
-
- l_last_line_no := a_unit_coverage.lines.last;
- if l_last_line_no is null then
- ut_utils.append_to_list(
- l_result
- , rpad( to_clob( '0' ), ( a_unit_coverage.total_lines * 3 ) - 2, ','||chr(10)||'0' )
- );
- else
- for line_no in 1 .. l_last_line_no loop
- if a_unit_coverage.lines.exists(line_no) then
- l_file_part := to_char(a_unit_coverage.lines(line_no).executions);
- else
- l_file_part := c_null;
- end if;
- if line_no < l_last_line_no then
- l_file_part := l_file_part ||',';
- end if;
- ut_utils.append_to_list(l_result, l_file_part);
- end loop;
- end if;
- ut_utils.append_to_list(l_result, ']');
- return l_result;
- end;
-
- function get_coverage_json(
- a_coverage_data ut_coverage.t_coverage
- ) return ut_varchar2_rows is
- l_result ut_varchar2_rows := ut_varchar2_rows();
- l_unit ut_coverage.t_object_name;
- c_coverage_header constant varchar2(30) := '{"source_files":[';
- c_coverage_footer constant varchar2(30) := ']}'||chr(10)||' ';
- begin
- ut_utils.append_to_list(l_result, c_coverage_header);
- l_unit := a_coverage_data.objects.first;
- while l_unit is not null loop
- ut_utils.append_to_list(l_result, '{ "name": "'||l_unit||'",');
-
- ut_utils.append_to_list(l_result,get_lines_json(a_coverage_data.objects(l_unit)));
-
- ut_utils.append_to_list(l_result, '}');
-
- l_unit := a_coverage_data.objects.next(l_unit);
- if l_unit is not null then
- ut_utils.append_to_list(l_result, ',');
- end if;
- end loop;
- ut_utils.append_to_list(l_result, c_coverage_footer);
- return l_result;
- end;
- begin
- ut_coverage.coverage_stop();
-
- self.print_text_lines(
- get_coverage_json(
- ut_coverage.get_coverage_data(a_run.coverage_options)
- )
- );
- end;
-
- overriding member function get_description return varchar2 as
- begin
- return 'Generates a JSON coverage report providing information on code coverage with line numbers.' || chr(10) ||
- 'Designed for [Coveralls](https://coveralls.io/).' || chr(10) ||
- 'JSON format conforms with specification: https://docs.coveralls.io/api-introduction';
- end;
-
-end;
-/
diff --git a/source/reporters/ut_coveralls_reporter.tps b/source/reporters/ut_coveralls_reporter.tps
deleted file mode 100644
index 74363b751..000000000
--- a/source/reporters/ut_coveralls_reporter.tps
+++ /dev/null
@@ -1,31 +0,0 @@
-create or replace type ut_coveralls_reporter under ut_coverage_reporter_base(
- /*
- utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
-
- Licensed under the Apache License, Version 2.0 (the "License"):
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- /**
- * Builds a coverage XML report that follows rules described in
- * https://docs.coveralls.io/api-introduction
- */
- constructor function ut_coveralls_reporter(
- self in out nocopy ut_coveralls_reporter
- ) return self as result,
-
- overriding member procedure after_calling_run(self in out nocopy ut_coveralls_reporter, a_run in ut_run),
-
- overriding member function get_description return varchar2
-)
-/
diff --git a/source/reporters/ut_debug_reporter.tpb b/source/reporters/ut_debug_reporter.tpb
index 879725172..547437cde 100644
--- a/source/reporters/ut_debug_reporter.tpb
+++ b/source/reporters/ut_debug_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_debug_reporter is
+create or replace noneditionable type body ut_debug_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_debug_reporter.tps b/source/reporters/ut_debug_reporter.tps
index 2123f19cc..edbf1cdc6 100644
--- a/source/reporters/ut_debug_reporter.tps
+++ b/source/reporters/ut_debug_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_debug_reporter under ut_output_reporter_base(
+create or replace noneditionable type ut_debug_reporter under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_documentation_reporter.tpb b/source/reporters/ut_documentation_reporter.tpb
index e8c0a4e31..83152ea1c 100644
--- a/source/reporters/ut_documentation_reporter.tpb
+++ b/source/reporters/ut_documentation_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_documentation_reporter is
+create or replace noneditionable type body ut_documentation_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_documentation_reporter.tps b/source/reporters/ut_documentation_reporter.tps
index 422225117..bab9082c6 100644
--- a/source/reporters/ut_documentation_reporter.tps
+++ b/source/reporters/ut_documentation_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_documentation_reporter under ut_console_reporter_base(
+create or replace noneditionable type ut_documentation_reporter under ut_console_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_junit_reporter.tpb b/source/reporters/ut_junit_reporter.tpb
index 3bceb52a4..bf62dc564 100644
--- a/source/reporters/ut_junit_reporter.tpb
+++ b/source/reporters/ut_junit_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_junit_reporter is
+create or replace noneditionable type body ut_junit_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_junit_reporter.tps b/source/reporters/ut_junit_reporter.tps
index 6cdaff1b9..a20913980 100644
--- a/source/reporters/ut_junit_reporter.tps
+++ b/source/reporters/ut_junit_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_junit_reporter force under ut_output_reporter_base(
+create or replace noneditionable type ut_junit_reporter force under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb
index 9c2af57ec..a8b7c566e 100644
--- a/source/reporters/ut_realtime_reporter.tpb
+++ b/source/reporters/ut_realtime_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_realtime_reporter is
+create or replace noneditionable type body ut_realtime_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps
index 0501006e4..b8686685b 100644
--- a/source/reporters/ut_realtime_reporter.tps
+++ b/source/reporters/ut_realtime_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_realtime_reporter force under ut_output_reporter_base(
+create or replace noneditionable type ut_realtime_reporter force under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_sonar_test_reporter.tpb b/source/reporters/ut_sonar_test_reporter.tpb
index 7c46879d2..da29b629d 100644
--- a/source/reporters/ut_sonar_test_reporter.tpb
+++ b/source/reporters/ut_sonar_test_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_sonar_test_reporter is
+create or replace noneditionable type body ut_sonar_test_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_sonar_test_reporter.tps b/source/reporters/ut_sonar_test_reporter.tps
index ac3b16bd1..0884ad3d3 100644
--- a/source/reporters/ut_sonar_test_reporter.tps
+++ b/source/reporters/ut_sonar_test_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_sonar_test_reporter under ut_output_reporter_base(
+create or replace noneditionable type ut_sonar_test_reporter under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_tap_reporter.tpb b/source/reporters/ut_tap_reporter.tpb
index ff095a369..c807ab3e1 100644
--- a/source/reporters/ut_tap_reporter.tpb
+++ b/source/reporters/ut_tap_reporter.tpb
@@ -1,5 +1,20 @@
-create or replace type body ut_tap_reporter is
+create or replace noneditionable type body ut_tap_reporter is
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
constructor function ut_tap_reporter(self in out nocopy ut_tap_reporter) return self as result is
begin
@@ -10,7 +25,7 @@ create or replace type body ut_tap_reporter is
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'));
+ self.print_clob(regexp_replace(a_comment, '^(.+)', '# \1', 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
diff --git a/source/reporters/ut_tap_reporter.tps b/source/reporters/ut_tap_reporter.tps
index bed809059..150486648 100644
--- a/source/reporters/ut_tap_reporter.tps
+++ b/source/reporters/ut_tap_reporter.tps
@@ -1,4 +1,20 @@
-create or replace type ut_tap_reporter under ut_documentation_reporter(
+create or replace noneditionable type ut_tap_reporter under ut_documentation_reporter(
+ /*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
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),
diff --git a/source/reporters/ut_teamcity_reporter.tpb b/source/reporters/ut_teamcity_reporter.tpb
index e05dc994f..94d5497d5 100644
--- a/source/reporters/ut_teamcity_reporter.tpb
+++ b/source/reporters/ut_teamcity_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_teamcity_reporter is
+create or replace noneditionable type body ut_teamcity_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_teamcity_reporter.tps b/source/reporters/ut_teamcity_reporter.tps
index e03fa3643..2def91c35 100644
--- a/source/reporters/ut_teamcity_reporter.tps
+++ b/source/reporters/ut_teamcity_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_teamcity_reporter under ut_output_reporter_base(
+create or replace noneditionable type ut_teamcity_reporter under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_teamcity_reporter_helper.pkb b/source/reporters/ut_teamcity_reporter_helper.pkb
index 1633d10aa..1d33c43ae 100644
--- a/source/reporters/ut_teamcity_reporter_helper.pkb
+++ b/source/reporters/ut_teamcity_reporter_helper.pkb
@@ -1,7 +1,7 @@
-create or replace package body ut_teamcity_reporter_helper is
+create or replace noneditionable package body ut_teamcity_reporter_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_teamcity_reporter_helper.pks b/source/reporters/ut_teamcity_reporter_helper.pks
index d7fa86cdc..bb9acef35 100644
--- a/source/reporters/ut_teamcity_reporter_helper.pks
+++ b/source/reporters/ut_teamcity_reporter_helper.pks
@@ -1,7 +1,7 @@
-create or replace package ut_teamcity_reporter_helper is
+create or replace noneditionable package ut_teamcity_reporter_helper is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_tfs_junit_reporter.tpb b/source/reporters/ut_tfs_junit_reporter.tpb
index 5e36aad17..5e24b2dca 100644
--- a/source/reporters/ut_tfs_junit_reporter.tpb
+++ b/source/reporters/ut_tfs_junit_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_tfs_junit_reporter is
+create or replace noneditionable type body ut_tfs_junit_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_tfs_junit_reporter.tps b/source/reporters/ut_tfs_junit_reporter.tps
index 61cbc3fd8..560bb10dd 100644
--- a/source/reporters/ut_tfs_junit_reporter.tps
+++ b/source/reporters/ut_tfs_junit_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_tfs_junit_reporter under ut_output_reporter_base(
+create or replace noneditionable type ut_tfs_junit_reporter under ut_output_reporter_base(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_xunit_reporter.tpb b/source/reporters/ut_xunit_reporter.tpb
index 4612fb640..74fc57ac0 100644
--- a/source/reporters/ut_xunit_reporter.tpb
+++ b/source/reporters/ut_xunit_reporter.tpb
@@ -1,7 +1,7 @@
-create or replace type body ut_xunit_reporter is
+create or replace noneditionable type body ut_xunit_reporter is
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/reporters/ut_xunit_reporter.tps b/source/reporters/ut_xunit_reporter.tps
index 6c530fee4..d701d8ab0 100644
--- a/source/reporters/ut_xunit_reporter.tps
+++ b/source/reporters/ut_xunit_reporter.tps
@@ -1,7 +1,7 @@
-create or replace type ut_xunit_reporter under ut_junit_reporter(
+create or replace noneditionable type ut_xunit_reporter under ut_junit_reporter(
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/set_install_params.sql b/source/set_install_params.sql
index 34a23dc93..b559b8023 100644
--- a/source/set_install_params.sql
+++ b/source/set_install_params.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/uninstall.sql b/source/uninstall.sql
index ced7b8dc4..712845fb7 100644
--- a/source/uninstall.sql
+++ b/source/uninstall.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/uninstall_all.sql b/source/uninstall_all.sql
index cfaaaa29f..d3d3f3fbe 100644
--- a/source/uninstall_all.sql
+++ b/source/uninstall_all.sql
@@ -1,6 +1,6 @@
/*
utPLSQL - Version 3
- Copyright 2016 - 2021 utPLSQL Project
+ Copyright 2016 - 2026 utPLSQL Project
Licensed under the Apache License, Version 2.0 (the "License"):
you may not use this file except in compliance with the License.
diff --git a/source/uninstall_coverage_tables.sql b/source/uninstall_coverage_tables.sql
index 890aa7090..df3c19627 100644
--- a/source/uninstall_coverage_tables.sql
+++ b/source/uninstall_coverage_tables.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
set echo off
set feedback off
begin
diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql
index dde9a824f..fcc8dfa52 100644
--- a/source/uninstall_objects.sql
+++ b/source/uninstall_objects.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
set echo off
declare
procedure drop_if_exists(a_object_type varchar2, a_object_name varchar2) is
@@ -57,8 +74,6 @@ drop synonym be_within;
drop synonym be_within_pct;
-drop type ut_coveralls_reporter force;
-
drop type ut_coverage_sonar_reporter force;
drop type ut_coverage_cobertura_reporter force;
@@ -273,6 +288,8 @@ drop type ut_stack force;
drop sequence ut_savepoint_seq;
+drop type ut_tap_reporter force;
+
drop type ut_documentation_reporter force;
drop type ut_debug_reporter force;
diff --git a/source/uninstall_synonyms.sql b/source/uninstall_synonyms.sql
index 2c96c03a4..4a12340f6 100644
--- a/source/uninstall_synonyms.sql
+++ b/source/uninstall_synonyms.sql
@@ -1,3 +1,20 @@
+/*
+ utPLSQL - Version 3
+ Copyright 2016 - 2026 utPLSQL Project
+
+ Licensed under the Apache License, Version 2.0 (the "License"):
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
set echo off
set feedback off
declare
diff --git a/test/install_and_run_tests.sh b/test/install_and_run_tests.sh
index 1719f137a..0c17b08b7 100755
--- a/test/install_and_run_tests.sh
+++ b/test/install_and_run_tests.sh
@@ -1,10 +1,9 @@
#!/bin/bash
set -ev
-. ./development/env.sh
-
#goto git root directory
git rev-parse && cd "$(git rev-parse --show-cdup)"
+. ./development/env.sh
cd test
time . ./install_tests.sh
diff --git a/test/install_ut3_user_tests.sql b/test/install_ut3_user_tests.sql
index 518e07841..b74c5d7ae 100644
--- a/test/install_ut3_user_tests.sql
+++ b/test/install_ut3_user_tests.sql
@@ -50,7 +50,6 @@ set define on
@@ut3_user/reporters/test_coverage/test_extended_coverage.pks
@@ut3_user/reporters/test_coverage/test_html_coverage_reporter.pks
set define off
-@@ut3_user/reporters/test_coverage/test_coveralls_reporter.pks
@@ut3_user/reporters/test_coverage/test_cov_cobertura_reporter.pks
@@ut3_user/reporters/test_coverage/test_coverage_sonar_reporter.pks
set define on
@@ -93,7 +92,6 @@ set define on
@@ut3_user/reporters/test_coverage/test_extended_coverage.pkb
@@ut3_user/reporters/test_coverage/test_html_coverage_reporter.pkb
set define off
-@@ut3_user/reporters/test_coverage/test_coveralls_reporter.pkb
@@ut3_user/reporters/test_coverage/test_cov_cobertura_reporter.pkb
@@ut3_user/reporters/test_coverage/test_coverage_sonar_reporter.pkb
set define on
diff --git a/test/run_tests.sh b/test/run_tests.sh
index 7d0431aec..078d011d6 100755
--- a/test/run_tests.sh
+++ b/test/run_tests.sh
@@ -17,7 +17,6 @@ time utPLSQL-cli/bin/utplsql run UT3_TESTER_HELPER/ut3@//${CONNECTION_STR} -D \
-f=ut_coverage_sonar_reporter -o=coverage.xml \
-f=ut_coverage_cobertura_reporter -o=cobertura.xml \
-f=ut_coverage_html_reporter -o=coverage.html \
--f=ut_coveralls_reporter -o=coverage.json \
-f=ut_sonar_test_reporter -o=test_results.xml \
-f=ut_junit_reporter -o=junit_test_results.xml \
-f=ut_tfs_junit_reporter -o=tfs_test_results.xml \
diff --git a/test/ut3_tester/core/annotations/test_annot_throws_exception.pkb b/test/ut3_tester/core/annotations/test_annot_throws_exception.pkb
index ac51d3a49..761377765 100644
--- a/test/ut3_tester/core/annotations/test_annot_throws_exception.pkb
+++ b/test/ut3_tester/core/annotations/test_annot_throws_exception.pkb
@@ -1,6 +1,7 @@
create or replace package body test_annot_throws_exception
is
g_tests_results clob;
+ g_results_other_schema clob;
procedure recollect_tests_results is
pragma autonomous_transaction;
@@ -25,10 +26,18 @@ is
e_some_exception exception;
pragma exception_init(e_some_exception, -20207);
- end;]';
+ end;
+ ]';
- l_package_spec := '
- create package annotated_package_with_throws is
+ l_package_spec := q'[
+ create or replace package annotated_package_with_throws is
+
+ c_local_error_no constant number := -20211;
+ e_some_local_exception exception;
+ pragma exception_init(e_some_local_exception, -20212);
+
+ e_uninitialized_exception_variable exception;
+
--%suite(Dummy package to test annotation throws)
--%test(Throws same annotated exception)
@@ -95,6 +104,22 @@ is
--%throws(exc_pkg.c_e_mix_missin,utter_rubbish)
procedure mixed_list_notexi;
+ --%test(Success referencing an exception variable when running from another schema)
+ --%throws(exc_pkg.e_some_exception)
+ procedure named_exc_pragma_run_from_another_schema;
+
+ --%test(Success referencing a numeric exception variable when running from another schema)
+ --%throws(exc_pkg.c_e_list_1)
+ procedure exc_number_var_run_from_another_schema;
+
+ --%test(Success referencing an exception variable without package name when running from another schema)
+ --%throws(e_some_local_exception)
+ procedure named_exc_pragma_run_from_another_schema_no_package_name;
+
+ --%test(Success referencing a numeric exception variable without package name when running from another schema)
+ --%throws(c_local_error_no)
+ procedure exc_number_var_run_from_another_schema_no_package_name;
+
--%test(Success resolve and match named exception defined in pragma exception init)
--%throws(exc_pkg.e_some_exception)
procedure named_exc_pragma;
@@ -122,11 +147,20 @@ is
--%test(Bad exception constant)
--%throws(exc_pkg.c_e_dummy);
procedure bad_exc_const;
+
+ --%test(Uninitialized exception variable can be used successfully in a test)
+ --%throws(e_uninitialized_exception_variable)
+ procedure referencing_uninitialized_exception;
+
+ --%test(Failure report shows all expected exceptions)
+ --%throws(c_local_error_no,e_some_local_exception,e_uninitialized_exception_variable)
+ procedure not_throwing_expected_exceptions;
+
end;
- ';
+ ]';
l_package_body := '
- create package body annotated_package_with_throws is
+ create or replace package body annotated_package_with_throws is
procedure raised_same_exception is
begin
raise_application_error(-20145, ''Test error'');
@@ -208,6 +242,26 @@ is
raise_application_error(exc_pkg.c_e_mix_missin,''Test'');
end;
+ procedure named_exc_pragma_run_from_another_schema is
+ begin
+ raise exc_pkg.e_some_exception;
+ end;
+
+ procedure exc_number_var_run_from_another_schema is
+ begin
+ raise_application_error(exc_pkg.c_e_list_1,''Test'');
+ end;
+
+ procedure named_exc_pragma_run_from_another_schema_no_package_name is
+ begin
+ raise e_some_local_exception;
+ end;
+
+ procedure exc_number_var_run_from_another_schema_no_package_name is
+ begin
+ raise_application_error(c_local_error_no,''Test'');
+ end;
+
procedure named_exc_pragma is
begin
raise exc_pkg.e_some_exception;
@@ -243,6 +297,15 @@ is
raise_application_error(-20143, ''Test error'');
end;
+ procedure referencing_uninitialized_exception is
+ begin
+ raise e_uninitialized_exception_variable;
+ end;
+
+ procedure not_throwing_expected_exceptions is
+ begin
+ raise_application_error(-20143, ''Test error'');
+ end;
end;
';
@@ -256,6 +319,14 @@ is
g_tests_results := ut3_develop.ut_utils.table_to_clob(l_test_results);
end;
+ procedure drop_test_package is
+ pragma autonomous_transaction;
+ begin
+ execute immediate 'drop package annotated_package_with_throws';
+ execute immediate 'drop package exc_pkg';
+ end;
+
+
procedure throws_same_annotated_except is
begin
ut.expect(g_tests_results).to_match('^\s*Throws same annotated exception \[[,\.0-9]+ sec\]\s*$','m');
@@ -312,7 +383,7 @@ is
procedure one_valid_exception_number is
begin
- ut.expect(g_tests_results).to_match('^\s*Detects a valid exception number within many invalid ones \[[\.0-9]+ sec\]\s*$','m');
+ ut.expect(g_tests_results).to_match('^\s*Detects a valid exception number within many invalid ones \[[,\.0-9]+ sec\]\s*$','m');
ut.expect(g_tests_results).to_match('one_valid_exception_number\s*Invalid parameter value ".*" for "--%throws" annotation. Parameter ignored.','m');
end;
@@ -357,7 +428,37 @@ is
ut.expect(g_tests_results).to_match('^\s*Success resolve and match named exception defined in pragma exception init \[[,\.0-9]+ sec\]\s*$','m');
ut.expect(g_tests_results).not_to_match('named_exc_pragma');
end;
-
+
+ procedure run_from_another_schema is
+ begin
+ ut3_tester_helper.run_helper.run(('ut3_tester.annotated_package_with_throws'));
+ g_results_other_schema := ut3_tester_helper.main_helper.get_dbms_output_as_clob();
+ end;
+
+ procedure named_exc_pragma_run_from_another_schema is
+ begin
+ ut.expect(g_results_other_schema).to_match('^\s*Success referencing an exception variable when running from another schema \[[,\.0-9]+ sec\]\s*$', 'm');
+ ut.expect(g_results_other_schema).not_to_match('named_exc_pragma_run_from_another_schema');
+ end;
+
+ procedure named_exc_pragma_run_from_another_schema_no_package_name is
+ begin
+ ut.expect(g_results_other_schema).to_match('^\s*Success referencing an exception variable without package name when running from another schema \[[,\.0-9]+ sec\]\s*$', 'm');
+ ut.expect(g_results_other_schema).not_to_match('named_exc_pragma_run_from_another_schema_no_package_name');
+ end;
+
+ procedure exc_number_var_run_from_another_schema_no_package_name is
+ begin
+ ut.expect(g_results_other_schema).to_match('^\s*Success referencing a numeric exception variable without package name when running from another schema \[[,\.0-9]+ sec\]\s*$', 'm');
+ ut.expect(g_results_other_schema).not_to_match('exc_number_var_run_from_another_schema_no_package_name');
+ end;
+
+ procedure exc_number_var_run_from_another_schema is
+ begin
+ ut.expect(g_results_other_schema).to_match('^\s*Success referencing a numeric exception variable when running from another schema \[[,\.0-9]+ sec\]\s*$', 'm');
+ ut.expect(g_results_other_schema).not_to_match('exc_number_var_run_from_another_schema');
+ end;
+
procedure named_exc_ora is
begin
ut.expect(g_tests_results).to_match('^\s*Success resolve and match oracle named exception \[[,\.0-9]+ sec\]\s*$','m');
@@ -392,13 +493,23 @@ is
begin
ut.expect(g_tests_results).to_match('^\s*Bad exception constant \[[,\.0-9]+ sec\] \(FAILED - [0-9]+\)\s*$','m');
ut.expect(g_tests_results).to_match('bad_exc_const\s*ORA-20143: Test error\s*ORA-06512: at "UT3_TESTER.ANNOTATED_PACKAGE_WITH_THROWS"');
- end;
-
- procedure drop_test_package is
- pragma autonomous_transaction;
+ end;
+
+ procedure referencing_uninitialized_exception is
+ l_test_results ut3_develop.ut_varchar2_list;
+ l_actual clob;
begin
- execute immediate 'drop package annotated_package_with_throws';
- execute immediate 'drop package exc_pkg';
+ select * bulk collect into l_test_results from table(ut3_develop.ut.run(('annotated_package_with_throws.referencing_uninitialized_exception')));
+
+ l_actual := ut3_develop.ut_utils.table_to_clob(l_test_results);
+ ut.expect(l_actual).to_match('^\s*Uninitialized exception variable can be used successfully in a test \[[,\.0-9]+ sec\]\s*$','m');
+ ut.expect(l_actual).not_to_match('referencing_uninitialized_exception');
+ end;
+
+ procedure not_throwing_expected_exceptions is
+ begin
+ ut.expect(g_tests_results).to_match('not_throwing_expected_exceptions');
+ ut.expect(g_tests_results).to_match('Actual: -20143 was expected to be one of: \(annotated_package_with_throws.e_some_local_exception, annotated_package_with_throws.e_uninitialized_exception_variable, -20211\)');
end;
end;
diff --git a/test/ut3_tester/core/annotations/test_annot_throws_exception.pks b/test/ut3_tester/core/annotations/test_annot_throws_exception.pks
index a9d20183d..a41c18d2b 100644
--- a/test/ut3_tester/core/annotations/test_annot_throws_exception.pks
+++ b/test/ut3_tester/core/annotations/test_annot_throws_exception.pks
@@ -5,7 +5,11 @@ is
--%beforeall
procedure recollect_tests_results;
-
+
+ --%afterall
+ procedure drop_test_package;
+
+
--%test(Gives success when annotated number exception is thrown)
procedure throws_same_annotated_except;
@@ -18,7 +22,7 @@ is
--%test(Gives failure when the raised exception is different that the annotated one)
procedure throws_diff_annotated_except;
- --%test(Ignores when the annotation throws is empty)
+ --%test(Ignores the throws annotation when it is empty)
procedure throws_empty;
--%test(Ignores when only bad parameters are passed, the test raise a exception and it shows errored test)
@@ -36,7 +40,7 @@ is
--%test(Detects a valid exception number within many invalid ones)
procedure one_valid_exception_number;
- --%test(Gives failure when a exception is expected and nothing is thrown)
+ --%test(Gives failure when an exception is expected and nothing is thrown)
procedure nothing_thrown;
--%test(Single exception defined as a constant number in package)
@@ -45,19 +49,19 @@ is
--%test(Gives success when one of annotated exception using constant is thrown)
procedure list_of_exc_constant;
- --%test(Gives failure when the raised exception is different that the annotated one using variable)
+ --%test(Gives failure when the raised exception is different than the annotated one using variable)
procedure fail_not_match_exc;
- --%test(Success when one of exception from mixed list of number and constant is thrown)
+ --%test(Success when one of exception from a mixed list of number and constant is thrown)
procedure mixed_exc_list;
- --%test(Success when match exception even if other variable on list dont exists)
+ --%test(Success when match exception even if another variable on list doesn't exists)
procedure mixed_list_notexi;
--%test(Success resolve and match named exception defined in pragma exception init)
procedure named_exc_pragma;
-
- --%test(Success resolve and match oracle named exception no data)
+
+ --%test(Success resolve and match oracle named exception no data)
procedure named_exc_ora;
--%test(Success resolve and match oracle named exception dup val index)
@@ -73,10 +77,32 @@ is
procedure non_existing_const;
--%test(Bad exception constant)
- procedure bad_exc_const;
+ procedure bad_exc_const;
+
+ --%test(Uninitialized exception variable can be used successfully in a test)
+ procedure referencing_uninitialized_exception;
+
+ --%test(a Failure report shows all expected exceptions)
+ procedure not_throwing_expected_exceptions;
- --%afterall
- procedure drop_test_package;
+ --%context(referencing exceptions when running from another schema)
+
+ --%beforeall
+ procedure run_from_another_schema;
+
+ --%test(Success referencing an exception variable when running from another schema)
+ procedure named_exc_pragma_run_from_another_schema;
+
+ --%test(Success referencing a numeric exception variable when running from another schema)
+ procedure exc_number_var_run_from_another_schema;
+
+ --%test(Success referencing an exception variable without a package name when running from another schema)
+ procedure named_exc_pragma_run_from_another_schema_no_package_name;
+
+ --%test(Success referencing a numeric exception variable without a package name when running from another schema)
+ procedure exc_number_var_run_from_another_schema_no_package_name;
+
+ --%endcontext
end;
/
diff --git a/test/ut3_tester/core/annotations/test_annotation_parser.pkb b/test/ut3_tester/core/annotations/test_annotation_parser.pkb
index bc789c377..beb526863 100644
--- a/test/ut3_tester/core/annotations/test_annotation_parser.pkb
+++ b/test/ut3_tester/core/annotations/test_annotation_parser.pkb
@@ -1,27 +1,28 @@
create or replace package body test_annotation_parser is
procedure test_proc_comments is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
-
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- -- %ann1(Name of suite)
- -- wrong line
- -- %ann2(some_value)
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' -- %ann1(Name of suite)' || chr(10),
+ ' -- wrong line' || chr(10),
+ ' -- %ann2(some_value)' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
-
l_expected := ut3_develop.ut_annotations(
ut3_develop.ut_annotation(2,'suite',null, null),
ut3_develop.ut_annotation(3,'displayname','Name of suite',null),
@@ -34,30 +35,33 @@ create or replace package body test_annotation_parser is
end;
procedure include_floating_annotations is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- -- %ann1(Name of suite)
- -- %ann2(all.globaltests)
-
- --%test
- procedure foo;
-
- -- %ann3(Name of suite)
- -- %ann4(all.globaltests)
-
- --%test
- procedure bar;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' -- %ann1(Name of suite)' || chr(10),
+ ' -- %ann2(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' procedure foo;' || chr(10),
+ '' || chr(10),
+ ' -- %ann3(Name of suite)' || chr(10),
+ ' -- %ann4(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' procedure bar;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -77,40 +81,41 @@ create or replace package body test_annotation_parser is
end;
procedure parse_complex_with_functions is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- --%test
- procedure foo;
-
-
- --%beforeeach
- procedure foo2;
-
- --test comment
- -- wrong comment
-
-
- /*
- describtion of the procedure
- */
- --%beforeeach(key=testval)
- PROCEDURE foo3(a_value number default null);
-
- --%all
- function foo4(a_val number default null
- , a_par varchar2 default := ''asdf'');
- END;';
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' procedure foo;' || chr(10),
+ '' || chr(10),
+ '' || chr(10),
+ ' --%beforeeach' || chr(10),
+ ' procedure foo2;' || chr(10),
+ '' || chr(10),
+ ' --test comment' || chr(10),
+ ' -- wrong comment' || chr(10),
+ '' || chr(10),
+ '' || chr(10),
+ '/*' || chr(10),
+ ' describtion of the procedure' || chr(10),
+ ' */' || chr(10),
+ ' --%beforeeach(key=testval)' || chr(10),
+ ' PROCEDURE foo3(a_value number default null);' || chr(10),
+ '' || chr(10),
+ ' --%all' || chr(10),
+ ' function foo4(a_val number default null' || chr(10),
+ ' , a_par varchar2 default := ''asdf'');' || chr(10),
+ 'END;'));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -128,21 +133,24 @@ create or replace package body test_annotation_parser is
end;
procedure no_procedure_annotation is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -156,21 +164,24 @@ create or replace package body test_annotation_parser is
end;
procedure parse_accessible_by is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt accessible by (foo) AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt accessible by (foo) AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -184,24 +195,27 @@ create or replace package body test_annotation_parser is
end;
procedure complex_package_declaration is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt
- ACCESSIBLE BY (calling_proc)
- authid current_user
- AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt' || chr(10),
+ ' ACCESSIBLE BY (calling_proc)' || chr(10),
+ ' authid current_user' || chr(10),
+ ' AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -215,21 +229,24 @@ create or replace package body test_annotation_parser is
end;
procedure complex_text is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- --%displayname(name = Name of suite)
- -- %suitepath(key=all.globaltests,key2=foo,"--%some text")
-
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' --%displayname(name = Name of suite)' || chr(10),
+ ' -- %suitepath(key=all.globaltests,key2=foo,"--%some text")' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -243,26 +260,29 @@ create or replace package body test_annotation_parser is
end;
procedure ignore_annotations_in_comments is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- /*
- Some comment
- -- inlined
- -- %ignored
- */
- -- %suite
- --%displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- procedure foo;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' /*' || chr(10),
+ ' Some comment' || chr(10),
+ ' -- inlined' || chr(10),
+ ' -- %ignored' || chr(10),
+ ' */' || chr(10),
+ ' -- %suite' || chr(10),
+ ' --%displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -311,17 +331,19 @@ v58yvbLAXLi9gYHwoIvAgccti+Cmpg0DKLY=
end;
procedure brackets_in_desc is
-
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite(Name of suite (including some brackets) and some more text)
-END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite(Name of suite (including some brackets) and some more text)' || chr(10),
+ 'END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -332,24 +354,27 @@ END;';
end;
procedure test_space_before_annot_params is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
- l_expected ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- /*
- Some comment
- -- inlined
- */
- -- %suite
- -- %suitepath (all.globaltests)
-
- procedure foo;
-END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' /*' || chr(10),
+ ' Some comment' || chr(10),
+ ' -- inlined' || chr(10),
+ ' */' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %suitepath (all.globaltests)'|| chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ 'END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -362,18 +387,21 @@ END;';
procedure test_windows_newline
as
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %suite
- -- %displayname(Name of suite)' || chr(13) || chr(10)
- || ' -- %suitepath(all.globaltests)
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(13) || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -387,21 +415,24 @@ END;';
procedure test_annot_very_long_name
as
- l_source clob;
- l_actual ut3_develop.ut_annotations;
- l_expected ut3_develop.ut_annotations;
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE very_long_procedure_name_valid_for_oracle_12_so_utPLSQL_should_allow_it_definitely_well_still_not_reached_128_but_wait_we_did_it AS
- -- %suite
- -- %displayname(Name of suite)
- -- %suitepath(all.globaltests)
-
- --%test
- procedure very_long_procedure_name_valid_for_oracle_12_so_utPLSQL_should_allow_it_definitely_well_still_not_reached_128_but_wait_we_dit_it;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE very_long_procedure_name_valid_for_oracle_12_so_utPLSQL_should_allow_it_definitely_well_still_not_reached_128_but_wait_we_did_it AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(Name of suite)' || chr(10),
+ ' -- %suitepath(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' procedure very_long_procedure_name_valid_for_oracle_12_so_utPLSQL_should_allow_it_definitely_well_still_not_reached_128_but_wait_we_dit_it;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -415,30 +446,33 @@ END;';
end;
procedure test_upper_annot is
- l_source clob;
+ l_source dbms_preprocessor.source_lines_t;
l_actual ut3_develop.ut_annotations;
l_expected ut3_develop.ut_annotations;
begin
- l_source := 'PACKAGE test_tt AS
- -- %SUITE
- -- %DISPLAYNAME(Name of suite)
- -- %SUITEPATH(all.globaltests)
-
- -- %ANN1(Name of suite)
- -- %ANN2(all.globaltests)
-
- --%TEST
- procedure foo;
-
- -- %ANN3(Name of suite)
- -- %ANN4(all.globaltests)
-
- --%TEST
- procedure bar;
- END;';
+ --Arrange
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %SUITE' || chr(10),
+ ' -- %DISPLAYNAME(Name of suite)' || chr(10),
+ ' -- %SUITEPATH(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' -- %ANN1(Name of suite)' || chr(10),
+ ' -- %ANN2(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%TEST' || chr(10),
+ ' procedure foo;' || chr(10),
+ '' || chr(10),
+ ' -- %ANN3(Name of suite)' || chr(10),
+ ' -- %ANN4(all.globaltests)' || chr(10),
+ '' || chr(10),
+ ' --%TEST' || chr(10),
+ ' procedure bar;' || chr(10),
+ ' END;' || chr(10)
+ ));
--Act
- l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source);
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
--Assert
l_expected := ut3_develop.ut_annotations(
@@ -457,5 +491,414 @@ END;';
end;
+ ------------------------------------------------------------
+ -- replace_multiline_comments coverage tests
+ ------------------------------------------------------------
+
+ procedure test_rmc_empty_source is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result.count).to_equal(0);
+ end;
+
+ procedure test_rmc_no_ml_comment_marker is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'procedure foo is' || chr(10),
+ 'begin' || chr(10),
+ ' null;' || chr(10),
+ 'end;' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(ut3_tester_helper.main_helper.lines_to_str(l_result)).to_equal(ut3_tester_helper.main_helper.lines_to_str(l_input));
+ end;
+
+ procedure test_rmc_line_inside_ml_comment is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'x := 1; /* start' || chr(10),
+ 'this whole line is comment' || chr(10),
+ 'end comment */ x := 2;' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('x := 1; ' || chr(10));
+ ut.expect(l_result(2)).to_equal('');
+ ut.expect(l_result(3)).to_equal(' x := 2;' || chr(10));
+ end;
+
+ procedure test_rmc_ml_comment_closed_midline is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ '/* open' || chr(10),
+ 'still inside' || chr(10),
+ '*/ code /* remove this too */ kept' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(2)).to_equal('');
+ ut.expect(l_result(3)).to_equal(' code kept' || chr(10));
+ end;
+
+ procedure test_rmc_fast_path_no_tokens is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ -- line 2 has none of / - ' so hits fast path B; line 1 needed to pass pre-scan
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ '/* comment */' || chr(10),
+ 'begin' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(2)).to_equal('begin' || chr(10));
+ end;
+
+ procedure test_rmc_ml_comment_single_line is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'x := /* inline comment */ 42;' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('x := 42;' || chr(10));
+ end;
+
+ procedure test_rmc_single_line_comment_preserved is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ '/* marker */' || chr(10),
+ ' -- %test annotation' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(2)).to_equal(' -- %test annotation' || chr(10));
+ end;
+
+ procedure test_rmc_string_literal_protects_markers is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'v := ''val /* not a comment */ here'';' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('v := ''val /* not a comment */ here'';' || chr(10));
+ end;
+
+ procedure test_rmc_string_literal_escaped_quotes is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'v := ''it''''s a /* test */'';' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('v := ''it''''s a /* test */'';' || chr(10));
+ end;
+
+ procedure test_rmc_q_quoted_string_literal is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'v := q''[/* not a comment */]'';' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('v := q''[/* not a comment */]'';' || chr(10));
+ end;
+
+ procedure test_rmc_unclosed_string_literal is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'v := ''hello /* inside unclosed' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('v := ''hello /* inside unclosed' || chr(10));
+ end;
+
+ procedure test_rmc_unclosed_q_string is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ c_line constant varchar2(100) := q'(v := q'[/* unclosed q-string)' || chr(10);
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(c_line));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal(c_line);
+ end;
+
+ procedure test_rmc_multiple_ml_comments_one_line is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'a /* one */ := /* two */ 1;' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('a := 1;' || chr(10));
+ end;
+
+ procedure test_rmc_comment_after_string_with_slash is
+ l_input dbms_preprocessor.source_lines_t;
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ --Arrange
+ l_input := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'v := ''a/b''; -- this is /* not */ a ml comment' || chr(10)
+ ));
+
+ --Act
+ l_result := ut3_develop.ut_utils.replace_multiline_comments(l_input);
+
+ --Assert
+ ut.expect(l_result(1)).to_equal('v := ''a/b''; -- this is /* not */ a ml comment' || chr(10));
+ end;
+
+ procedure test_multiline_proc_header_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- procedure header spans multiple lines before terminating ;
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' procedure foo(' || chr(10),
+ ' a_param1 varchar2' || chr(10),
+ ' ,a_param2 number default null' || chr(10),
+ ' );' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
+ ut3_develop.ut_annotation( 4, 'test', null, 'foo' )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
+ procedure test_non_comment_line_resets_block_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- a non-comment non-proc line between annotation and procedure breaks the association
+ -- %test becomes a floating top-level annotation with no subobject
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' pragma serially_reusable;' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ -- %test is NOT associated with foo β accumulator was reset by pragma line
+ -- it surfaces as a top-level annotation with no subobject_name
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
+ ut3_develop.ut_annotation( 4, 'test', null, null )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
+ procedure test_annotation_not_at_line_start_ignored_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- code before -- means it is not at start of line and must be ignored
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' x := 1; -- %not_an_annotation' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
+ procedure test_whitespace_line_between_comment_and_proc_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- space-only line between annotation comment and procedure declaration is tolerated
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ '' || chr(10),
+ ' --%test' || chr(10),
+ ' ' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
+ ut3_develop.ut_annotation( 4, 'test', null, 'foo' )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
+ procedure test_space_between_dashes_and_qualifier_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- spaces between -- and % are skipped and annotation is still recognised
+ -- annotations are not adjacent to a procedure so they are top-level
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- %displayname(my suite)' || chr(10),
+ '' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
+ ut3_develop.ut_annotation( 3, 'displayname', 'my suite', null )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
+ procedure test_percent_not_after_dashes_ignored_lines is
+ l_source dbms_preprocessor.source_lines_t;
+ l_actual ut3_develop.ut_annotations;
+ l_expected ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ -- -- present and % present on line but % is not immediately after --
+ -- e.g. a regular comment that happens to mention 100%
+ l_source := ut3_tester_helper.main_helper.make_source(ut3_develop.ut_varchar2_list(
+ 'PACKAGE test_tt AS' || chr(10),
+ ' -- %suite' || chr(10),
+ ' -- coverage is 100% on this module' || chr(10),
+ ' procedure foo;' || chr(10),
+ ' END;' || chr(10)
+ ));
+
+ --Act
+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
+
+ --Assert
+ l_expected := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation( 2, 'suite', null, null )
+ );
+
+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
+ end;
+
end test_annotation_parser;
-/
+/
\ No newline at end of file
diff --git a/test/ut3_tester/core/annotations/test_annotation_parser.pks b/test/ut3_tester/core/annotations/test_annotation_parser.pks
index a4fe3ed70..c61c14d3a 100644
--- a/test/ut3_tester/core/annotations/test_annotation_parser.pks
+++ b/test/ut3_tester/core/annotations/test_annotation_parser.pks
@@ -19,24 +19,57 @@ create or replace package test_annotation_parser is
procedure complex_text;
--%test(Ignores content of multi-line comments)
procedure ignore_annotations_in_comments;
-
- --%test(Ignores wrapped package and does not raise exception)
+ -- %test(ignore wrapped package source)
procedure ignore_wrapped_package;
-
--%test(Parses package level annotations with annotation params containing brackets)
procedure brackets_in_desc;
-
--%test(Parses annotation text even with spaces before brackets)
procedure test_space_before_annot_params;
-
-- %test(Parses source-code with Windows-style newline)
procedure test_windows_newline;
-
- -- %test(Parses annotations with very long object names)
+ -- %test(parse annotations with very long procedure name)
procedure test_annot_very_long_name;
-
-- %test(Parses upper case annotations)
procedure test_upper_annot;
+ -- %test(empty source returns immediately without processing)
+ procedure test_rmc_empty_source;
+ -- %test(source with no multiline comment markers returned unchanged)
+ procedure test_rmc_no_ml_comment_marker;
+ -- %test(line entirely inside multiline comment is blanked)
+ procedure test_rmc_line_inside_ml_comment;
+ -- %test(closing delimiter mid-line falls through to scan remainder)
+ procedure test_rmc_ml_comment_closed_midline;
+ -- %test(fast path line with no slash dash or quote copied unchanged)
+ procedure test_rmc_fast_path_no_tokens;
+ -- %test(single-line block comment removed on same line)
+ procedure test_rmc_ml_comment_single_line;
+ -- %test(single-line comment preserved intact)
+ procedure test_rmc_single_line_comment_preserved;
+ -- %test(string literal containing comment markers not stripped)
+ procedure test_rmc_string_literal_protects_markers;
+ -- %test(string literal with escaped quotes handled correctly)
+ procedure test_rmc_string_literal_escaped_quotes;
+ -- %test(q-quoted string literal protects interior comment markers)
+ procedure test_rmc_q_quoted_string_literal;
+ -- %test(unclosed string literal copies remainder and exits scan)
+ procedure test_rmc_unclosed_string_literal;
+ -- %test(unclosed q-quoted string copies remainder and exits scan)
+ procedure test_rmc_unclosed_q_string;
+ -- %test(multiple block comments on single line all removed)
+ procedure test_rmc_multiple_ml_comments_one_line;
+ -- %test(comment markers after string with slash handled correctly)
+ procedure test_rmc_comment_after_string_with_slash;
+ --%test(Procedure header spanning multiple lines is handled correctly)
+ procedure test_multiline_proc_header_lines;
+ --%test(Non-comment line between annotation and procedure resets association)
+ procedure test_non_comment_line_resets_block_lines;
+ --%test(Comment with non-whitespace before dashes is not treated as annotation)
+ procedure test_annotation_not_at_line_start_ignored_lines;
+ --%test(Spaces between dashes and annotation qualifier are skipped correctly)
+ procedure test_space_between_dashes_and_qualifier_lines;
+ --%test(Percent sign not immediately after dashes is not treated as annotation)
+ procedure test_percent_not_after_dashes_ignored_lines;
+
end test_annotation_parser;
-/
+/
\ No newline at end of file
diff --git a/test/ut3_tester/core/test_output_buffer.pkb b/test/ut3_tester/core/test_output_buffer.pkb
index 317e7e3d5..55670b8b8 100644
--- a/test/ut3_tester/core/test_output_buffer.pkb
+++ b/test/ut3_tester/core/test_output_buffer.pkb
@@ -1,5 +1,13 @@
create or replace package body test_output_buffer is
+ function long_text return varchar2 is
+ l_txt varchar2(32767);
+ begin
+ for i in 1 .. 100 loop
+ l_txt := l_txt||lpad('a text', 310, ',a text');
+ end loop;
+ return l_txt;
+ end;
procedure test_receive is
l_actual_text clob;
l_actual_item_type varchar2(1000);
@@ -10,10 +18,10 @@ create or replace package body test_output_buffer is
begin
--Arrange
l_buffer := ut3_develop.ut_output_clob_table_buffer();
- l_expected_text := to_clob(lpad('a text', 31000, ',a text'))
- || chr(10) || to_clob(lpad('a text', 31000, ',a text'))
- || chr(13) || to_clob(lpad('a text', 31000, ',a text'))
- || chr(13) || chr(10) || to_clob(lpad('a text', 31000, ',a text')) || to_clob(lpad('a text', 31000, ',a text'));
+ l_expected_text := to_clob('a text') ||long_text()
+ || chr(10) || long_text()
+ || chr(13) || long_text()
+ || chr(13) || chr(10) || long_text() || long_text();
l_expected_item_type := lpad('some item type',1000,'-');
--Act
l_buffer.lock_buffer();
@@ -196,5 +204,14 @@ create or replace package body test_output_buffer is
ut.expect(lengthb(l_text)).to_be_less_or_equal(l_max_len);
end;
- end test_output_buffer;
+ procedure concurrent_calls_do_not_cause_exception is
+ l_consumer_buffer_instance ut3_develop.ut_output_buffer_base;
+ l_shared_output_id raw(32) := sys_guid();
+ begin
+ ut3_tester_helper.run_helper.run_as_job('declare x ut3_develop.ut_output_buffer_base; begin x := ut3_develop.ut_output_table_buffer(a_output_id => '''||l_shared_output_id||'''); end;');
+ dbms_session.sleep(0.5);
+ l_consumer_buffer_instance := ut3_develop.ut_output_table_buffer(a_output_id => l_shared_output_id);
+ end;
+
+end test_output_buffer;
/
diff --git a/test/ut3_tester/core/test_output_buffer.pks b/test/ut3_tester/core/test_output_buffer.pks
index 5b6cd678b..aa5c830d3 100644
--- a/test/ut3_tester/core/test_output_buffer.pks
+++ b/test/ut3_tester/core/test_output_buffer.pks
@@ -53,5 +53,10 @@ create or replace package test_output_buffer is
--%test(Successfully sends multibyte long clob line into text buffer)
procedure text_buffer_send_clob_multib;
+ --%beforetest(ut3_tester_helper.run_helper.slow_down_insert_into_table_buffer)
+ --%aftertest(ut3_tester_helper.run_helper.cleanup_slow_down_insert_into_table_buffer)
+ --%test(concurrent calls to init() procedure do not cause errors - Issue #985)
+ procedure concurrent_calls_do_not_cause_exception;
+
end test_output_buffer;
/
diff --git a/test/ut3_tester/core/test_suite_builder.pkb b/test/ut3_tester/core/test_suite_builder.pkb
index 570d86a0d..9a86772c7 100644
--- a/test/ut3_tester/core/test_suite_builder.pkb
+++ b/test/ut3_tester/core/test_suite_builder.pkb
@@ -1370,6 +1370,54 @@ create or replace package body test_suite_builder is
);
end;
+ procedure context_name_case_insensitive is
+ l_actual clob;
+ l_annotations ut3_develop.ut_annotations;
+ begin
+ --Arrange
+ l_annotations := ut3_develop.ut_annotations(
+ ut3_develop.ut_annotation(1, 'suite','Cool', null),
+ ut3_develop.ut_annotation(2, 'beforeall',null, 'suite_level_beforeall'),
+ ut3_develop.ut_annotation(3, 'test','In suite', 'suite_level_test'),
+ ut3_develop.ut_annotation(4, 'context','A context', null),
+ ut3_develop.ut_annotation(5, 'name','a_Context', null),
+ ut3_develop.ut_annotation(6, 'beforeall',null, 'context_setup'),
+ ut3_develop.ut_annotation(7, 'test', 'In context', 'test_in_a_context'),
+ ut3_develop.ut_annotation(8, 'endcontext',null, null)
+ );
+ --Act
+ l_actual := invoke_builder_for_annotations(l_annotations, 'SOME_PACKAGE');
+ --Assert
+ ut.expect(l_actual).to_be_like(
+ ''||
+ '' ||
+ '%' ||
+ '%' ||
+ '' ||
+ '%suite_level_testIn suitesome_package.suite_level_test' ||
+ '%' ||
+ '' ||
+ '%a_contextA contextsome_package.a_context' ||
+ '%' ||
+ '' ||
+ '%test_in_a_contextIn contextsome_package.a_context.test_in_a_context' ||
+ '%' ||
+ '' ||
+ '' ||
+ '%some_packagecontext_setup' ||
+ '%' ||
+ '' ||
+ '' ||
+ '' ||
+ '' ||
+ '%some_packagesuite_level_beforeall' ||
+ '%' ||
+ '' ||
+ ''||
+ ''
+ );
+ end;
+
procedure throws_value_empty is
l_actual clob;
l_annotations ut3_develop.ut_annotations;
diff --git a/test/ut3_tester/core/test_suite_builder.pks b/test/ut3_tester/core/test_suite_builder.pks
index 4cbfcad74..09ff3c0b3 100644
--- a/test/ut3_tester/core/test_suite_builder.pks
+++ b/test/ut3_tester/core/test_suite_builder.pks
@@ -142,7 +142,7 @@ create or replace package test_suite_builder is
--%test(Falls back to default context name and gives warning when name contains spaces)
procedure name_with_spaces_invalid;
- --%test(Raises warning when more than one name annotation used )
+ --%test(Raises warning when more than one name annotation used)
procedure duplicate_name_annotation;
--%test(Is ignored when used outside of context - no warning given)
@@ -154,6 +154,9 @@ create or replace package test_suite_builder is
--%test(Is applied to corresponding context when multiple contexts used)
procedure multiple_contexts;
+ --%test(Context name is case insensitive)
+ procedure context_name_case_insensitive;
+
--%endcontext
--%context(--%throws annotation)
diff --git a/test/ut3_tester/core/test_ut_suite_tag_filter.pkb b/test/ut3_tester/core/test_ut_suite_tag_filter.pkb
index edfb27cfc..32610edf6 100644
--- a/test/ut3_tester/core/test_ut_suite_tag_filter.pkb
+++ b/test/ut3_tester/core/test_ut_suite_tag_filter.pkb
@@ -62,6 +62,15 @@ create or replace package body test_ut_suite_tag_filter is
ut.fail('Expected exception but nothing was raised');
end;
+ procedure conversion_throws_when_lb_rb is
+ l_postfix ut3_develop.ut_varchar2_list;
+ l_input_token ut3_develop.ut_varchar2_list;
+ begin
+ l_input_token := ut3_develop.ut_varchar2_list('(',')');
+ l_postfix := ut3_develop.ut_suite_tag_filter.shunt_logical_expression(l_input_token);
+ ut.fail('Expected exception but nothing was raised');
+ end;
+
procedure conv_from_tag_to_sql_filter is
l_sql_filter varchar2(4000);
begin
@@ -78,5 +87,37 @@ create or replace package body test_ut_suite_tag_filter is
ut.expect(l_sql_filter).to_equal(q'[('test1' member of tags and not('test2' member of tags))]');
end;
+ procedure filtering_is_correctly_applied_to_all_items is
+ l_input_data ut3_develop.ut_suite_cache_rows;
+ l_expected sys_refcursor;
+ l_actual sys_refcursor;
+ begin
+ l_input_data := ut3_develop.ut_suite_cache_rows(
+ ut3_develop.ut_suite_cache_row(
+ 1, 'UT_SUITE', 'some.path.test_tags', 'TEST_USER', 'TEST_TAGS', 'TEST_TAGS', 3, timestamp '2026-05-06 10:23:38.461299', NULL, NULL, 0, NULL, null, null, null, null, null, null, null, null,
+ ut3_develop.ut_varchar2_rows('slow'), null),
+ ut3_develop.ut_suite_cache_row(
+ 2, 'UT_SUITE_CONTEXT', 'some.path.test_tags.nested_context_#1', 'TEST_USER', 'TEST_TAGS', 'NESTED_CONTEXT_#1', 9, timestamp '2026-05-06 10:23:38.461299', 'tags_are_applied_in_contexts', NULL, 0, NULL, null, null, null, null, null, null, null, null,
+ ut3_develop.ut_varchar2_rows('context_tag'), null),
+ ut3_develop.ut_suite_cache_row(
+ 3, 'UT_TEST', 'some.path.test_tags.nested_context_#1.create_new_mapping', 'TEST_USER', 'TEST_TAGS', 'CREATE_NEW_MAPPING', 11, timestamp '2026-05-06 10:23:38.461299', NULL, NULL, 0, NULL, null, null, null, null, null, null, null, null,
+ ut3_develop.ut_varchar2_rows('test_tag'), ut3_develop.ut_executable_test('UT_EXECUTABLE_TEST', 'test', 'TEST_USER', 'test_tags', 'create_new_mapping', NULL, NULL, NULL, NULL, NULL))
+ );
+
+ ut.expect(ut3_develop.ut_suite_tag_filter.apply( l_input_data, 'slow').count).to_equal(3 );
+
+ open l_expected for select * from table( l_input_data );
+ open l_actual for select * from table( ut3_develop.ut_suite_tag_filter.apply( l_input_data, 'slow') );
+ ut.expect(l_actual).to_equal(l_expected).join_by('ID');
+
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, '!slow').count ).to_equal(0);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, 'bad').count ).to_equal(0);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, '!bad').count ).to_equal(3);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, '!context_tag').count ).to_equal(0);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, 'context_tag').count ).to_equal(3);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, '!test_tag').count ).to_equal(0);
+ ut.expect( ut3_develop.ut_suite_tag_filter.apply(l_input_data, 'test_tag').count ).to_equal(3);
+ end;
+
end test_ut_suite_tag_filter;
/
diff --git a/test/ut3_tester/core/test_ut_suite_tag_filter.pks b/test/ut3_tester/core/test_ut_suite_tag_filter.pks
index 0f84b751b..e7b255d4b 100644
--- a/test/ut3_tester/core/test_ut_suite_tag_filter.pks
+++ b/test/ut3_tester/core/test_ut_suite_tag_filter.pks
@@ -24,10 +24,17 @@ create or replace package test_ut_suite_tag_filter is
--%throws(ut3_develop.ut_utils.gc_invalid_tag_expression)
procedure test_conversion_rb_by_oprd;
+ --%test(Conversion raises exception when empty brackets)
+ --%throws(ut3_develop.ut_utils.gc_invalid_tag_expression)
+ procedure conversion_throws_when_lb_rb;
+
--%endcontext
--%test( Test conversion of expression from tag into custom where filter for SQL)
- procedure conv_from_tag_to_sql_filter;
+ procedure conv_from_tag_to_sql_filter;
+
+ --%test( Regression for issue #1324 - corect filtering by tags with suitepath and contexts)
+ procedure filtering_is_correctly_applied_to_all_items;
end test_ut_suite_tag_filter;
/
diff --git a/test/ut3_tester/core/test_ut_utils.pkb b/test/ut3_tester/core/test_ut_utils.pkb
index 433987c01..4dc10492b 100644
--- a/test/ut3_tester/core/test_ut_utils.pkb
+++ b/test/ut3_tester/core/test_ut_utils.pkb
@@ -375,8 +375,8 @@ end;';
procedure replace_multiline_comments
is
l_source clob;
- l_actual clob;
- l_expected clob;
+ l_actual dbms_preprocessor.source_lines_t;
+ l_expected dbms_preprocessor.source_lines_t;
begin
--Arrange
l_source := q'[
@@ -390,11 +390,11 @@ create or replace package dummy as
gv_text2 varchar2(200) := '/* multi-line comment
in a multi-line
string*/';
- -- ignored start of multi-line comment with multi-byte text οΏ½ /*
- -- ignored end of multi-line comment with multi-byte text οΏ½ */
+ -- ignored start of multi-line comment with multi-byte text βΊ /*
+ -- ignored end of multi-line comment with multi-byte text βΊ */
/* multi-line comment
with
- multi-byte characters οΏ½οΏ½οΏ½
+ multi-byte characters βΊβΊβΊ
in it */
gv_text3 varchar2(200) := 'some text'; /* multiline comment*/ --followed by single-line comment
/* multi-line comment in one line*/
@@ -403,7 +403,14 @@ create or replace package dummy as
string*/}';
end;
]';
- l_expected := q'[
+
+ --Act
+ l_actual := ut3_develop.ut_utils.replace_multiline_comments(
+ ut3_tester_helper.main_helper.make_source( ut3_develop.ut_utils.clob_to_table(l_source) )
+ );
+
+ --Assert
+ l_expected := ut3_tester_helper.main_helper.make_source( ut3_develop.ut_utils.clob_to_table( q'[
create or replace package dummy as
-- single line comment with disabled /* multi-line comment */
@@ -414,8 +421,8 @@ create or replace package dummy as
gv_text2 varchar2(200) := '/* multi-line comment
in a multi-line
string*/';
- -- ignored start of multi-line comment with multi-byte text οΏ½ /*
- -- ignored end of multi-line comment with multi-byte text οΏ½ */
+ -- ignored start of multi-line comment with multi-byte text βΊ /*
+ -- ignored end of multi-line comment with multi-byte text βΊ */
]'||q'[
@@ -426,11 +433,9 @@ create or replace package dummy as
in escaped q'multi-line
string*/}';
end;
-]';
+]' ) );
--Act
- l_actual := ut3_develop.ut_utils.replace_multiline_comments(l_source);
- --Assert
- ut.expect(l_actual).to_equal(l_expected);
+ ut.expect(ut3_tester_helper.main_helper.lines_to_str(l_actual)).to_equal(ut3_tester_helper.main_helper.lines_to_str(l_expected));
end;
procedure int_conv_ds_sec is
diff --git a/test/ut3_tester_helper/main_helper.pkb b/test/ut3_tester_helper/main_helper.pkb
index f1dadec66..f60ce796c 100644
--- a/test/ut3_tester_helper/main_helper.pkb
+++ b/test/ut3_tester_helper/main_helper.pkb
@@ -155,6 +155,24 @@ create or replace package body main_helper is
begin
ut3_develop.ut_session_context.clear_all_context;
end;
+
+ function lines_to_str(a_lines dbms_preprocessor.source_lines_t) return varchar2 is
+ l_result varchar2(32767);
+ begin
+ for i in 1 .. a_lines.count loop
+ l_result := l_result || a_lines(i);
+ end loop;
+ return l_result;
+ end;
+
+ function make_source(a_lines ut3_develop.ut_varchar2_list) return dbms_preprocessor.source_lines_t is
+ l_result dbms_preprocessor.source_lines_t;
+ begin
+ for i in 1 .. a_lines.count loop
+ l_result(i) := a_lines(i);
+ end loop;
+ return l_result;
+ end;
end;
/
diff --git a/test/ut3_tester_helper/main_helper.pks b/test/ut3_tester_helper/main_helper.pks
index 7decad88d..71575e145 100644
--- a/test/ut3_tester_helper/main_helper.pks
+++ b/test/ut3_tester_helper/main_helper.pks
@@ -47,5 +47,9 @@ create or replace package main_helper is
procedure clear_ut_run_context;
+ function lines_to_str(a_lines dbms_preprocessor.source_lines_t) return varchar2;
+
+ function make_source(a_lines ut3_develop.ut_varchar2_list) return dbms_preprocessor.source_lines_t;
+
end;
/
diff --git a/test/ut3_tester_helper/run_helper.pkb b/test/ut3_tester_helper/run_helper.pkb
index 9d65d6667..c56f31dc0 100644
--- a/test/ut3_tester_helper/run_helper.pkb
+++ b/test/ut3_tester_helper/run_helper.pkb
@@ -211,7 +211,7 @@ create or replace package body run_helper is
begin execute immediate 'drop package ut3_user.test_db_link'; exception when others then null; end;
end;
- procedure create_suite_with_link is
+ procedure create_suite_with_link is
pragma autonomous_transaction;
begin
create_db_link;
@@ -250,7 +250,7 @@ create or replace package body run_helper is
execute immediate 'grant execute on test_distributed_savepoint to public';
end;
- procedure drop_suite_with_link is
+ procedure drop_suite_with_link is
pragma autonomous_transaction;
begin
drop_db_link;
@@ -926,5 +926,39 @@ create or replace package body run_helper is
return l_result;
end;
+ procedure slow_down_insert_into_table_buffer is
+ pragma autonomous_transaction;
+ begin
+ execute immediate q'[
+ create or replace trigger ut3_develop.slow_down_buffer_insert
+ before insert on ut3_develop.ut_output_buffer_info_tmp
+ begin
+ dbms_session.sleep(1);
+ end;]';
+ end;
+
+ procedure cleanup_slow_down_insert_into_table_buffer is
+ pragma autonomous_transaction;
+ begin
+ execute immediate 'drop trigger ut3_develop.slow_down_buffer_insert';
+ exception when others then
+ if sqlcode <> -4080 then raise; end if;
+ end;
+
+ procedure run_as_job(a_job_action varchar2) is
+ l_job_name varchar2(50);
+ l_timestamp timestamp with time zone := current_timestamp;
+ pragma autonomous_transaction;
+ begin
+ l_job_name := 'utPLSQL__'||to_char(l_timestamp,'yyyymmddhh24missff');
+ dbms_scheduler.create_job(
+ job_name => l_job_name,
+ job_type => 'PLSQL_BLOCK',
+ job_action => a_job_action,
+ start_date => l_timestamp,
+ enabled => TRUE,
+ auto_drop => TRUE
+ );
+ end;
end;
/
diff --git a/test/ut3_tester_helper/run_helper.pks b/test/ut3_tester_helper/run_helper.pks
index ad0f615e5..6c5dd4a3b 100644
--- a/test/ut3_tester_helper/run_helper.pks
+++ b/test/ut3_tester_helper/run_helper.pks
@@ -74,5 +74,10 @@ create or replace package run_helper is
a_name varchar2 := null
) return sys_refcursor;
+ procedure slow_down_insert_into_table_buffer;
+
+ procedure cleanup_slow_down_insert_into_table_buffer;
+
+ procedure run_as_job(a_job_action varchar2);
end;
/
diff --git a/test/ut3_user/api/test_ut_run.pkb b/test/ut3_user/api/test_ut_run.pkb
index f0cfd8373..8c99af7d7 100644
--- a/test/ut3_user/api/test_ut_run.pkb
+++ b/test/ut3_user/api/test_ut_run.pkb
@@ -551,7 +551,7 @@ Failures:%
ORA-04068: existing state of packages (DB_LOOPBACK%) has been discarded
ORA-04061: existing state of package body "%.STATEFUL_PACKAGE" has been invalidated
ORA-04065: not executed, altered or dropped package body "%.STATEFUL_PACKAGE"%
- ORA-06512: at line 6%
+ ORA-06512: at line 7%
1 tests, 0 failed, 1 errored, 0 disabled, 0 warning(s)%';
--Act
@@ -854,7 +854,7 @@ Failures:%
l_results ut3_develop.ut_varchar2_list;
begin
select * bulk collect into l_random_results
- from table ( ut3_develop.ut.run( 'ut3_tester_helper.test_package_1', a_random_test_order_seed => 6 ) )
+ from table ( ut3_develop.ut.run( 'ut3_tester_helper.test_package_1', a_random_test_order_seed => 123 ) )
where trim(column_value) is not null and column_value not like 'Finished in %'
and column_value not like '%Tests were executed with random order %';
diff --git a/test/ut3_user/api/test_ut_runner.pkb b/test/ut3_user/api/test_ut_runner.pkb
index d665718e1..d35495c70 100644
--- a/test/ut3_user/api/test_ut_runner.pkb
+++ b/test/ut3_user/api/test_ut_runner.pkb
@@ -386,7 +386,6 @@ end;';
select 'UT3_DEVELOP.UT_DEBUG_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_COVERAGE_HTML_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_COVERAGE_SONAR_REPORTER', 'Y' from dual union all
- select 'UT3_DEVELOP.UT_COVERALLS_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_DOCUMENTATION_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_JUNIT_REPORTER', 'Y' from dual union all
select 'UT3_DEVELOP.UT_REALTIME_REPORTER', 'Y' from dual union all
diff --git a/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pkb b/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pkb
deleted file mode 100644
index e3806cd97..000000000
--- a/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pkb
+++ /dev/null
@@ -1,77 +0,0 @@
-create or replace package body test_coveralls_reporter is
-
- procedure report_on_file is
- l_expected clob;
- l_actual clob;
- l_file_path varchar2(250);
- begin
- --Arrange
- l_file_path := 'test/ut3_develop.'||ut3_tester_helper.coverage_helper.covered_package_name||'.pkb';
- l_expected := q'[{"source_files":[
-{ "name": "]'||l_file_path||q'[",
-"coverage": [
-null,
-null,
-null,
-3,
-null,
-0
-]
-}
-]}
- ]';
- l_actual :=
- ut3_tester_helper.coverage_helper.run_tests_as_job(
- q'[
- ut3_develop.ut.run(
- a_path => 'ut3_develop.test_dummy_coverage',
- a_reporter => ut3_develop.ut_coveralls_reporter( ),
- a_source_files => ut3_develop.ut_varchar2_list( ']'||l_file_path||q'[' ),
- a_test_files => ut3_develop.ut_varchar2_list( )
- )
- ]'
- );
- --Assert
- ut.expect(l_actual).to_equal(l_expected);
- end;
-
- procedure report_zero_coverage is
- l_expected clob;
- l_actual clob;
- begin
- --Arrange
- l_expected := q'[{"source_files":[
-{ "name": "package body ut3_develop.]'||ut3_tester_helper.coverage_helper.covered_package_name||q'[",
-"coverage": [
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0,
-0
-]
-}
-]}
- ]';
-
- --Act
- l_actual :=
- ut3_tester_helper.coverage_helper.run_tests_as_job(
- q'[
- ut3_develop.ut.run(
- 'ut3_develop.test_dummy_coverage.zero_coverage',
- ut3_develop.ut_coveralls_reporter(),
- a_include_objects => ut3_develop.ut_varchar2_list('UT3_DEVELOP.]'||ut3_tester_helper.coverage_helper.covered_package_name||q'[')
- )
- ]'
- );
- --Assert
- ut.expect(l_actual).to_equal(l_expected);
-
- end;
-
-end;
-/
diff --git a/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pks b/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pks
deleted file mode 100644
index d958b8f12..000000000
--- a/test/ut3_user/reporters/test_coverage/test_coveralls_reporter.pks
+++ /dev/null
@@ -1,13 +0,0 @@
-create or replace package test_coveralls_reporter is
-
- --%suite(ut_coveralls_reporter)
- --%suitepath(utplsql.test_user.reporters.test_coverage)
-
- --%test(reports on a project file mapped to database object)
- procedure report_on_file;
-
- --%test(reports zero coverage on each line of non-executed database object)
- procedure report_zero_coverage;
-
-end;
-/
diff --git a/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pkb b/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pkb
index f3aad5702..4b06f725f 100644
--- a/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pkb
+++ b/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pkb
@@ -207,5 +207,26 @@ create or replace package body test_proftab_coverage is
ut.expect(l_actual).to_be_like(coverage_helper.substitute_covered_package(l_expected));
end;
+ procedure no_issue_with_duplicate_source is
+ l_actual clob;
+ begin
+ --Act
+ l_actual :=
+ ut3_tester_helper.coverage_helper.run_tests_as_job(
+ coverage_helper.substitute_covered_package(
+ q'[
+ ut3_develop.ut.run(
+ 'ut3_develop.test_dummy_coverage.zero_coverage',
+ ut3_develop.ut_coverage_sonar_reporter(),
+ a_include_schema_expr =>'SYS'
+ )
+ ]'
+ )
+ );
+
+ --Running above line is successful if there is no exception thrown due to duplicate lines in coverage
+ ut.expect(l_actual).not_to_be_null();
+ end;
+
end;
/
diff --git a/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pks b/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pks
index 740862f86..fb1d0cfe3 100644
--- a/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pks
+++ b/test/ut3_user/reporters/test_coverage/test_proftab_coverage.pks
@@ -28,5 +28,8 @@ create or replace package test_proftab_coverage is
--%test(reports zero coverage on each line of non-executed database object - Issue #917)
procedure report_zero_coverage;
+ --%test(Allows reporting coverage on objects across SYS or MDSYS without errors - Issue #1323 )
+ procedure no_issue_with_duplicate_source;
+
end;
/
diff --git a/test/ut3_user/reporters/test_documentation_reporter.pkb b/test/ut3_user/reporters/test_documentation_reporter.pkb
index 016cec256..d9c5d48c8 100644
--- a/test/ut3_user/reporters/test_documentation_reporter.pkb
+++ b/test/ut3_user/reporters/test_documentation_reporter.pkb
@@ -38,7 +38,7 @@ Failures:
2) erroring_test
ORA-06502: PL/SQL: %: character to number conversion error
ORA-06512: at "UT3_USER.TEST_REPORTERS", line 44%
- ORA-06512: at line 6
+ ORA-06512: at line 7
Finished in % seconds
5 tests, 1 failed, 1 errored, 2 disabled, 0 warning(s)%]';
diff --git a/test/ut3_user/reporters/test_realtime_reporter.pkb b/test/ut3_user/reporters/test_realtime_reporter.pkb
index 84053c3c9..d4d83f7a3 100644
--- a/test/ut3_user/reporters/test_realtime_reporter.pkb
+++ b/test/ut3_user/reporters/test_realtime_reporter.pkb
@@ -410,7 +410,7 @@ create or replace package body test_realtime_reporter as
= 'realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error';
ut3_tester_helper.main_helper.append_to_list(l_expected_list, '');
+ ut3_tester_helper.main_helper.append_to_list(l_expected_list, '%ORA-06512: at line 7]]>');
l_expected := ut3_tester_helper.main_helper.table_to_clob(l_expected_list);
ut.expect(l_actual).to_be_like(l_expected);
end error_stack_of_test;
@@ -427,7 +427,7 @@ create or replace package body test_realtime_reporter as
= 'realtime_reporting.check_realtime_reporting3';
ut3_tester_helper.main_helper.append_to_list(l_expected_list, '');
+ ut3_tester_helper.main_helper.append_to_list(l_expected_list, '%ORA-06512: at line 7]]>');
l_expected := ut3_tester_helper.main_helper.table_to_clob(l_expected_list);
ut.expect(l_actual).to_be_like(l_expected);
end error_stack_of_testsuite;
diff --git a/test/ut3_user/reporters/test_tfs_junit_reporter.pkb b/test/ut3_user/reporters/test_tfs_junit_reporter.pkb
index 1036be2ba..105517763 100644
--- a/test/ut3_user/reporters/test_tfs_junit_reporter.pkb
+++ b/test/ut3_user/reporters/test_tfs_junit_reporter.pkb
@@ -100,7 +100,7 @@ create or replace package body test_tfs_junit_reporter as
--%displayname(Test in and out of context)
-- %context(incontext)
- -- %name(ProductincontextFeatures)
+ -- %name(Production_context_Features)
--%test(inctx)
--%displayname(inctx)
@@ -298,7 +298,7 @@ create or replace package body test_tfs_junit_reporter as
-
+