Skip to content

Instantly share code, notes, and snippets.

@AndrewAllison
Last active August 19, 2021 14:14
Show Gist options
  • Save AndrewAllison/9fa492f692038ebcc1c499d7681493f3 to your computer and use it in GitHub Desktop.
Save AndrewAllison/9fa492f692038ebcc1c499d7681493f3 to your computer and use it in GitHub Desktop.
Some commonly used javascript functions
import { compare } from './array-functions';
describe('array-functions', () => {
it('should sort and array', () => {
const unsortedArray = [
{ order: 0, name: 'item 1' },
{ order: 2, name: 'item 3' },
{ order: 1, name: 'item 2' },
];
const resultsArray = unsortedArray.sort((a, b) =>
compare(a, b, 'order', 'desc'),
);
expect(resultsArray[0].name).toEqual('item 1');
expect(resultsArray[1].name).toEqual('item 2');
expect(resultsArray[2].name).toEqual('item 3');
});
it('should sort and array ascending', () => {
const unsortedArray = [
{ order: 0, name: 'item 1' },
{ order: 2, name: 'item 3' },
{ order: 1, name: 'item 2' },
];
const resultsArray = unsortedArray.sort((a, b) =>
compare(a, b, 'order', 'asc'),
);
expect(resultsArray[2].name).toEqual('item 1');
expect(resultsArray[1].name).toEqual('item 2');
expect(resultsArray[0].name).toEqual('item 3');
});
});
/**
* Used with {Array} sort function with compare objects based on a property and rearrange them
* @example
* someArray.sort((a,b) => compare(a,b, 'username', 'desc')
* @param a Object to be sorted
* @param b Object to be compared
* @param orderBy Field / prop name for the comparison
* @param orderDir Sort direction asc or desc
*/
export const compare = (
a: Record<string, unknown>,
b: Record<string, unknown>,
orderBy: string,
orderDir: string,
) => {
if (a[orderBy] < b[orderBy]) {
return orderDir === 'desc' ? -1 : 1;
}
if (a[orderBy] > b[orderBy]) {
return orderDir === 'desc' ? 1 : -1;
}
return 0;
};
import { DateTime } from 'luxon';
/**
* Wrapper method for Luxon to compare a date to DateTime.now() and return a number of days
* representing the difference
* @param dueDate {DateTime} a Luxon Date time object representing the date to carry out the comparison on.
* @param roundValues {boolean} Determines if the value should be rounded via Math.round defaults to 'true'
* @returns {number} The number of days difference from not to the given date.
*/
const calculateDaysBetween = (dueDate: DateTime, roundValues = true) => {
const dueDateDiff = dueDate.diff(DateTime.now(), ['days']).toObject();
return dueDateDiff?.days
? roundValues
? Math.round(dueDateDiff.days)
: dueDateDiff
: 0;
};
/**
* Wrapper method for Luxon to compare a date to DateTime.now() and return an object
* representing the difference ['days', 'weeks', 'months', 'years']
* @param dueDate {DateTime} The date to find the difference of
* @param roundValues should the values be Math.round()
* @returns {object} Returns an object with 'days', 'weeks', 'months', 'years' props
*/
const calculateDiffBetween = (dueDate: DateTime, roundValues = true) => {
const dueDateDiff = dueDate
.diff(DateTime.now(), ['days', 'weeks', 'months', 'years'])
.toObject();
const { days, months, weeks, years } = dueDateDiff;
return {
days: roundValues ? Math.round(days) : days,
weeks: roundValues ? Math.round(weeks) : weeks,
months: roundValues ? Math.round(months) : months,
years: roundValues ? Math.round(years) : years,
};
};
export { calculateDaysBetween, calculateDiffBetween };
import { DateTime } from 'luxon';
import { calculateDaysBetween, calculateDiffBetween } from './date-functions';
describe('date-functions', () => {
describe('calculateDiffBetween', () => {
it('should return the appropriate number of days.', () => {
const dueDate = DateTime.now().minus({ days: 4 });
const daysBetween = calculateDaysBetween(dueDate);
expect(daysBetween).toEqual(-4);
});
it('should handle forward dates.', () => {
const dueDate = DateTime.now().plus({ days: 4 });
const daysBetween = calculateDaysBetween(dueDate);
expect(daysBetween).toEqual(4);
});
it('should return the appropriate number of days.', () => {
const dueDate = DateTime.now().minus({ years: 1 });
const daysBetween = calculateDaysBetween(dueDate);
expect(daysBetween).toEqual(-365); // may fail if it's a leap year.
});
});
describe('calculateDaysBetween', () => {
it('should return the correctly formatted values with default rounding', () => {
const dueDate = DateTime.now().minus({
days: 4,
months: 2,
weeks: 1,
years: 1,
});
const daysBetween = calculateDiffBetween(dueDate);
expect(daysBetween.days).toEqual(-4);
expect(daysBetween.weeks).toEqual(-1);
expect(daysBetween.weeks).toEqual(-1);
expect(daysBetween.months).toEqual(-2);
});
});
});
import { percentageDifference } from './math-functions';
describe('math-functions', () => {
describe('percentageDifference', () => {
it('should calculate a percentage difference.', () => {
const tests = [
[50, 100, 50],
[15, 30, 50],
];
tests.forEach((r) =>
expect(percentageDifference(r[0], r[1])).toEqual(r[2]),
);
});
});
});
/**
* Provides the percentage difference between two numbers
* @param a Initial number
* @param b Secondary value
* @return {number} The difference as a percentage value with Math.ceil rounding.
*/
export const percentageDifference = (a, b) => {
return Math.ceil((a / b) * 100);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment