Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
176fc53
chore: improved project setup
alessiofrittoli Dec 27, 2024
98b2897
feature: add publish script for automated publishing
alessiofrittoli Dec 27, 2024
196050c
feature: add jest tests workflow and coverage report
alessiofrittoli Dec 27, 2024
a3f7a7e
fix: add `coverage` folder to `.gitignore`
alessiofrittoli Dec 27, 2024
f0ba808
fix: replace `pad` with `padStart` for timezone offset formatting
alessiofrittoli Dec 27, 2024
ee1f485
feature: moved `pnpm test:ci:coverage` into a separate jest test work…
alessiofrittoli Dec 27, 2024
7578f23
fix: rename `Install dependencies` step in jest test CI workflow
alessiofrittoli Dec 27, 2024
a935774
docs: add badges for coverage status and dependencies in README
alessiofrittoli Dec 27, 2024
82fe3f0
docs: update README to enhance development section and clarify test c…
alessiofrittoli Dec 27, 2024
381420c
refactor: update imports to named exports
alessiofrittoli Dec 27, 2024
b2600f7
tests: add utility functions missing branches coverage
alessiofrittoli Dec 27, 2024
f21d0db
fix: pass timezone parameter to isDstObserved in formatDate function
alessiofrittoli Dec 27, 2024
5c633e4
fix: return 0 for UTC timezone in getTimezoneOffsetH function
alessiofrittoli Dec 27, 2024
8ddde15
feat: add support for 'q' timezone format in formatDate function
alessiofrittoli Dec 27, 2024
93deabb
tests: add format functions missing branches coverage
alessiofrittoli Dec 27, 2024
88e59a7
refactor: rename stdTimezoneOffset to dstTimezoneOffset
alessiofrittoli Dec 27, 2024
aa2a807
tests: add timezone functions missing branches coverage
alessiofrittoli Dec 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VAR_LOADED=true
32 changes: 32 additions & 0 deletions .github/workflows/tests-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
on: [ "push", "pull_request" ]

name: Unit Tests

jobs:
test:
name: Run Unit Tests
runs-on: ubuntu-latest
steps:

- uses: actions/checkout@v4

- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x

- name: Install dependencies
run: |
npm install -g pnpm@latest
pnpm i

- name: Run tests
run: |
pnpm test:ci:coverage

- name: Report to Coveralls
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}
file: coverage/lcov.info
allow-empty: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/dist
/node_modules
/coverage

.env.*
!.env.test
.DS_Store
6 changes: 5 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
/src
/__tests__
/docs
/coverage
/scripts

/node_modules
/.git
/.github

.gitignore
.env.*
.DS_Store

eslint.config.mjs
jest.config.js
jest.config.ts
jest.setup.ts
tsconfig.json
tsup.config.ts
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"configurations": [
{
"type": "node",
"name": "Debug Tests",
"request": "launch",
"args": [
"test",
"--",
"--runInBand",
"--watchAll=false",
"--testNamePattern",
"${jest.testNamePattern}",
"--runTestsByPath",
"${jest.testFile}"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"runtimeExecutable": "pnpm"
}
]
}
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"statusBar.background": "#212121",
"statusBar.border":"#C637CB",
"statusBar.foreground": "#F0F0F0",
"activityBar.activeBorder": "#C637CB",
},
}
45 changes: 40 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Version 1.1.1

