From e10b1e20111d13ed448c9026560230645ad493c7 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Tue, 21 Jul 2026 13:54:13 +0530 Subject: [PATCH 1/8] step2: upload coverage reports to Codecov --- .github/workflows/api.yml | 21 +++++++++++++++++++ api/app.py | 35 +++++++++++++++++++++++++++++++ api/calculator/__init__.py | 0 api/calculator/calculator.py | 14 +++++++++++++ api/calculator/test_calculator.py | 30 ++++++++++++++++++++++++++ api/requirements.txt | 3 +++ 6 files changed, 103 insertions(+) create mode 100644 .github/workflows/api.yml create mode 100644 api/app.py create mode 100644 api/calculator/__init__.py create mode 100644 api/calculator/calculator.py create mode 100644 api/calculator/test_calculator.py create mode 100644 api/requirements.txt diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml new file mode 100644 index 00000000..565c13eb --- /dev/null +++ b/.github/workflows/api.yml @@ -0,0 +1,21 @@ +name: API workflow + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + name: Test python API + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v2 + with: + python-version: '3.10' + - name: Install requirements + run: pip install -r api/requirements.txt + - name: Run tests and collect coverage + run: pytest --cov=api.calculator --cov-report=xml + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v5 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/api/app.py b/api/app.py new file mode 100644 index 00000000..d91792d1 --- /dev/null +++ b/api/app.py @@ -0,0 +1,35 @@ +from flask import ( + Flask, + request, +) + +from calculator.calculator import Calculator + +app = Flask(__name__) + +@app.route('/api/add', methods=['POST']) +def add(): + return operation('add', 2) + +@app.route('/api/subtract', methods=['POST']) +def subtract(): + return operation('subtract', 2) + +@app.route('/api/multiply', methods=['POST']) +def multiply(): + return operation('multiply', 2) + +@app.route('/api/divide', methods=['POST']) +def divide(): + return operation('divide', 2) + +def operation(method, num_factors): + factors = [] + if num_factors == 2: + factors.append(float(request.json.get('x'))) + factors.append(float(request.json.get('y'))) + + return str(getattr(Calculator, method)(*factors)) + + +app.run(host='0.0.0.0', port=8080) \ No newline at end of file diff --git a/api/calculator/__init__.py b/api/calculator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/api/calculator/calculator.py b/api/calculator/calculator.py new file mode 100644 index 00000000..eac4e7ac --- /dev/null +++ b/api/calculator/calculator.py @@ -0,0 +1,14 @@ +class Calculator: + def add(x, y): + return x + y + + def subtract(x, y): + return x - y + + def multiply(x, y): + return x * y + + def divide(x, y): + if y == 0: + return 'Cannot divide by 0' + return x * 1.0 / y \ No newline at end of file diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py new file mode 100644 index 00000000..69fa778f --- /dev/null +++ b/api/calculator/test_calculator.py @@ -0,0 +1,30 @@ +from .calculator import Calculator + + +def test_add(): + assert Calculator.add(1, 2) == 3.0 + assert Calculator.add(1.0, 2.0) == 3.0 + assert Calculator.add(0, 2.0) == 2.0 + assert Calculator.add(2.0, 0) == 2.0 + assert Calculator.add(-4, 2.0) == -2.0 + +def test_subtract(): + assert Calculator.subtract(1, 2) == -1.0 + assert Calculator.subtract(2, 1) == 1.0 + assert Calculator.subtract(1.0, 2.0) == -1.0 + assert Calculator.subtract(0, 2.0) == -2.0 + assert Calculator.subtract(2.0, 0.0) == 2.0 + assert Calculator.subtract(-4, 2.0) == -6.0 + +def test_multiply(): + assert Calculator.multiply(1, 2) == 2.0 + assert Calculator.multiply(1.0, 2.0) == 2.0 + assert Calculator.multiply(0, 2.0) == 0.0 + assert Calculator.multiply(2.0, 0.0) == 0.0 + assert Calculator.multiply(-4, 2.0) == -8.0 + +def test_divide(): + assert Calculator.divide(1, 2) == 0.5 + assert Calculator.divide(1.0, 2.0) == 0.5 + assert Calculator.divide(0, 2.0) == 0 + assert Calculator.divide(-4, 2.0) == -2.0 \ No newline at end of file diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 00000000..cae20d9e --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,3 @@ +flask +pytest +pytest-cov From 59a868fd91e629e1470f19aa9321f305dc1659a9 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Tue, 21 Jul 2026 14:12:41 +0530 Subject: [PATCH 2/8] step3: add project status check target --- codecov.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..b6ac064f --- /dev/null +++ b/codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + project: + default: + target: 100% + threshold: 1% \ No newline at end of file From 700e40e2aba58df56a7dd6fb0385dc0a94c99625 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Tue, 21 Jul 2026 14:23:33 +0530 Subject: [PATCH 3/8] step3: cover divide by 0 case --- api/calculator/test_calculator.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py index 69fa778f..c89e808c 100644 --- a/api/calculator/test_calculator.py +++ b/api/calculator/test_calculator.py @@ -27,4 +27,8 @@ def test_divide(): assert Calculator.divide(1, 2) == 0.5 assert Calculator.divide(1.0, 2.0) == 0.5 assert Calculator.divide(0, 2.0) == 0 - assert Calculator.divide(-4, 2.0) == -2.0 \ No newline at end of file + assert Calculator.divide(-4, 2.0) == -2.0 + + +def test_divide_by_0(): + assert Calculator.divide(2.0, 0) == 'Cannot divide by 0' \ No newline at end of file From f8bc67e1afc4c36d8bff539ede381237ae009bf5 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Tue, 21 Jul 2026 14:29:09 +0530 Subject: [PATCH 4/8] step3: customize Codecov PR comment layout --- codecov.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index b6ac064f..e515868d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,4 +3,8 @@ coverage: project: default: target: 100% - threshold: 1% \ No newline at end of file + threshold: 1% + +comment: + layout: "header, diff, files, footer" + hide_project_coverage: false \ No newline at end of file From e09de4370bb4fc4106a7602f4a0806bb5875a282 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Tue, 21 Jul 2026 14:38:35 +0530 Subject: [PATCH 5/8] step3: use legacy Codecov comment layout and update test --- api/calculator/test_calculator.py | 2 +- codecov.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py index c89e808c..de45889e 100644 --- a/api/calculator/test_calculator.py +++ b/api/calculator/test_calculator.py @@ -9,7 +9,7 @@ def test_add(): assert Calculator.add(-4, 2.0) == -2.0 def test_subtract(): - assert Calculator.subtract(1, 2) == -1.0 + assert Calculator.subtract(2, 2) == 0 assert Calculator.subtract(2, 1) == 1.0 assert Calculator.subtract(1.0, 2.0) == -1.0 assert Calculator.subtract(0, 2.0) == -2.0 diff --git a/codecov.yml b/codecov.yml index e515868d..22fb8981 100644 --- a/codecov.yml +++ b/codecov.yml @@ -6,5 +6,5 @@ coverage: threshold: 1% comment: - layout: "header, diff, files, footer" + layout: "newheader, diff, files, newfooter" hide_project_coverage: false \ No newline at end of file From 86bac3c9f051ee9bc98d8717ffe04dbd2c0d3773 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Wed, 22 Jul 2026 12:51:28 +0530 Subject: [PATCH 6/8] test: verify Codecov from last known working baseline Branch from e09de43 (PR #5) with the exact workflow that previously produced codecov/patch success. Do not merge until Codecov works. Co-authored-by: Cursor --- api/calculator/test_calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py index de45889e..079973d1 100644 --- a/api/calculator/test_calculator.py +++ b/api/calculator/test_calculator.py @@ -31,4 +31,5 @@ def test_divide(): def test_divide_by_0(): - assert Calculator.divide(2.0, 0) == 'Cannot divide by 0' \ No newline at end of file + assert Calculator.divide(2.0, 0) == 'Cannot divide by 0' +# codecov baseline test From 033f16b087354bf527c89c82b80fe4a7b85d24e1 Mon Sep 17 00:00:00 2001 From: Ayush Nirankari Date: Wed, 5 Aug 2026 16:11:36 +0530 Subject: [PATCH 7/8] test: add power and modulo methods to exercise patch coverage power is covered by a new test; modulo is intentionally left untested so the local Codecov instance reports a partial patch coverage figure. Co-authored-by: Cursor --- api/calculator/calculator.py | 10 +++++++++- api/calculator/test_calculator.py | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/api/calculator/calculator.py b/api/calculator/calculator.py index eac4e7ac..dc7ca10c 100644 --- a/api/calculator/calculator.py +++ b/api/calculator/calculator.py @@ -11,4 +11,12 @@ def multiply(x, y): def divide(x, y): if y == 0: return 'Cannot divide by 0' - return x * 1.0 / y \ No newline at end of file + return x * 1.0 / y + + def power(x, y): + return x ** y + + def modulo(x, y): + if y == 0: + return 'Cannot modulo by 0' + return x % y \ No newline at end of file diff --git a/api/calculator/test_calculator.py b/api/calculator/test_calculator.py index 079973d1..72656d2d 100644 --- a/api/calculator/test_calculator.py +++ b/api/calculator/test_calculator.py @@ -32,4 +32,9 @@ def test_divide(): def test_divide_by_0(): assert Calculator.divide(2.0, 0) == 'Cannot divide by 0' + + +def test_power(): + assert Calculator.power(2, 3) == 8 + assert Calculator.power(5, 0) == 1 # codecov baseline test From f7862376a5f318e4513aeb5e677b41b63191fd33 Mon Sep 17 00:00:00 2001 From: local-probe Date: Thu, 6 Aug 2026 10:55:55 +0530 Subject: [PATCH 8/8] chore: local probe commit for PR upload path --- api/calculator/calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/calculator/calculator.py b/api/calculator/calculator.py index dc7ca10c..fc061a99 100644 --- a/api/calculator/calculator.py +++ b/api/calculator/calculator.py @@ -19,4 +19,5 @@ def power(x, y): def modulo(x, y): if y == 0: return 'Cannot modulo by 0' - return x % y \ No newline at end of file + return x % y +# local-codecov-pr-probe