Skip to content

Releases: jbiter/citationer

v4.6.1 - Dedup year=None Fix

Choose a tag to compare

@github-actions github-actions released this 16 Jul 08:58

Dedup Fix

Fixed dedup engine wrongly merging records without year data.

Tests: 628 passing, coverage 80.83%.

v4.6.0 — Interactive Save

Choose a tag to compare

@github-actions github-actions released this 14 Jul 08:23

Interactive Save

Interactive wizard now saves real report files (was previously a placeholder).

Tests: 622 passing, coverage 80.80%.

v4.5.0 — Report Templates

Choose a tag to compare

@github-actions github-actions released this 14 Jul 07:28

Report Templates

New simple template: concise summary with top-5 authors/keywords and last 5 years. Academic template unchanged.

Tests: 610 passing, coverage 80.86%.

v4.4.0 — Funding Analysis

Choose a tag to compare

@github-actions github-actions released this 14 Jul 06:51

Funding Analysis

New citationer stats funding subcommand: funding rate, top-N funders, yearly trend.

Tests: 582 passing, coverage 80.81%.

v4.3.0 — Standalone Binary

Choose a tag to compare

@jbiter jbiter released this 10 Jul 09:33

Standalone Binary

PyInstaller-packaged executable for Linux, macOS, and Windows. Built automatically on tag push.

Tests: 562 passing.

v4.2.0 — Documentation Site

Choose a tag to compare

@jbiter jbiter released this 10 Jul 03:29

Documentation Site

MkDocs site deployed to GitHub Pages with changelog, command reference, and installation guide.

Bug Fixes

CI workflow fix for MkDocs build path.

Tests: 562 passing.

v4.1.2 — Bug Fixes

Choose a tag to compare

@jbiter jbiter released this 10 Jul 01:25

Bug Fixes

  • Fixed 4 outstanding bugs (#16, #17, #19, #20)
  • Improved round-trip integrity for bilingual records
  • Robust burst detection in trend analysis

Tests: 562 passing, coverage 80.65%.

v4.1.1 — Fix BUG-001 (db_loader crash)

Choose a tag to compare

@jbiter jbiter released this 10 Jul 01:00

v4.1.1 — Bug Fix Release

🐛 Fix: BUG-001 (Critical)

load_records_from_db() no longer crashes when records have NULL year or citation_count.

Root cause: SQLite stores nullable INTEGER columns as empty strings "" when not set. The loader passed these "" values directly to Pydantic's Record constructor, which expects int | None and rejected empty strings with int_parsing validation errors.

Impact: After importing any bibliographic file with incomplete metadata (missing year or citation count), all subsequent analysis commands (stats, text, network, trend) crashed.

Fix: Added _opt_int() helper in src/citationer/utils/db_loader.py:103-111 that converts empty strings, None, or whitespace-only strings to None before passing to Pydantic.

def _opt_int(value):
    if value is None:
        return None
    if isinstance(value, int):
        return value
    if value == "" or str(value).strip() == "":
        return None
    return value

✅ Regression Tests

3 new tests in tests/test_database.py::TestBug001Regression:

  • test_load_with_null_year — Pydantic Record accepts NULL year
  • test_load_with_empty_string_year — Manual SQL UPDATE sets int columns to NULL → load succeeds
  • test_round_trip_orphan_record — Full round-trip with all year/citation_count fields missing

📊 Status

  • Tests: 562 passing (was 559)
  • Coverage: 80.49% (CI gate 80% met)
  • Lint: ruff clean

🐞 Remaining Defects (not fixed in 4.1.1)

  • #16 BUG-002: Institution.name_en not serialized
  • #17 BUG-003: en/zh keywords not split on load
  • #19 BUG-004: trend baseline median polluted by burst
  • #20 BUG-005: trend strategy recomputes in second pass

Closes #15

v4.1.0 — Test Coverage 80% (P4-1 Complete)

Choose a tag to compare

@jbiter jbiter released this 09 Jul 09:53

v4.1.0 — Test Coverage 80% (P4-1 Complete)

🎯 Major Milestone

Test coverage increased from 35% → 80.51% (CI gate at 80% enforced). Test count grew from 153 to 559 passing tests.

📊 Coverage Breakdown

Newly tested modules (90-100% coverage)

  • utils/database.py: 70% → 100%
  • utils/serialization.py: 90% → 100%
  • utils/db_loader.py: 67% → 98%
  • analysis/trend.py: 15% → 93%
  • parsers/cnki.py: 19% → 93%
  • parsers/pubmed.py: 14% → 93%
  • parsers/wos.py: 40% → 92%
  • viz/charts.py: 0% → 89%
  • cli/help.py: 0% → 100%
  • cli/main.py: 0% → 92%

Test additions

  • 5 new test files for low-coverage CLI modules
  • 17 new test files total (excluding conftest)
  • Comprehensive conftest.py with shared fixtures
  • End-to-end CLI testing via Typer CliRunner

🐛 Defects Discovered (not fixed in this release)

Documented via GitHub issues, scheduled for v4.1.1 or v4.2.0:

# Severity Description
#15 🔴 Critical empty-string int fields crash db_loader
#16 🟠 Major Institution.name_en not serialized
#17 🟡 Minor en/zh keywords not split back on load
#19 🟠 Major trend baseline median polluted by burst
#20 🟢 Suggestion trend strategy recomputes in second pass

🔧 CI Improvements

  • Coverage gate: --cov-fail-under=80
  • All ruff checks pass (lint clean)
  • All 559 tests pass on Python 3.11/3.12

📦 Installation

pipx install citationer
# or
pip install citationer

🛠 Development

git clone https://github.com/jbiter/citationer.git
cd citationer
pip install -e ".[all,dev]"
pytest tests/ --cov=src/citationer