-
Notifications
You must be signed in to change notification settings - Fork 4
fix(skills): allow single-letter languages C, R, and D (#832) #840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -402,8 +402,8 @@ describe("tokenizeSkillLine — issue #221 non-skill sub-labels", () => { | |||||||||
| }); | ||||||||||
|
|
||||||||||
| it("keeps skill sub-labels (Languages/Technologies/Tools/Frameworks)", () => { | ||||||||||
| expect(tokenizeSkillLine("Languages: Python, Go, C++, Java")).toEqual( | ||||||||||
| expect.arrayContaining(["Python", "Go", "C++", "Java"]), | ||||||||||
| expect(tokenizeSkillLine("Languages: Python, Go, C++, Java, C")).toEqual( | ||||||||||
| expect.arrayContaining(["Python", "Go", "C++", "Java", "C"]), | ||||||||||
| ); | ||||||||||
| expect(tokenizeSkillLine("Technologies: Linux, AWS, Docker, iOS")).toEqual( | ||||||||||
| expect.arrayContaining(["Linux", "AWS", "Docker", "iOS"]), | ||||||||||
|
|
@@ -426,6 +426,23 @@ describe("tokenizeSkillLine — issue #221 non-skill sub-labels", () => { | |||||||||
| }); | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| describe("tokenizeSkillLine — issue #832 single-letter languages", () => { | ||||||||||
| it("keeps C, R, and D as real programming languages", () => { | ||||||||||
| expect(tokenizeSkillLine("Languages: C, R, D")).toEqual( | ||||||||||
| expect.arrayContaining(["C", "R", "D"]), | ||||||||||
| ); | ||||||||||
|
Comment on lines
+431
to
+433
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit (non-blocking).
Suggested change
|
||||||||||
| }); | ||||||||||
|
|
||||||||||
| it("still rejects other single-character noise tokens", () => { | ||||||||||
| expect(tokenizeSkillLine("Skills: x, J, •, (")).toEqual([]); | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit (non-blocking): every token on this line is expected to be rejected, so A positive control in the same line pins it: expect(tokenizeSkillLine("Skills: Python, x, J, C")).toEqual(["Python", "C"]);I ran that on this branch — it returns exactly |
||||||||||
| }); | ||||||||||
|
|
||||||||||
| it("allows allowlisted single letters alongside real skills on the same line", () => { | ||||||||||
| // Positive control: distinguishes rejecting noise from rejecting everything. | ||||||||||
| expect(tokenizeSkillLine("Skills: Python, x, J, C")).toEqual(["Python", "C"]); | ||||||||||
| }); | ||||||||||
| }); | ||||||||||
|
|
||||||||||
| describe("parseHeuristic — issue #221 Interests sub-label in SKILLS section", () => { | ||||||||||
| it("excludes Interests items while keeping Languages/Technologies skills", () => { | ||||||||||
| // Repro from the issue: a Technical Skills section internally sub-labeled | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -138,7 +138,14 @@ function looksLikeContactLink(tok: string): boolean { | |
| return PROFILE_LABEL_RE.test(t) || PROFILE_HOST_RE.test(t) || URLISH_RE.test(t); | ||
| } | ||
|
|
||
| /** One-character tokens that are real, commonly-listed languages. The | ||
| * `tok.length < 2` floor in `isSkillToken` is a noise guard against stray | ||
| * glyphs left by column splitting; these are the only single characters that | ||
| * are not noise, so they are allowlisted rather than lowering the floor. */ | ||
| const SINGLE_LETTER_SKILLS = new Set(["c", "r", "d"]); | ||
|
Comment on lines
+141
to
+145
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit — the docblock says what is in the set, not what was deliberately kept out. #832 makes the exclusions the interesting decision: One sentence fixes it. Non-blocking, and fine to skip. If you do want it, fold it into the existing commit with /** One-character tokens that are real, commonly-listed languages. The
* `tok.length < 2` floor in `isSkillToken` is a noise guard against stray
* glyphs left by column splitting; these are the only single characters that
* are not noise, so they are allowlisted rather than lowering the floor.
* Deliberately excludes J/K/Q/F (#832): each is a real language name, but
* each is also a plausible stray glyph, so admitting them trades a rare
* recall win for a common precision loss. */ |
||
|
|
||
| function isSkillToken(tok: string): boolean { | ||
| if (tok.length === 1 && SINGLE_LETTER_SKILLS.has(tok.toLowerCase())) return true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is correct and matches #832's plan exactly — including the early return, which is what lets an allowlisted token skip the numeric / URL / date-range / word-count checks below. What it also does, though, is move four baked corpus snapshots and clear one |
||
| if (tok.length < 2 || tok.length > 40) return false; | ||
| if (/^\d+$/.test(tok)) return false; | ||
| // A professional-profile link (or its bare "GitHub" / "LinkedIn" heading) is | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (non-blocking). This is the
#221sub-label test, widened to also carry a#832case. Now that#832has its owndescribeblock immediately below, reverting this line keeps each test attributable to the issue it guards — useful later when someone bisects one of the two and wants to know which assertions are load-bearing for which fix.Both forms pass (
["Python", "Go", "C++", "Java", "C"]is the actual return either way), so this is purely about attribution.