# AGENTS.md - XQuery Code Style and Build Guide ## Build & Test Commands ### Running Tests ```bash basex -t /path/to/test/file.xqm # Run all tests in a file basex -t test/simple.xqm # Run unit tests (7 tests) basex -t test/smoke.xq # Run smoke tests (no assertions) ``` **Running Single Tests**: BaseX runs all tests in a file. To run a single test, comment out others or use `%unit:test` selectively. Test names: `test:from-file`, `test:from-string1`, `test:from-string2`, `test:update-start`, `test:update-end`, `test:update-lines`, `test:lines`. ### Query Execution ```bash basex query.xq # Execute XQuery file basex -V query.xq # Verbose mode with timing info (includes compile/execute times) basex -q "query string" # Execute inline query basex -Q test/file.xqm # Execute XQuery file (explicit flag, for query files without test functions) basex -c "commands" # Execute BaseX commands from string basex -C script.bxs # Execute BaseX command script basex # Start interactive BaseX shell ``` ### Database Operations (Already included in Query Execution section above) ## Environment - **XQuery Engine**: BaseX 12.2 - **XQuery Version**: 3.1+ - **Module System**: BaseX module system with `module namespace` - **Test Framework**: `http://basex.org/modules/unit` ## Code Style Guidelines ### File Naming - Module files: `lowercase.xqm` (e.g., `doci.xqm`) - Test files: `snake_case.xqm` or `snake_case.xq` - Use hyphens for multi-word names (e.g., `pdfbox.xqm`) - Resource files: lowercase with hyphens (e.g., `test-data.txt`) ```xquery module namespace doci = 'urn:quodatum:text:doci'; ``` ### Records & Types - Use `declare record` for structured data - Use `declare type` for custom types - Record fields use `?field` syntax for access - Mark optional fields with `?` after field name ```xquery declare record doci:doci( lines as xs:string+, separator? as xs:string ); ``` ### Function Naming - Module functions: prefix with module namespace (e.g., `doci:build`) - Helper functions: use camelCase internally - Test functions: prefix with `test:` namespace and `test:` prefix - Use descriptive names that clarify purpose ### Import/Module Syntax ```xquery import module namespace mod = 'namespace' at "path/to/file.xqm"; ``` - Use relative paths for local modules - Keep imports at top of file, grouped logically ### Module Organization - Group related functionality in modules - Export public API functions - Keep private functions marked with `%private` if needed - Document exported functions with `(:~` doc comments ### Line Separators - Detect automatically using `doci:separator()` - Default: `file:line-separator()` - Handle all common separators: `\n`, `\r\n`, `\r` ### Module Function Implementation Notes - Use `=>` for function chaining/piping - Prefer `let` over `for` for single items - Use `if-then-else` expressions - Leverage XQuery 3.1+ functions: `tokenize()`, `string-join()` - Use `!` for mapping single items (e.g., `$lines!doci:build(.)`) - Use `*` for mapping sequences: `expr!func()` - Prefer `switch() case when` over nested `if-then-else` - Use `trace()` for debugging: `=>trace("$var")` or `=>trace("label")` ### Error Handling ```xquery try { ... } catch * { error(xs:QName("mod:code"), "descriptive message") } ``` - Use `try/catch` for external operations (files, PDFs, network) - Define custom error codes as `xs:QName` - Validate parameters and ranges before processing - Provide meaningful error messages with context - Use `#mod:code` for errorQName in `error()` calls ### XQuery Best Practices - Use `=>` for function chaining/piping - Prefer `let` over `for` for single items - Use `if-then-else` expressions - Leverage XQuery 3.1+ functions: `tokenize()`, `string-join()` - Use `!` for mapping single items - Use `*` for mapping sequences: `expr!func()` - Prefer `switch() case when` over nested `if-then-else` ### Type Checking ```xquery declare function foo($param as xs:string) as xs:integer { ... } ``` - Specify parameter types using `as xs:type` - Use `item()`, `item()*` for flexible/untyped sequences - Return type declarations are mandatory for exported functions - Use `doci:num` for union types (e.g., integer|double) ### Record Field Access - Use `?field` syntax for record field access (e.g., `$doci?lines`) - Optional fields marked with `?` after field name in record declaration in declaration, but `?field` syntax for access ### Documentation ```xquery (:~ * Documentation comment * @param $name Description * @return Description * @see Reference URL :) ``` - Use `(:~` for module and function documentation - Document parameters, return values, and side effects - Include `@see` references to external docs when relevant ## Test Structure ### Test Module Pattern ```xquery module namespace test = 'test:module-name'; import module namespace mod = 'namespace' at "../src/file.xqm"; declare %unit:test function test:name() { let $result := mod:function(...) return unit:assert-equals(expected, $result) }; ``` ### Test Assertions ```xquery unit:assert-equals(expected, actual) unit:assert(condition) ``` - Use `unit:assert-equals` for value comparison - Use `unit:assert` for boolean conditions - Provide meaningful test names: `test:functionality` ### Running Single Tests ```bash basex -t test/file.xqm # Runs all tests in the file # To run a single test, comment out others or use test: namespaces ``` ### Test Helper Functions ```xquery declare function test:read($path as xs:string) as xs:string { file:resolve-path($path, file:base-dir()) => file:read-text() }; ``` ### Test Data - Place test resources in `test/resources/` - Use descriptive filenames (e.g., `sample.txt`, `empty.txt`) - Use `test:read("resources/filename.txt")` helper ### Test Organization - Group tests by functionality - Test edge cases: empty input, null values, boundaries - Test error cases where applicable - Keep tests independent and order-independent ## Commit Standards ### Commit Message Format ``` verb: description ``` ### Examples ```bash fix: handle empty input add: support多元 line separators refactor: improve error handling test: add edge case for range updates docs: update module documentation ``` ### Commit Guidelines - Add test cases for bug fixes - Update documentation for public API changes - Keep commits focused on single changes - Verify tests pass before committing ## Notes - BaseX 12.2 supports XQuery 3.1 syntax - Use `hof:until` instead of `fn:do-until` if available - Java interoperability available through `Q{namespace}` syntax (e.g., `Q{java:java.io.File}new()`) - For PDF processing (`pdfbox` module), external JAR dependencies required - The `doci:separator()` function auto-detects line separators (`\n`, `\r\n`, `\r`) - Use `=>trace()` liberally during debugging to inspect intermediate values