Skip to content

Comments

Fix/winal-radix-correction#94

Closed
drewsonne wants to merge 15 commits intomainfrom
fix/winal-radix-correction
Closed

Fix/winal-radix-correction#94
drewsonne wants to merge 15 commits intomainfrom
fix/winal-radix-correction

Conversation

@drewsonne
Copy link
Owner

No description provided.

Copilot AI review requested due to automatic review settings January 2, 2026 16:37
@drewsonne drewsonne force-pushed the fix/winal-radix-correction branch from 3efa6ab to 33038b6 Compare January 2, 2026 16:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request addresses a winal-radix correction by adding comprehensive test infrastructure based on historical Maya date correlations from Mesoweb's "Table of Palenque Rulers". The changes introduce a substantial JSON dataset containing 3,647 correlation entries and testing utilities to validate the library's Maya calendar calculations against historically documented dates.

Key Changes

  • Added JSON dataset with historical Maya date correlations (3,647 entries across 4 correlation constants)
  • Implemented test data loader utility with filtering and query helpers
  • Created comprehensive test suites validating correlations, calendar rounds, and full dates

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/__tests__/test-data-loader.ts Utility module for loading and querying the JSON correlation dataset
src/__tests__/maya_date_correlations.json Historical correlation data from Mesoweb source with 3,647 entries
src/__tests__/lc/western/western.spec.ts Added tests validating Long Count to Western date conversions using JSON data
src/__tests__/full-date.spec.ts Added historical full date validation tests with orthographic variation handling
src/__tests__/correlation-validation.spec.ts Comprehensive test suite for correlation constants, calendar rounds, and data quality
.mocharc.json Mocha test runner configuration for TypeScript support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// of Maya day/month names), some entries may not parse. This is expected.
// The JSON data uses various transliteration systems that may differ from
// the library's expected spellings.
console.log(`Calendar Round parsing: ${successCount} succeeded, ${failureCount} failed (orthographic variations expected)`);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using console.log in test code can clutter test output and is generally discouraged. Consider removing this or using a proper test reporting mechanism if you need to track these statistics.

Suggested change
console.log(`Calendar Round parsing: ${successCount} succeeded, ${failureCount} failed (orthographic variations expected)`);

Copilot uses AI. Check for mistakes.
const year = correlation.western_date.split('-')[0];
const gregorianDate = `${lc.gregorian}`;
// Remove leading zeros for comparison (e.g., 0397 -> 397)
expect(gregorianDate).to.include(year.replace(/^0+/, ''));
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The year comparison logic using replace(/^0+/, '') and string inclusion is fragile and may produce false positives. A date with year "397" would match "1397" or "2397". Consider parsing the dates into comparable formats or extracting the year component more precisely for comparison.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot I think a better solution is just to match on a single format (eg, iso8601)

const expectedYear = correlation.western_date.split('-')[0];
const gregorianDate = `${lc.gregorian}`;
// Remove leading zeros for comparison
expect(gregorianDate).to.include(expectedYear.replace(/^0+/, ''));
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The year comparison logic using replace(/^0+/, '') and string inclusion is fragile and may produce false positives. A date with year "397" would match "1397" or "2397". Consider parsing the dates into comparable formats or extracting the year component more precisely for comparison.

Copilot uses AI. Check for mistakes.
Comment on lines 68 to 69
// This is a placeholder - you may need to adjust date format comparison
expect(actualDate).to.include(correlation.western_date.split('-')[0]); // At least check year
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is defined inside a forEach loop but then creates a nested it block, which is incorrect test structure. The it block should be the outer loop iterator, not defined inside the forEach. This will cause only the last iteration to be tested or may fail to register tests properly.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +40 to +50
let correlationData: CorrelationTestData | null = null;

/**
* Loads the Maya date correlation test data from JSON file
*/
export function loadCorrelationData(): CorrelationTestData {
if (!correlationData) {
const jsonPath = path.join(__dirname, 'maya_date_correlations.json');
const rawData = fs.readFileSync(jsonPath, 'utf8');
correlationData = JSON.parse(rawData) as CorrelationTestData;
}
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module-level mutable state correlationData is used for caching. While this works, consider using a more explicit caching pattern or documenting this behavior, as module-level mutable state can make testing and debugging more difficult.

Suggested change
let correlationData: CorrelationTestData | null = null;
/**
* Loads the Maya date correlation test data from JSON file
*/
export function loadCorrelationData(): CorrelationTestData {
if (!correlationData) {
const jsonPath = path.join(__dirname, 'maya_date_correlations.json');
const rawData = fs.readFileSync(jsonPath, 'utf8');
correlationData = JSON.parse(rawData) as CorrelationTestData;
}
const jsonPath = path.join(__dirname, 'maya_date_correlations.json');
const rawData = fs.readFileSync(jsonPath, 'utf8');
const correlationData: CorrelationTestData = JSON.parse(rawData) as CorrelationTestData;
/**
* Loads the Maya date correlation test data from JSON file
*/
export function loadCorrelationData(): CorrelationTestData {

Copilot uses AI. Check for mistakes.
@drewsonne drewsonne force-pushed the fix/winal-radix-correction branch from 33038b6 to e569144 Compare January 2, 2026 17:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated 16 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

*/
export function loadCorrelationData(): CorrelationTestData {
if (!correlationData) {
const jsonPath = path.join(__dirname, 'maya_date_correlations.json');
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path references 'maya_date_correlations.json' but the actual file in the diff is 'maya_date_correlations.json.bak'. This path mismatch will cause a file not found error at runtime. Either the filename needs to be updated to match the path, or the path needs to include the '.bak' extension.

Suggested change
const jsonPath = path.join(__dirname, 'maya_date_correlations.json');
const jsonPath = path.join(__dirname, 'maya_date_correlations.json.bak');

Copilot uses AI. Check for mistakes.
import LongCountFactory from '../factory/long-count';
import FullDateFactory from '../factory/full-date';
import {getCorrelationConstant} from '../lc/correlation-constant';

Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment references a "winal radix correction" in the PR title, but there's no documentation explaining what this correction is or why these tests validate it. Consider adding a comment block at the top of this test file explaining the purpose of these tests and how they relate to the winal radix correction mentioned in the PR title.

Suggested change
/**
* These tests validate Maya Long Count western date correlations using the JSON
* fixture data and the conversion factories. In particular, they exercise logic
* affected by the "winal radix correction" mentioned in the PR title.
*
* The winal radix correction refers to how 20‑day winals are handled when mapping
* Long Count positions to a fixed day count (JDN) and then to Gregorian/Julian
* calendar dates. Historically, small off‑by‑one errors in this radix handling
* can shift whole correlation constants by one or more days.
*
* By:
* - loading the canonical correlation dataset,
* - validating the GMT correlation constant (584285) against direct historical
* source entries, and
* - comparing western dates produced under neighboring correlation constants
* (e.g. 584283–584286),
* these tests ensure that the current implementation of the winal radix, and the
* resulting correlation constants, produce stable and internally consistent dates.
*/

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,3647 @@
{
"metadata": {
"generated_at": "2026-01-02",
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file has a ".bak" extension which suggests this is a backup file. Backup files should typically not be committed to version control. If this is intended to be the actual test data file, it should be renamed to remove the ".bak" extension. If it's truly a backup, it should be excluded from the repository.

Suggested change
"generated_at": "2026-01-02",
"generated_at": "2025-01-02",

Copilot uses AI. Check for mistakes.
Comment on lines 10 to 11
getAvailableCorrelations,
CorrelationData
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'CorrelationData' is defined but never used.

Suggested change
getAvailableCorrelations,
CorrelationData
getAvailableCorrelations

Copilot uses AI. Check for mistakes.
// Test that Calendar Round actually parses - this will fail if spellings don't match
const fullDateString = `${data.calendar_round} ${data.maya_long_count}`;
const fullDate = factory.parse(fullDateString);
expect(fullDate).to.not.be.null;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Suggested change
expect(fullDate).to.not.be.null;
expect(fullDate).to.not.equal(null);

Copilot uses AI. Check for mistakes.
@@ -67,3 +72,49 @@ it('isPartial should detect wildcards', () => {
expect(fd3.isPartial()).to.be.true;
expect(fd4.isPartial()).to.be.true;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Copilot uses AI. Check for mistakes.
// Parse should succeed - if it fails, the spellings don't match
const fullDate = new FullDateFactory().parse(fullDateString);

expect(fullDate).to.not.be.null;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Suggested change
expect(fullDate).to.not.be.null;
expect(fullDate).to.not.equal(null);

Copilot uses AI. Check for mistakes.
const lcString = correlation.maya_long_count;
const lc = new LongCountFactory().parse(lcString);

expect(lc).to.not.be.null;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Copilot uses AI. Check for mistakes.
import {
getGMTCorrelationData,
getDirectSourceData,
findCorrelation,
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'findCorrelation' is defined but never used.

Suggested change
findCorrelation,

Copilot uses AI. Check for mistakes.
const lc = lcFactory.parse(correlation.maya_long_count).setCorrelationConstant(corr);

// Validate the Long Count parses correctly
expect(lc).to.not.be.null;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Suggested change
expect(lc).to.not.be.null;
expect(lc).to.not.equal(null);

Copilot uses AI. Check for mistakes.
@drewsonne
Copy link
Owner Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Contributor

Copilot AI commented Jan 2, 2026

@drewsonne I've opened a new pull request, #95, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Jan 2, 2026

@drewsonne I've opened a new pull request, #100, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Jan 2, 2026

@drewsonne I've opened a new pull request, #101, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Jan 2, 2026

@drewsonne I've opened a new pull request, #102, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits January 2, 2026 17:31
…ntation

Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 2, 2026 17:47
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

/**
* Loads the Maya date correlation test data from JSON file
*/
export function loadCorrelationData(): CorrelationTestData {
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing explicit return type annotation. According to the coding guidelines, all public functions must have explicit return types. Add : CorrelationData[] as the return type.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +70 to +72
expect(fd2.isPartial()).to.equal(true);
expect(fd3.isPartial()).to.equal(true);
expect(fd4.isPartial()).to.equal(true);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent assertion style. Lines 70-72 use .to.equal(true) while the rest of the codebase (including line 69) uses .to.be.true. For consistency with Chai best practices and the existing code, use .to.be.true instead of .to.equal(true).

Suggested change
expect(fd2.isPartial()).to.equal(true);
expect(fd3.isPartial()).to.equal(true);
expect(fd4.isPartial()).to.equal(true);
expect(fd2.isPartial()).to.be.true;
expect(fd3.isPartial()).to.be.true;
expect(fd4.isPartial()).to.be.true;

Copilot uses AI. Check for mistakes.
@@ -63,7 +67,53 @@ it('isPartial should detect wildcards', () => {
const fd4 = new FullDateFactory().parse('4 Ajaw * Kumk\'u 9.17.0.0.*');

expect(fd1.isPartial()).to.be.false;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected an assignment or function call and instead saw an expression.

Suggested change
expect(fd1.isPartial()).to.be.false;
expect(fd1.isPartial()).to.equal(false);

Copilot uses AI. Check for mistakes.
Copilot AI and others added 4 commits January 2, 2026 20:43
…age control

Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
Co-authored-by: drewsonne <233054+drewsonne@users.noreply.github.com>
- Fixed BCE year conversion to use astronomical year numbering (1 BCE = year 0)
- Corrected verification logic in GregorianFactory.parse() for BCE dates
- Removed asterisk suffix from toString() for threshold dates (Oct 4/15, 1582)
- Cleaned up test data to remove asterisk markers from date strings
- Simplified Gregorian offset table to remove incorrect intermediate ranges
- All 466 tests now passing, including 5 previously failing edge cases
- Renamed correlation-validation.spec.ts.skip back to .spec.ts
- All comprehensive data validation tests now pass
- Tests validate JSON dataset structure, metadata, helper functions
- Adds 20 additional passing tests for data quality and structure
This temporary debugging file was used to investigate year boundary failures
that have now been fixed. No longer needed with all tests passing.
This diagnostic test was used to investigate year boundary failures
that have now been resolved. The actual functionality is covered by
western.spec.ts and correlation-validation.spec.ts.
This file was used to debug offset boundary calculations but only prints
diagnostic output without actual assertions. The functionality is fully
tested in western.spec.ts with proper assertions.
The variable held all Gregorian calendar dates from the dataset, not a sample.
Also updated the test suite description for clarity.
const g = gregorianFactory.parse(dc.gregorian);
// Verify that the parsed date matches the expected Gregorian date string
// The toString() method should return the same format as the input (without asterisk if not threshold)
const expectedDate = dc.gregorian.replace('*', '').trim();

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding High test

This replaces only the first occurrence of '*'.

Copilot Autofix

AI about 2 months ago

In general, to fix this kind of problem, ensure that any sanitization or marker-removal that should apply to all occurrences uses a global replacement (e.g., a regex with the g flag) or a built-in method that replaces all occurrences (such as replaceAll).

In this specific case, we want to remove all * characters from dc.gregorian before comparing it to the parsed date string. The minimal, behavior-preserving fix is to change line 82 from using string.replace('*', '') to a global replacement. Since this is TypeScript targeting typical Node/test environments, using a regular expression with the global flag is reliable and avoids any dependency changes. Thus we should update line 82 to:

const expectedDate = dc.gregorian.replace(/\*/g, '').trim();

This ensures that any and all * characters in the string are removed, not just the first one, while keeping the rest of the test logic unchanged. No new imports or helper functions are needed; the change is confined to the single line in src/__tests__/lc/western/western.spec.ts.

Suggested changeset 1
src/__tests__/lc/western/western.spec.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/__tests__/lc/western/western.spec.ts b/src/__tests__/lc/western/western.spec.ts
--- a/src/__tests__/lc/western/western.spec.ts
+++ b/src/__tests__/lc/western/western.spec.ts
@@ -79,7 +79,7 @@
       const g = gregorianFactory.parse(dc.gregorian);
       // Verify that the parsed date matches the expected Gregorian date string
       // The toString() method should return the same format as the input (without asterisk if not threshold)
-      const expectedDate = dc.gregorian.replace('*', '').trim();
+      const expectedDate = dc.gregorian.replace(/\*/g, '').trim();
       const actualDate = `${g}`.trim();
       expect(actualDate).to.eq(expectedDate);
     });
EOF
@@ -79,7 +79,7 @@
const g = gregorianFactory.parse(dc.gregorian);
// Verify that the parsed date matches the expected Gregorian date string
// The toString() method should return the same format as the input (without asterisk if not threshold)
const expectedDate = dc.gregorian.replace('*', '').trim();
const expectedDate = dc.gregorian.replace(/\*/g, '').trim();
const actualDate = `${g}`.trim();
expect(actualDate).to.eq(expectedDate);
});
Copilot is powered by AI and may make mistakes. Always verify output.
@drewsonne drewsonne closed this Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants