Skip to content

Commit 4281cb4

Browse files
authored
Initial commit
Initial commit
2 parents f0887b8 + 649f552 commit 4281cb4

19 files changed

Lines changed: 1806 additions & 2 deletions

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: CI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
# branches:
7+
# - main
8+
# - feature/*
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
python-version: ["3.13", "3.12", "3.11", "3.10", "3.9"]
16+
steps:
17+
- uses: actions/checkout@v5
18+
- name: Set up Python ${{ matrix.python-version }}
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Run tests
23+
run: python -m unittest discover test

.github/workflows/deploy-docs.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Deploy docs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- mkdocs.yml
9+
- docs/**
10+
11+
permissions:
12+
contents: read
13+
actions: read
14+
pages: write
15+
id-token: write
16+
17+
concurrency:
18+
group: "pages"
19+
cancel-in-progress: false
20+
21+
jobs:
22+
build-and-deploy:
23+
name: Build and deploy
24+
runs-on: ubuntu-latest
25+
environment:
26+
name: github-pages
27+
url: ${{ steps.deployment.outputs.page_url }}
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
- name: Build documentation
32+
run: docker run -v ${PWD}:/docs squidfunk/mkdocs-material build
33+
- name: Setup Pages
34+
uses: actions/configure-pages@v4
35+
- name: Upload artifact
36+
uses: actions/upload-pages-artifact@v3
37+
with:
38+
path: site
39+
- name: Deploy to GitHub Pages
40+
id: deployment
41+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
.env
3+
.idea/
4+
.vscode/
5+
__pycache__

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased](https://github.com/nationalarchives/tna-frontend-jinja/compare/v0.0.1...HEAD)
9+
10+
### Added
11+
### Changed
12+
### Deprecated
13+
### Removed
14+
### Fixed
15+
### Security

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
# python-utilities
2-
A library of common National Archives Python functions
1+
# National Archives Python Utilities
2+
3+
A library of common National Archives Python functions.
4+
5+
```sh
6+
# Run the tests
7+
python -m unittest discover test
8+
9+
# Format the code
10+
./tasks/format.sh
11+
```

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TNA Python Utilities

mkdocs.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
site_name: TNA Python Utilities Docs
2+
repo_url: https://github.com/nationalarchives/python-utilities
3+
theme:
4+
name: material
5+
favicon: https://raw.githubusercontent.com/nationalarchives/tna-frontend/main/src/nationalarchives/assets/images/favicon.ico
6+
features:
7+
- navigation.indexes
8+
plugins:
9+
- search
10+
markdown_extensions:
11+
- pymdownx.superfences:
12+
custom_fences:
13+
- name: mermaid
14+
class: mermaid
15+
format: !!python/name:pymdownx.superfences.fence_code_format

setup.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import setuptools
2+
3+
with open("README.md", "r", encoding="utf-8") as fh:
4+
long_description = fh.read()
5+
6+
setuptools.setup(
7+
name="tna-utilities",
8+
version="0.0.1",
9+
author="Andrew Hosgood",
10+
author_email="andrew.hosgood@nationalarchives.gov.uk",
11+
description="A library of common National Archives Python functions",
12+
long_description=long_description,
13+
long_description_content_type="text/markdown",
14+
url="https://github.com/nationalarchives/python-utilities",
15+
project_urls={
16+
"Bug Tracker": "https://github.com/nationalarchives/python-utilities/issues",
17+
},
18+
classifiers=[
19+
"Programming Language :: Python :: 3",
20+
"License :: OSI Approved :: MIT License",
21+
"Operating System :: OS Independent",
22+
"Environment :: Web Environment",
23+
"Intended Audience :: Developers",
24+
],
25+
packages=["tna_utilities"],
26+
# package_data={
27+
# "": ["**/*.py", "**/*.html"],
28+
# },
29+
python_requires=">=3.9",
30+
)

tasks/format.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
docker run --rm -v "$(pwd)":/app/ ghcr.io/nationalarchives/tna-python-dev:latest format

test/test_currency.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import unittest
2+
3+
from tna_utilities.currency import currency, pretty_price, pretty_price_range
4+
5+
6+
class TestCurrency(unittest.TestCase):
7+
def test_happy_number(self):
8+
self.assertEqual(currency(0), "0")
9+
self.assertEqual(currency(5), "5")
10+
self.assertEqual(currency(5.0), "5")
11+
self.assertEqual(currency(5.00), "5")
12+
self.assertEqual(currency(5.1), "5.10")
13+
self.assertEqual(currency(5.01), "5.01")
14+
self.assertEqual(currency(5.001), "5.00")
15+
self.assertEqual(currency(5.005), "5.00")
16+
self.assertEqual(currency(5.006), "5.01")
17+
18+
def test_happy_string(self):
19+
self.assertEqual(currency("0"), "0")
20+
self.assertEqual(currency("5"), "5")
21+
self.assertEqual(currency("5.0"), "5")
22+
self.assertEqual(currency("5.00"), "5")
23+
self.assertEqual(currency("5.1"), "5.10")
24+
self.assertEqual(currency("5.01"), "5.01")
25+
self.assertEqual(currency("5.001"), "5.00")
26+
self.assertEqual(currency("5.005"), "5.00")
27+
self.assertEqual(currency("5.006"), "5.01")
28+
29+
def test_happy_not_simplified(self):
30+
self.assertEqual(currency("0", False), "0.00")
31+
self.assertEqual(currency("5", False), "5.00")
32+
self.assertEqual(currency("5.0", False), "5.00")
33+
self.assertEqual(currency("5.00", False), "5.00")
34+
35+
36+
class TestPrettyPrice(unittest.TestCase):
37+
def test_happy_number(self):
38+
self.assertEqual(pretty_price(0), "Free")
39+
self.assertEqual(pretty_price(0.1), "£0.10")
40+
self.assertEqual(pretty_price(0.101), "£0.10")
41+
self.assertEqual(pretty_price(0.001), "Free")
42+
self.assertEqual(pretty_price(0.009), "£0.01")
43+
self.assertEqual(pretty_price(1), "£1")
44+
self.assertEqual(pretty_price(1.1), "£1.10")
45+
self.assertEqual(pretty_price(1.11), "£1.11")
46+
self.assertEqual(pretty_price(1.111), "£1.11")
47+
self.assertEqual(pretty_price(123456789), "£123,456,789")
48+
self.assertEqual(pretty_price(123456789.01), "£123,456,789.01")
49+
50+
def test_happy_string(self):
51+
self.assertEqual(pretty_price("0"), "Free")
52+
self.assertEqual(pretty_price("0.1"), "£0.10")
53+
self.assertEqual(pretty_price("0.10"), "£0.10")
54+
self.assertEqual(pretty_price("0.101"), "£0.10")
55+
self.assertEqual(pretty_price("0.001"), "Free")
56+
self.assertEqual(pretty_price("0.009"), "£0.01")
57+
self.assertEqual(pretty_price("1"), "£1")
58+
self.assertEqual(pretty_price("01"), "£1")
59+
self.assertEqual(pretty_price("1.1"), "£1.10")
60+
self.assertEqual(pretty_price("1.11"), "£1.11")
61+
self.assertEqual(pretty_price("1.111"), "£1.11")
62+
self.assertEqual(pretty_price("123456789"), "£123,456,789")
63+
self.assertEqual(pretty_price("123456789.01"), "£123,456,789.01")
64+
65+
def test_happy_not_simplified(self):
66+
self.assertEqual(pretty_price("0", False), "Free")
67+
self.assertEqual(pretty_price("0.1"), "£0.10")
68+
self.assertEqual(pretty_price("0.10"), "£0.10")
69+
self.assertEqual(pretty_price("0.101"), "£0.10")
70+
self.assertEqual(pretty_price("0.001"), "Free")
71+
self.assertEqual(pretty_price("0.009"), "£0.01")
72+
self.assertEqual(pretty_price("5", False), "£5.00")
73+
self.assertEqual(pretty_price("5.0", False), "£5.00")
74+
self.assertEqual(pretty_price("5.00", False), "£5.00")
75+
76+
77+
class TestPrettyPriceRange(unittest.TestCase):
78+
def test_happy(self):
79+
self.assertEqual(pretty_price_range(0, 0), "Free")
80+
self.assertEqual(pretty_price_range("0", "0"), "Free")
81+
self.assertEqual(pretty_price_range(5, 5), "£5")
82+
self.assertEqual(pretty_price_range("5", 5), "£5")
83+
self.assertEqual(pretty_price_range(5, "5"), "£5")
84+
self.assertEqual(pretty_price_range("5", "5"), "£5")
85+
self.assertEqual(pretty_price_range(5.1, 5.1), "£5.10")
86+
self.assertEqual(pretty_price_range(0, 5), "Free to £5")
87+
self.assertEqual(pretty_price_range(None, 5), "Free to £5")
88+
self.assertEqual(pretty_price_range(5, 0), "From £5")
89+
self.assertEqual(pretty_price_range(5, 10), "£5 to £10")
90+
self.assertEqual(pretty_price_range(10, 5), "£5 to £10")
91+
with self.assertRaises(ValueError):
92+
pretty_price_range("5", "a")
93+
pretty_price_range("5", [])
94+
pretty_price_range("5", True)

0 commit comments

Comments
 (0)