Skip to content

Instantly share code, notes, and snippets.

@ivan-kleshnin
Last active April 12, 2022 09:52
Show Gist options
  • Save ivan-kleshnin/b5cd180b02fb62fe19cfe3fc1b6ca297 to your computer and use it in GitHub Desktop.
Save ivan-kleshnin/b5cd180b02fb62fe19cfe3fc1b6ca297 to your computer and use it in GitHub Desktop.
const experiences = [
// all `nulls`s
{id: 1, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: null, endDateMonth: null},
// three `null`s
{id: 2, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: null, endDateMonth: null},
{id: 3, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: null, endDateMonth: null},
{id: 4, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: 2022, endDateMonth: null},
{id: 5, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: null, endDateMonth: 2},
// two `null`s
{id: 6, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: 2022, endDateMonth: null},
{id: 7, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: null, endDateMonth: 2},
{id: 8, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: 2022, endDateMonth: null},
{id: 9, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: 2022, endDateMonth: 2},
{id: 10, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: null, endDateMonth: 2},
{id: 11, name: "FOO", startDateYear: 2044, startDateMonth: 2, endDateYear: null, endDateMonth: null},
// single `null`
{id: 12, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: 2022, endDateMonth: 2},
{id: 13, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: 2022, endDateMonth: 2},
{id: 14, name: "FOO", startDateYear: 2022, startDateMonth: 2, endDateYear: 2021, endDateMonth: null},
// no `null`
{id: 15, name: "FOO", startDateYear: 2022, startDateMonth: 2, endDateYear: 2032, endDateMonth: 2},
{id: 16, name: "FOO", startDateYear: 2024, startDateMonth: 2, endDateYear: 2032, endDateMonth: 2},
{id: 16, name: "FOO", startDateYear: 2020, startDateMonth: 2, endDateYear: 2021, endDateMonth: 2},
{id: 16, name: "FOO", startDateYear: 2020, startDateMonth: 2, endDateYear: 2020, endDateMonth: 2},
].flatMap(exp => [{...exp, endDateIsCurrent: true}, {...exp, id: exp.id + 10, endDateIsCurrent: false}])
function isWorkExperience(experience) {
// IMPORTANT won't work if we start to return `undefined` instead of `null`
// In this case new prop `_type` should be injected
return "companyName" in experience
}
export function convertExperience(experience : TalentWorkExperience | TalentEducation) : Experience {
const expDates : ExperienceDates = {
// TODO check 1st month is 1 or 0!!!
...(experience.startDateYear && experience.startDateMonth)
? {startDate: new Date(experience.startDateYear, experience.startDateMonth)}
: {},
...experience.endDateIsCurrent
? {endDate: true}
: (experience.endDateYear && experience.endDateMonth) ? {endDate: new Date(experience.endDateYear, experience.endDateMonth)} : {},
}
return isWorkExperience(experience) ? {
...expDates,
id: experience.id,
name: experience.name,
companyName: experience.companyName,
link: experience.link,
description: experience.description,
} : {
...expDates,
id: experience.id,
name: experience.name,
description: experience.description,
}
}
type ComparisonResult = -1 | 0 | 1 // TODO use a global type
function compareIds(e1 : Experience, e2 : Experience) : ComparisonResult {
return (e1.id > e2.id) ? -1 :
(e1.id < e2.id) ? 1 : 0
}
function compareDatesByField(field : "startDate" | "endDate") {
return function compareDates(e1 : Experience, e2 : Experience) : ComparisonResult {
if (e1[field] && e2[field]) {
return (e1[field]! > e2[field]!) ? -1 :
(e1[field]! < e2[field]!) ? 1 : compareIds(e1, e2)
} else if (e1[field]) {
return -1
} else if (e2[field]) {
return 1
} else {
return compareIds(e1, e2)
}
}
}
const compareStartDates = compareDatesByField("startDate")
const compareEndDates = compareDatesByField("endDate")
function compareExperiences(e1 : Experience, e2 : Experience) {
if (e1.endDate === true && e2.endDate === true) {
return compareStartDates(e1, e2)
} else if (e1.endDate === true) {
return -1
} else if (e2.endDate === true) {
return 1
} else {
return compareStartDates(e1, e2) || compareEndDates(e1, e2)
}
}
@ShaimaaHamdan
Copy link

Hey @ivan-kleshnin
I am just wondering why you are doing the date comparison manually why we can use dayjs plugin to do the comparison functions actually it works fine over all our events, we have isSame, isSameOrBefore, isSameOrAfter, and diff functions they are really cool and it results accurately
the second point we can create some test cases using jtest or any other tech to test the flow giving them all possible inputs to get the outputs , I prefer in writing algorithms doing it in reverse mode TDD, testing first then the code itself.
thank you

@ivan-kleshnin
Copy link
Author

ivan-kleshnin commented Nov 12, 2021

Thank you for the review!

I am just wondering why you are doing the date comparison manually why we can use dayjs plugin to do the comparison functions actually it works fine over all our events, we have isSame, isSameOrBefore, isSameOrAfter, and diff functions they are really cool and it results accurately

Because in this case I don't see much benefit of using an extra library. For date manipulations I personally prefer https://date-fns.org/ but it's quite large. Right now, to avoid wasting time on search & comparison & bundling something we don't really need there's just one extra function. Can be reconsidered in the future, of course, if we start using dayjs or something else.

the second point we can create some test cases using jtest or any other tech to test the flow giving them all possible inputs to get the outputs , I prefer in writing algorithms doing it in reverse mode TDD, testing first then the code itself.

Yep, I just didn't have time to setup test infrastructure yet. For TypeScript + React + NextJS it's not the quickest task. I spent days trying to make Jest work with TS and ESM modules and JSX in the (not so distant) past.

I plan to work on that, if someone with "Automation QA" skill will join us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment