Skip to content

Commit deed31b

Browse files
committed
Bump version to 1.0.1; add changelog & tests
Update project for release 1.0.1: bump package version in gleam.toml and CI Gleam version (1.13.0 -> 1.14.0). Add a CHANGELOG.md documenting 1.0.1 and 1.0.0 entries. Improve docs for cmp.reverse and expand tests: make by_normalized_string_test use proper lowercase normalization and assert normalization changes results, add reverse_test to verify Lt/Gt inversion and Eq stability, and add chain_empty_test to assert chain([]) returns Eq.
1 parent f449665 commit deed31b

5 files changed

Lines changed: 85 additions & 6 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- uses: erlef/setup-beam@v1
1616
with:
1717
otp-version: "28"
18-
gleam-version: "1.13.0"
18+
gleam-version: "1.14.0"
1919
rebar3-version: "3"
2020
# elixir-version: "1"
2121
- run: gleam deps download

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.0.1] - 2026-03-20
9+
10+
### Fixed
11+
12+
- Improved `by_normalized_string` test: now uses a real normalizer (`string.lowercase`)
13+
and verifies that normalization actually changes the comparison result
14+
15+
### Added
16+
17+
- Test for `reverse/1`: covers `Lt↔Gt` inversion and `Eq` stability
18+
- Test for `chain/1` with empty list: verifies it always returns `Eq`
19+
- Expanded doc comment for `reverse/1` with example and explicit description of behaviour
20+
21+
## [1.0.0] - 2026-03-18
22+
23+
### Added
24+
25+
- `Comparator(a)` type alias (`fn(a, a) -> order.Order`)
26+
- Basic comparators: `natural_int/2`, `natural_string/2`, `natural_float/2`
27+
- Contramap helpers: `by/2`, `by_int/1`, `by_string/1`, `by_float/1`,
28+
`by_string_with/2`, `by_normalized_string/3`
29+
- Composition: `then/2`, `chain/1`, `lazy_then/2`, `reverse/1`
30+
- Container comparators: `option/2`, `pair/2`, `triple/3`, `list_compare/1`
31+
- Full test suite with gleeunit
32+
- README with design philosophy, usage examples, and Unicode normalization guide
33+
34+
[1.0.1]: https://github.com/lupodevelop/cmp/compare/v1.0.0...v1.0.1
35+
[1.0.0]: https://github.com/lupodevelop/cmp/releases/tag/v1.0.0

gleam.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "cmp_gleam"
2-
version = "1.0.0"
2+
version = "1.0.1"
33

44
# Fill out these fields if you intend to generate HTML documentation or publish
55
# your project to the Hex package manager.

src/cmp.gleam

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ pub fn natural_int(a: Int, b: Int) -> order.Order {
1515
}
1616

1717
/// Reverse the ordering produced by `comp`.
18-
/// Delegates to `order.reverse` for correctness.
18+
/// `Lt` becomes `Gt`, `Gt` becomes `Lt`, `Eq` stays `Eq`.
19+
/// Delegates to `order.reverse` from stdlib.
20+
///
21+
/// Example:
22+
///
23+
/// ```gleam
24+
/// let desc = cmp.reverse(cmp.by_int(fn(u) { u.age }))
25+
/// list.sort(users, by: desc)
26+
/// ```
1927
pub fn reverse(comp: Comparator(a)) -> Comparator(a) {
2028
order.reverse(comp)
2129
}

test/cmp_gleam_test.gleam

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,24 @@ pub fn by_string_with_test() {
8888
pub fn by_normalized_string_test() {
8989
let u1 = #("A", 1)
9090
let u2 = #("a", 2)
91+
let u3 = #("B", 3)
9192
let key = fn(u) {
9293
case u {
9394
#(name, _) -> name
9495
}
9596
}
96-
// Normalizer that maps any string to the same value -> equal
97-
let normalize = fn(_s) { "x" }
98-
let c = cmp.by_normalized_string(key, normalize, string.compare)
97+
// Normalizer that folds to lowercase: "A" == "a" -> Eq
98+
let to_lower = string.lowercase
99+
let c = cmp.by_normalized_string(key, to_lower, string.compare)
99100
assert c(u1, u2) == order.Eq
101+
102+
// Without normalization "A" < "a" (uppercase < lowercase in unicode),
103+
// but after lowercasing "a" == "a" -> Eq; confirms normalization changes result
104+
assert string.compare("A", "a") != order.Eq
105+
106+
// Normalization still orders different values correctly: "a" < "b"
107+
assert c(u1, u3) == order.Lt
108+
assert c(u3, u1) == order.Gt
100109
}
101110

102111
pub fn chain_test() {
@@ -205,6 +214,33 @@ pub fn triple_test() {
205214
assert t_cmp(a, c) == order.Gt
206215
}
207216

217+
pub fn reverse_test() {
218+
let asc = cmp.by_int(fn(u) {
219+
case u {
220+
#(_, age) -> age
221+
}
222+
})
223+
let desc = cmp.reverse(asc)
224+
225+
let u1 = #("Alice", 30)
226+
let u2 = #("Bob", 25)
227+
228+
// ascending: 30 > 25
229+
assert asc(u1, u2) == order.Gt
230+
// reversed: 30 < 25
231+
assert desc(u1, u2) == order.Lt
232+
assert desc(u2, u1) == order.Gt
233+
234+
// equal values stay Eq after reverse
235+
assert desc(u1, u1) == order.Eq
236+
}
237+
238+
pub fn chain_empty_test() {
239+
let c = cmp.chain([])
240+
assert c(1, 2) == order.Eq
241+
assert c(42, 42) == order.Eq
242+
}
243+
208244
pub fn natural_float_test() {
209245
assert cmp.natural_float(1.2, 2.3) == order.Lt
210246
assert cmp.natural_float(2.3, 1.2) == order.Gt

0 commit comments

Comments
 (0)