Commit Graph

21 Commits

Author SHA1 Message Date
2ae016f426 Failing tests for vCard v4 fix sets. 2026-03-28 19:54:17 -05:00
e3f0fdc1ab Refactor vCard validation and canonicalize VERSION handling
Move whole-card cardinality checks into overloaded validate helpers in
the vCard 3 and vCard 4 modules, and have readVCard invoke those
validators after parsing instead of hard-coding property checks in the
shared parser.

For vCard 3, validate property cardinality directly from propertyCardMap
and add regression coverage for duplicate single-cardinality properties.
For vCard 4, validate from propertyCardMap as well, while preserving
ALTID semantics for single-cardinality properties so alternate
representations remain valid and duplicate ungrouped properties are
rejected.

Rework VERSION handling to treat it as parser metadata rather than
stored card content. Parsing still requires exactly one canonical
VERSION line and rejects missing or duplicate occurrences, but parsed
cards no longer retain VC3_Version or VC4_Version objects in content.
Accessors and serializers continue to expose and emit the canonical
version for the concrete card type, which keeps parsed and
programmatically constructed cards on the same model.

Update the vCard 3 and vCard 4 test suites to cover the new validation
path, confirm VERSION is not persisted in content, and adjust fixture
expectations to match the canonical VERSION model.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 19:41:09 -05:00
cfac536d60 Fix vCard 3 PROFILE and AGENT handling
Parse PROFILE as the concrete VC3_Profile type instead of a bare
VC3_Property, and validate PROFILE parameters under the correct
content-type name.

Preserve AGENT values in newVC3_Agent so both parsed and constructed
AGENT properties serialize with their actual URI or inline content.

Expand regression coverage to verify PROFILE is exposed and serialized
as the standard property, parsed AGENT URI values round-trip correctly,
and constructed AGENT values retain their content.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 13:33:20 -05:00
8f2a05cde6 Fix vCard 3 REV and KEY value handling
Bring the remaining vCard 3 REV and KEY behavior into line with RFC
2426.

For REV, serialize VALUE=date using the date form instead of incorrectly
emitting VALUE=date-time with a timestamp payload.

For KEY, stop defaulting constructed values to VALUE=uri. The vCard 3
specification defines KEY as binary by default and allows it to be reset
to text, but not to uri. Tighten both construction and parsing
accordingly: reject VALUE=uri for KEY, enforce the relationship between
VALUE=binary and ENCODING=b, and reject VALUE=text when ENCODING=b is
present.

Update the regression coverage to reflect the spec boundary: PHOTO,
LOGO, and SOUND may round-trip as uris; KEY may contain text that looks
like a URI; KEY does not allow VALUE=uri; and vCard 3 KEY parameters
still require name=value syntax.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:46:41 -05:00
6e6e06bdc4 Fix quoted MIME-DIR parameter parsing
Correct the vCard 3 parameter parser so quoted parameter values are
consumed according to the MIME-DIR grammar instead of failing
immediately on the opening double quote.

The fix explicitly advances past the opening quote, reads the quoted
qsafe-char sequence, and strips the surrounding quotes from the returned
parameter value. Unquoted parameter handling is unchanged.

Add private parser coverage for quoted parameter values and quoted
values containing commas, plus a public regression test showing that
quoted LANGUAGE and TYPE parameters are accepted by the vCard 3 parser.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:32:58 -05:00
201556ecbe Fix vCard 3 text escaping and decoding
Implement RFC 2426 text escaping consistently across vCard 3
serialization and parsing.

On serialization, escape backslashes, newlines, semicolons, and commas
for simple text properties, structured text components, and list-valued
text properties so generated FN, N, ADR, ORG, CATEGORIES, and related
properties are spec-compliant on the wire.

On parsing, decode escaped text for the properties that were previously
read as raw values: FN, NICKNAME, LABEL, MAILER, TITLE, ROLE, PRODID,
and SORT-STRING. This preserves existing structured-text parsing for N,
ADR, NOTE, ORG, and CATEGORIES while fixing the direct raw-value
mismatch identified in the review.

Add regression coverage for both directions: parsing escaped text values
and serializing escaped simple, structured, and list text values.

