Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
name: Build

on:
pull_request:
branches:
- '**'
types: [ opened, synchronize, reopened ]
# pull_request:
# branches:
# - '**'
# types: [ opened, synchronize, reopened ]
workflow_dispatch:

jobs:
test:
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/check_pr_release_notes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
name: Check PR Release Notes

on:
pull_request:
types: [opened, synchronize, reopened, edited, labeled, unlabeled]
branches: [ master ]
# pull_request:
# types: [opened, synchronize, reopened, edited, labeled, unlabeled]
# branches: [ master ]
workflow_dispatch:

env:
SKIP_LABEL: 'no RN'
Expand Down
31 changes: 23 additions & 8 deletions .github/workflows/jacoco_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ jobs:
with:
java-version: "adopt@1.8"

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.14"

- name: Setup database
run: |
psql postgresql://postgres:postgres@localhost:5432/mag_db -f balta/src/test/resources/db/postgres/02_users.ddl
Expand All @@ -93,19 +98,29 @@ jobs:
id: jacocorun
run: sbt jacoco

# - name: Check coverage thresholds and add reports in PR comments
# id: jacoco
# uses: MoranaApps/jacoco-report@master
# with:
# token: '${{ secrets.GITHUB_TOKEN }}'
# paths: |
# balta/target/**/jacoco-report/jacoco.xml
# sensitivity: "detail"
# comment-mode: 'single'
# min-coverage-overall: ${{ env.coverage-overall }}
# min-coverage-changed-files: ${{ env.coverage-changed-files }}
# min-coverage-per-changed-file: ${{ env.coverage-per-changed-file }}
# skip-unchanged: false

- name: Check coverage thresholds and add reports in PR comments
id: jacoco
uses: MoranaApps/jacoco-report@54bfe284d1119dc917dddba80517c54c5bcf3627
uses: MoranaApps/jacoco-report@master
with:
token: '${{ secrets.GITHUB_TOKEN }}'
paths: |
balta/target/**/jacoco-report/jacoco.xml
sensitivity: "detail"
comment-mode: 'single'
min-coverage-overall: ${{ env.coverage-overall }}
min-coverage-changed-files: ${{ env.coverage-changed-files }}
min-coverage-per-changed-file: ${{ env.coverage-per-changed-file }}
skip-unchanged: false
**/jacoco.xml
global-thresholds: '${{ env.coverage-overall }}*${{ env.coverage-changed-files }}*${{ env.coverage-per-changed-file }}'
fail-on-threshold: ''

noop:
name: No Operation
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/test_filenames_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
name: Test Filenames Check

on:
pull_request:
branches: [ master ]
types: [ opened, synchronize, reopened ]
# pull_request:
# branches: [ master ]
# types: [ opened, synchronize, reopened ]
workflow_dispatch:

jobs:
test_filenames_check:
Expand Down
36 changes: 36 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,39 @@ lazy val balta = (project in file("balta"))
jmfReportFile := Some(target.value / "jmf-report.json"),
jmfReportFormat := "json",
)

lazy val calculator = (project in file("calculator"))
.enablePlugins(JacocoFilterPlugin)
.settings(
name := "balta-calculator",
scalacOptions ++= Seq(
"-deprecation",
"-feature",
),
crossScalaVersions := supportedScalaVersions,
libraryDependencies += "org.scalatest" %% "scalatest" % Versions.scalatest % Test,
)

lazy val validator = (project in file("validator"))
.enablePlugins(JacocoFilterPlugin)
.settings(
name := "balta-validator",
scalacOptions ++= Seq(
"-deprecation",
"-feature",
),
crossScalaVersions := supportedScalaVersions,
libraryDependencies += "org.scalatest" %% "scalatest" % Versions.scalatest % Test,
)

lazy val formatter = (project in file("formatter"))
.enablePlugins(JacocoFilterPlugin)
.settings(
name := "balta-formatter",
scalacOptions ++= Seq(
"-deprecation",
"-feature",
),
crossScalaVersions := supportedScalaVersions,
libraryDependencies += "org.scalatest" %% "scalatest" % Versions.scalatest % Test,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2023 ABSA Group Limited
*
* 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.
*/

package za.co.absa.db.balta.calculator

/**
* Simple arithmetic calculator used to produce measurable JaCoCo coverage data.
*/
class Calculator {

/**
* Returns the sum of two integers.
* @param a first operand
* @param b second operand
* @return a + b
*/
def add(a: Int, b: Int): Int = a + b

/**
* Returns the difference of two integers.
* @param a first operand
* @param b second operand
* @return a - b
*/
def subtract(a: Int, b: Int): Int = a - b

/**
* Returns the product of two integers.
* @param a first operand
* @param b second operand
* @return a * b
*/
def multiply(a: Int, b: Int): Int = a * b

/**
* Returns the integer quotient of a divided by b.
* @param a dividend
* @param b divisor; must not be zero
* @return a / b
* @throws ArithmeticException if b is zero
*/
def divide(a: Int, b: Int): Int = {
if (b == 0) throw new ArithmeticException("Division by zero")
a / b
}

/**
* Returns the absolute value of an integer.
* @param a input value
* @return non-negative value of a
*/
def abs(a: Int): Int = if (a < 0) -a else a

/**
* Returns the larger of two integers.
* @param a first value
* @param b second value
* @return the maximum of a and b
*/
def max(a: Int, b: Int): Int = if (a >= b) a else b
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2023 ABSA Group Limited
*
* 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.
*/

package za.co.absa.db.balta.calculator

import org.scalatest.funsuite.AnyFunSuite

class CalculatorUnitTests extends AnyFunSuite {

private val calc = new Calculator

test("add returns the sum of two positive integers") {
assert(calc.add(3, 4) == 7)
}

test("add returns the sum when one operand is negative") {
assert(calc.add(-2, 5) == 3)
}

// test("subtract returns the difference of two integers") {
// assert(calc.subtract(10, 4) == 6)
// }

// test("subtract returns negative result when b is greater than a") {
// assert(calc.subtract(2, 9) == -7)
// }

// test("multiply returns the product of two integers") {
// assert(calc.multiply(3, 7) == 21)
// }

// test("multiply returns zero when one operand is zero") {
// assert(calc.multiply(0, 99) == 0)
// }

test("divide returns the integer quotient") {
assert(calc.divide(10, 2) == 5)
}

test("divide throws ArithmeticException when divisor is zero") {
intercept[ArithmeticException] {
calc.divide(5, 0)
}
}

// test("abs returns the same value for a positive integer") {
// assert(calc.abs(7) == 7)
// }

// test("abs returns the negated value for a negative integer") {
// assert(calc.abs(-7) == 7)
// }

// test("abs returns zero for zero input") {
// assert(calc.abs(0) == 0)
// }

test("max returns the first value when it is greater") {
assert(calc.max(9, 3) == 9)
}

test("max returns the second value when it is greater") {
assert(calc.max(3, 9) == 9)
}

test("max returns the common value when both are equal") {
assert(calc.max(5, 5) == 5)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2023 ABSA Group Limited
*
* 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.
*/

package za.co.absa.db.balta.formatter

/**
* String formatter used to produce measurable JaCoCo coverage data.
*/
class Formatter {

/**
* Capitalizes the first character of a string, leaving the rest unchanged.
* Returns the input unchanged when it is null or empty.
* @param s input string
* @return string with the first character uppercased
*/
def capitalize(s: String): String = {
if (s == null || s.isEmpty) s
else s.head.toUpper + s.tail
}

/**
* Truncates a string to at most maxLen characters, appending "..." when truncation occurs.
* @param s input string
* @param maxLen maximum allowed length before truncation
* @return the original string or its prefix followed by "..."
*/
def truncate(s: String, maxLen: Int): String = {
if (s.length <= maxLen) s
else s.take(maxLen) + "..."
}

/**
* Wraps a string with a prefix and suffix.
* @param s input string
* @param prefix string prepended to s
* @param suffix string appended to s
* @return prefix + s + suffix
*/
def wrap(s: String, prefix: String, suffix: String): String = s"$prefix$s$suffix"

/**
* Repeats a string a given number of times.
* Returns an empty string when times is zero or negative.
* @param s string to repeat
* @param times number of repetitions
* @return concatenation of s repeated times
*/
def repeat(s: String, times: Int): String = {
if (times <= 0) ""
else s * times
}
}
Loading
Loading