Count the other progress bar too
Double-tapping the year bar asks for a birth year and a life expectancy, and a second bar appears below measuring one against the other. Tab moves between the two, Enter commits the pair, Escape drops them. Hovering the bar names the thing, and double-tapping it puts it away again. A birth year rather than an age, so the bar keeps counting on its own instead of going stale the moment it is entered. Expectancy defaults to ninety and falls back to it when what is entered makes no sense, so the bar always has something to measure against; a birth year that makes no sense leaves the bar hidden instead, which is also where it starts. Putting the bar away keeps the expectancy, so setting a birth year again brings your own number back rather than the default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cc4771fd91
commit
9e3da4e27f
@@ -40,6 +40,45 @@ assertEqual(calendar.yearProgressPercent(2026, 0, 1), 0, 'calendar starts the ye
|
||||
assertEqual(calendar.yearProgressPercent(2026, 6, 26), 56, 'calendar reports the share of the year behind you')
|
||||
assertEqual(calendar.yearProgressPercent(2026, 11, 31), 100, 'calendar finishes the year at a hundred percent')
|
||||
assertEqual(calendar.yearProgressPercent(2024, 11, 31), 100, 'calendar finishes a leap year too')
|
||||
|
||||
// ---- memento mori
|
||||
// A birth year rather than an age, so the bar keeps counting on its own.
|
||||
assertEqual(calendar.parseBirthYear('1979', 2026), 1979, 'calendar reads a birth year')
|
||||
assertEqual(calendar.parseBirthYear(1979, 2026), 1979, 'calendar reads a numeric birth year')
|
||||
assertEqual(calendar.parseBirthYear(' 1979 ', 2026), 1979, 'calendar trims a birth year')
|
||||
assertEqual(calendar.parseBirthYear('2026', 2026), 2026, 'calendar accepts the current year')
|
||||
assertEqual(calendar.parseBirthYear('2027', 2026), 0, 'calendar rejects a birth year in the future')
|
||||
assertEqual(calendar.parseBirthYear('1905', 2026), 0, 'calendar rejects an implausibly distant birth year')
|
||||
assertEqual(calendar.parseBirthYear('79', 2026), 0, 'calendar rejects a two-digit year')
|
||||
assertEqual(calendar.parseBirthYear('', 2026), 0, 'calendar treats a blank birth year as unset')
|
||||
assertEqual(calendar.parseBirthYear('abc', 2026), 0, 'calendar treats a non-numeric birth year as unset')
|
||||
|
||||
assertEqual(calendar.ageFromBirthYear('1979', 2026), 47, 'calendar derives an age from a birth year')
|
||||
assertEqual(calendar.ageFromBirthYear('1979', 2027), 48, 'calendar keeps counting as the years pass')
|
||||
assertEqual(calendar.ageFromBirthYear('2026', 2026), 0, 'calendar makes someone born this year zero')
|
||||
assertEqual(calendar.ageFromBirthYear('', 2026), 0, 'calendar derives no age without a birth year')
|
||||
|
||||
assertEqual(calendar.parseAge('47'), 47, 'calendar reads an age')
|
||||
assertEqual(calendar.parseAge(47), 47, 'calendar reads a numeric age')
|
||||
assertEqual(calendar.parseAge(' 47 '), 47, 'calendar trims an age')
|
||||
assertEqual(calendar.parseAge(''), 0, 'calendar treats a blank age as unset')
|
||||
assertEqual(calendar.parseAge('0'), 0, 'calendar treats zero as unset')
|
||||
assertEqual(calendar.parseAge('-3'), 0, 'calendar treats a negative age as unset')
|
||||
assertEqual(calendar.parseAge('121'), 0, 'calendar treats an implausible age as unset')
|
||||
assertEqual(calendar.parseAge('abc'), 0, 'calendar treats a non-numeric age as unset')
|
||||
assertEqual(calendar.parseAge('4.5'), 0, 'calendar treats a fractional age as unset')
|
||||
assertEqual(calendar.parseLifeExpectancy('65'), 65, 'calendar reads a life expectancy')
|
||||
assertEqual(calendar.parseLifeExpectancy(''), 90, 'calendar defaults the life expectancy to ninety')
|
||||
assertEqual(calendar.parseLifeExpectancy(0), 90, 'calendar defaults an unset life expectancy')
|
||||
assertEqual(calendar.parseLifeExpectancy('abc'), 90, 'calendar defaults a non-numeric life expectancy')
|
||||
assertEqual(calendar.parseLifeExpectancy('200'), 90, 'calendar defaults an implausible life expectancy')
|
||||
|
||||
assertEqual(calendar.lifeProgressPercent(45, 90), 50, 'calendar measures a life against the expectancy given')
|
||||
assertEqual(calendar.lifeProgressPercent(45, 65), 69, 'calendar honours a shorter expectancy')
|
||||
assertEqual(calendar.lifeProgressPercent(45, ''), 50, 'calendar falls back to ninety when no expectancy is set')
|
||||
assertEqual(calendar.lifeProgressPercent(90, 90), 100, 'calendar fills the life bar at the expectancy')
|
||||
assertEqual(calendar.lifeProgressPercent(80, 65), 100, 'calendar never overfills the life bar')
|
||||
assertEqual(calendar.lifeProgressPercent(0, 90), 0, 'calendar leaves the life bar empty when no age is set')
|
||||
assertEqual(calendar.daysInYear(2024), 366, 'calendar knows leap years are longer')
|
||||
assertEqual(calendar.daysInYear(2026), 365, 'calendar knows common years')
|
||||
|
||||
@@ -108,7 +147,7 @@ assert(/ipcTarget: "omarchy\.clock"/.test(panelSource), 'calendar panel register
|
||||
assert(/manageIpc: false/.test(panelSource), 'calendar panel leaves the IPC target to the bar widget')
|
||||
assert(/anchorItem: root\.anchorItem/.test(panelSource), 'calendar panel anchors to the host widget button')
|
||||
assert(/function toggleWeekStart\(\)/.test(panelSource), 'calendar panel exposes a week start toggle')
|
||||
assert(/setting\("weekStartDay", null\)/.test(panelSource) && /entry\.weekStartDay =/.test(panelSource), 'calendar reads and writes the week start as weekStartDay')
|
||||
assert(/setting\("weekStartDay", null\)/.test(panelSource) && /persistSettings\(\{ weekStartDay:/.test(panelSource), 'calendar reads and writes the week start as weekStartDay')
|
||||
assert(/updateEntryInline/.test(panelSource), 'calendar panel persists the week start to shell.json')
|
||||
assert(/function moveMonth\(delta\)/.test(panelSource), 'calendar panel steps between months')
|
||||
assert(!/property bool onToday/.test(panelSource) && !/root\.onToday/.test(panelSource), 'calendar panel avoids the on-prefixed property name QML reads as a signal handler')
|
||||
@@ -123,6 +162,24 @@ assert(!/clampMonth/.test(panelSource), 'calendar steps freely into future month
|
||||
assert(/Qt\.formatDate\(root\.today, "MMMM d"\)/.test(panelSource), 'calendar hero spells out today')
|
||||
assert(/id: yearLabel/.test(panelSource) && /root\.yearDone/.test(panelSource), 'calendar panel shows the year progress bar')
|
||||
|
||||
// The memento mori bar is opt-in: double-tapping the year bar asks for an age,
|
||||
// and nothing shows until one has been given.
|
||||
assert(/onDoubleTapped: root\.startEditingLife\(\)/.test(panelSource), 'calendar asks for an age when the year bar is double-tapped')
|
||||
assert(/persistSettings\(\{ birthYear: born, lifeExpectancy: span \}\)/.test(panelSource), 'calendar saves birth year and expectancy together, so neither lands on a stale copy')
|
||||
assert(/readonly property int birthYear: Model\.parseBirthYear\(setting\("birthYear", 0\)/.test(panelSource), 'calendar reads the saved birth year back')
|
||||
assert(/readonly property int age: Model\.ageFromBirthYear\(birthYear/.test(panelSource), 'calendar derives the age from the stored birth year')
|
||||
assert(/readonly property int lifeExpectancy: Model\.parseLifeExpectancy\(setting\("lifeExpectancy", 0\)\)/.test(panelSource), 'calendar reads the saved expectancy back')
|
||||
assert(/id: expectancyField/.test(panelSource) && /id: bornField/.test(panelSource), 'calendar offers both inputs')
|
||||
assert(/visible: root\.editingLife\s*\n\s*anchors\.horizontalCenter: parent\.horizontalCenter/.test(panelSource), 'calendar centers the inputs over the bar they replace')
|
||||
assert(/visible: root\.birthYear > 0/.test(panelSource), 'calendar hides the life bar until a birth year is known')
|
||||
assert(/text: "LIFE"/.test(panelSource) && /root\.lifeDone/.test(panelSource), 'calendar shows the life bar')
|
||||
assert(/text: "Memento Mori"/.test(panelSource), 'calendar names the life bar on hover')
|
||||
assert(/onDoubleTapped: root\.clearLife\(\)/.test(panelSource), 'calendar puts the life bar away when it is double-tapped')
|
||||
assert(/persistSettings\(\{ birthYear: 0 \}\)/.test(panelSource), 'calendar clears the birth year to hide the life bar')
|
||||
assertEqual(calendar.parseBirthYear(0, 2026), 0, 'a cleared birth year reads back as unset')
|
||||
assert(/blocked: root\.editingLife/.test(panelSource), 'calendar lets the inputs have the keyboard while they are up')
|
||||
assert(/if \(root\.editingLife\) root\.cancelEditingLife\(\)/.test(panelSource), 'calendar drops a half-finished edit when the panel closes')
|
||||
|
||||
assert(/source: Qt\.resolvedUrl\("Panel\.qml"\)/.test(widgetSource), 'clock widget hosts the calendar panel')
|
||||
assert(/readonly property bool opened:/.test(widgetSource), 'clock widget exposes the panel open state to shell routing')
|
||||
assert(/Qt\.RightButton\) root\.cycleFormat\(\)/.test(widgetSource), 'clock right click cycles the label format')
|
||||
|
||||
Reference in New Issue
Block a user