AI-Assisted: yes
AI-Tool: OpenAI Codex / gpt-5.4 xhigh
2026-03-28 10:27:37 -05:00
35377f5a25 Fix vCard 3 inline binary round-tripping
Decode ENCODING=b payloads for PHOTO, LOGO, SOUND, and KEY when parsing
so serializing a parsed card does not base64-encode already encoded wire
data a second time. Add regression coverage for both inline binary and
VALUE=uri round-trips.

AI-Assisted: yes
AI-Tool: OpenAI Codex /gpt-5.4 xhigh
2026-03-28 10:13:52 -05:00
3d2d40667d Add a unified test runner for better test output. 2026-03-28 10:03:43 -05:00
c9de20f3a7 WIP: Test cases covering findings surfaced by ChatGPT. 2026-03-28 09:58:12 -05:00
ab2579bdb5 Modifications to compile under Nim 2.x 2026-03-28 09:55:17 -05:00
98c300fee2 vcard4: Complete implementation.
- Parsers and serializers are now present for all property types.
- Tests exist to cover parsing for most value types. Many property types
  share the same parsing logic based on their value type. We have
  created unit tests to cover each value type, not neccesarily all
  properties individually.
2023-05-02 22:37:23 -05:00
daa58518e3 vcard3: Unify with VCard4 implementation.
- Unify the naming pattern of types and enums. Specifically:
  - use `VC_Param` instead of `VCParam`. The goal here is to make the
    important information (Param, Source, PropertyName, etc.) easy to
    see at a glance while preserving a prefix that allows multiple
    implementation to coexist (VC3_Source vs. VC4_Source) and also be
    easily distinguishable at a glance.
  - use `pnName` instead of `cnName`. The VCard standard refers to each
    line of data as a "content line," so the original name of each was
    "Content." However, the spec more commonly refers to each piece of
    data as a "property." There is a 1-to-1 mapping of content lines to
    property instances, but property is a more accurate name.

- Introduce the idea of property cardinality to the VCard3
  implementation. The spec does not tightly define property cardinality,
  but implies it with statements like "if the NAME type is present, then
  *its* value is *the* displayable, presentation text associated..."
  (emphasis added). Similar language implies some properties must be
  present exactly once (FN, N, VERSION) or at most once (NAME, PROFILE,
  SOURCE, BDAY, CATEGORIES, PRODID, REV, SORT-STRING, UID). Any other
  properties are assumed to be allowed any number of times (including
  0).

  In the case of a VCard that contains multiple instances of properties
  expected to be singular, the parser will still parse and store these
  properties. They can be accessed via the `vcard#allPropsOfType`
  function. For example:

      # vc3 is a VCard3
      allPropsOfType[VC3_N](vc3)

  If we see over the course of time that other implementations regularly
  use multiple instances of properties we have expected to be singular,
  we are open to changing the contract to treat them so (though this
  may be a breaking change).

- Refactor the VCard3 implementation to use generated property
  accessors, following a similar pattern to the new VCard4
  implementation.

- Remove the accessor definitions that allow access via the content seq
  directly (`vc3.content.name` for example). There really isn't a reason
  for this use-case and the library is simpler without exposing this.
2023-05-02 22:36:27 -05:00
f59403ad72 WIP - initial VCard4 implementation. 2023-04-23 21:56:15 -05:00
8e58189a8b Re-organizing code in preparation for v4.0 implementation. 2023-04-23 21:56:04 -05:00
68554920e5 Fix bug in parsing TEL content. Rework unit tests.
- newVC3_Tel was not assigning the value provided to the constructed
  object.
- Private unit tests were run every time the code was compiled due to
  how the unittest library works. These now only run as part of the unit
  tests with `nimble test`.
2023-04-16 03:34:14 -05:00
0f353e97ca Add test case for email preference. 2023-04-15 07:08:30 -05:00
a0cd676521 Fix defect found testing EMAIL content types. 2023-04-10 16:10:49 -05:00
82dffc1154 Initial VCard 3.0 implementation completed. 2023-04-04 14:31:44 -05:00
c322616747 WIP lexer unit tests. 2023-04-01 17:36:01 -05:00
d6d8e1d654 WIP vcard 3.0 implementation. 2023-03-26 20:45:52 -05:00
ee716a4801 Initial commit with Nimble library template and RFCs. 2022-07-01 23:01:09 -05:00