[![Coverage Status](https://coveralls.io/repos/github/alessiofrittoli/date-utils/badge.svg)](https://coveralls.io/github/alessiofrittoli/date-utils) [![Dependencies](https://img.shields.io/librariesio/release/npm/%40alessiofrittoli%2Fdate-utils)](https://libraries.io/npm/%40alessiofrittoli%2Fdate-utils)

## Lightweight TypeScript date utility functions library

This lightweight TypeScript utility library comes with common and utility dates functions.
Expand All @@ -16,8 +18,9 @@ Everything is exported from the root of this library but specific paths can be u
- [Formatting functions](https://github.com/alessiofrittoli/date-utils/blob/master/docs/format/README.md)
- [Timezone utilities](https://github.com/alessiofrittoli/date-utils/blob/master/docs/timezones/README.md)
- [Utility functions](https://github.com/alessiofrittoli/date-utils/blob/master/docs/utils/README.md)
- [ESLint](#eslint)
- [Jest](#jest)
- [Development](#development)
- [ESLint](#eslint)
- [Jest](#jest)
- [Contributing](#contributing)
- [Security](#security)
- [Credits](#made-with-)
Expand All @@ -38,21 +41,43 @@ or using `pnpm`
pnpm i @alessiofrittoli/date-utils
```

### [ESLint](https://www.npmjs.com/package/eslint)
### Development

#### Install depenendencies

```bash
npm install
```

or using `pnpm`

```bash
pnpm i
```

#### Build your source code

Run the following command to build code for distribution.

```bash
pnpm build
```

#### [ESLint](https://www.npmjs.com/package/eslint)

warnings / errors check.

```bash
pnpm lint
```

### [Jest](https://npmjs.com/package/jest)
#### [Jest](https://npmjs.com/package/jest)

Run all the defined test suites by running the following:

```bash
# Run tests and watch file changes.
pnpm test
pnpm test:watch

# Run tests in a CI environment.
pnpm test:ci
Expand All @@ -70,6 +95,16 @@ pnpm test:timezones
pnpm test:utils
```

Run tests with coverage.

An HTTP server is then started to serve coverage files from `./coverage` folder.

⚠️ You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.

```bash
test:coverage:serve
```

---

### Contributing
Expand Down
129 changes: 111 additions & 18 deletions __tests__/format.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InSeconds } from '@/common'
import { formatLocaleDate, secondsToUnit } from '@/format'
import formatDate from '@/format/formatDate'
import formatRelativeTime from '@/format/formatRelativeTime'
import { formatDate } from '@/format/formatDate'
import { formatRelativeTime } from '@/format/formatRelativeTime'


describe( 'formatDate', () => {
Expand All @@ -15,16 +15,71 @@ describe( 'formatDate', () => {


it( 'formats a date with tokenized parameter', () => {
const date = new Date( '2024-04-20T16:20:00.000Z' )
const tokens = "d - j - D - J - l - w - N - S - z - b - W - m - n - M - F - E - t - L - Y - y - a - A - g - G - h - H - i - s - v - e - O - P - Z - c - U"
const expected = "20 - 20 - Sat - S - Saturday - 6 - 6 - th - 111 - in the evening - 16 - 04 - 4 - Apr - April - A - 30 - 1 - 2024 - 24 - pm - PM - 6 - 18 - 06 - 18 - 20 - 00 - 0 - Europe/Rome - +0200 - +02:00 - 7200 - 2024-04-20T16:20:00.000Z - 1713630000"
const date = new Date( '2024-04-20T16:20:35.420Z' )
const tokensMap = {
d: '20',
j: '20',
D: 'Sat',
J: 'S',
l: 'Saturday',
w: '6',
N: '6',
S: 'th',
z: '111',
b: 'in the evening',
W: '16',
m: '04',
n: '4',
M: 'Apr',
F: 'April',
E: 'A',
t: '30',
L: '1',
Y: '2024',
y: '24',
a: 'pm',
A: 'PM',
B: '723',
g: '6',
G: '18',
h: '06',
H: '18',
i: '20',
s: '35',
v: '420',
u: '420000',
e: 'Europe/Rome',
C: 'Central European Summer Time',
K: 'Central European Time',
Q: 'GMT+02:00',
q: 'GMT+0200',
R: 'GMT+2',
V: 'Italy Time',
T: 'GMT+2',
I: '1',
O: '+0200',
P: '+02:00',
p: '+02:00',
Z: '7200',
c: '2024-04-20T16:20:35.420Z',
r: 'Sat Apr 20 2024 18:20:35 GMT+0200 (Central European Summer Time)',
U: '1713630035.42',
}
const tokens = Object.keys( tokensMap ).join( ' - ' )
const expected = Object.values( tokensMap ).join( ' - ' )

expect( formatDate( date, tokens, 'en-US', 'Europe/Rome' ) )
.toBe( expected )

} )


it( 'returns Z instead of +00:00 with `p` token', () => {
expect( formatDate( new Date( '2024-04-20T16:20:35.420Z' ), 'p', 'en-US', 'UTC' ) )
.toBe( 'Z' )
} )


it( 'formats a date with Intl.DateTimeFormatOptions parameter', () => {
const formatted = (
formatDate( '2024-11-24', {
Expand All @@ -37,6 +92,14 @@ describe( 'formatDate', () => {
} )


it( 'formats a date with the current Timezone', () => {

expect( formatDate( '2024-11-24T21:20:00.000Z', 'e', 'en-US' ) )
.toBeTruthy() // cannot test it's result since it depends on the current machine Timezone.

} )


it( 'formats a date with the given Timezone', () => {

expect( formatDate( '2024-11-24T21:20:00.000Z', 'Y-m-d g.i A', 'en-US', 'America/New_York' ) )
Expand All @@ -62,21 +125,36 @@ describe( 'secondsToUnit', () => {

it( 'converts seconds to the right units', () => {

const result = secondsToUnit( total )
expect( secondsToUnit( total ) )
.toStrictEqual( expect.objectContaining( {
years : 3,
months : 2,
weeks : 3,
days : 4,
hours : 4,
minutes : 35,
seconds : 23,
milliseconds : 230,
microseconds : 245,
} ) )

const pass = (
result.years === 3 &&
result.months === 2 &&
result.weeks === 3 &&
result.days === 4 &&
result.hours === 4 &&
result.minutes === 35 &&
result.seconds === 23 &&
result.milliseconds === 230 &&
result.microseconds === 245
)
} )

expect( pass ).toBe( true )

it( 'converts seconds to the right units with negative value', () => {

expect( secondsToUnit( total * -1 ) )
.toStrictEqual( expect.objectContaining( {
years : -3,
months : -2,
weeks : -3,
days : -4,
hours : -4,
minutes : -35,
seconds : -23,
milliseconds : -230,
microseconds : -245,
} ) )

} )

Expand All @@ -101,12 +179,27 @@ describe( 'secondsToUnit', () => {

} )


it( 'skips weeks with negative value', () => {

const result = secondsToUnit( total * -1, true )

expect( result.weeks ).toBe( null )
expect( result.days ).toBe( nDays * -1 )

} )

} )

describe( 'formatLocaleDate', () => {

const date = new Date( '2024-04-20T14:20:00.000Z' )

it( 'formats the current Date', () => {
expect( typeof formatLocaleDate() ).toBe( 'string' )
} )


it( 'formats a date with custom locale', () => {
expect( formatLocaleDate( date, 'it-IT' ) ).toBe( '20 aprile 2024' )
} )
Expand Down
14 changes: 14 additions & 0 deletions __tests__/jest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe( 'Jest', () => {

it( 'loads .env files correctly', () => {
// Arrange ...
const envVar = process.env.VAR_LOADED

// Act ...
const isLoaded = envVar === 'true'

// Assert ...
expect( isLoaded ).toBe( true )
} )

} )
Loading
Loading