Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## [0.0.6]

- rename testEmptyLine to isEmptyLine, change its signature to accept options object with greedy property

## [0.0.5]

- export Newline type
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

Fetch and parse ranges of CSV file.

## Early version

This is an early version. The API may change completely:

- until version 0.1.0, breaking changes may be introduced at any time.
- from version 0.1.0 to 1.0.0, breaking changes will be introduced only in minor versions.
- from version 1.0.0, breaking changes will be introduced only in major versions.

## Install

```bash
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "csv-range",
"version": "0.0.5",
"version": "0.0.6",
"description": "Parse ranges of a CSV file.",
"type": "module",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { parseText } from './text'
export type { Newline, ParseError, ParseMeta, ParseResult } from './types'
export { parseURL } from './url'
export { testEmptyLine } from './utils'
export { isEmptyLine } from './utils'
4 changes: 2 additions & 2 deletions src/options/delimiter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { parse } from '../parser'
import type { Newline } from '../types'
import { testEmptyLine } from '../utils'
import { isEmptyLine } from '../utils'
import { BAD_DELIMITERS, RECORD_SEP, UNIT_SEP } from './constants'

/**
Expand Down Expand Up @@ -50,7 +50,7 @@ export function guessDelimiter(text: string, newline?: Newline, comments?: boole
break
}
// always remove empty lines from consideration
if (testEmptyLine(row, true)) {
if (isEmptyLine(row)) {
continue
}
nonEmptyLinesCount++
Expand Down
9 changes: 5 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ export function escapeRegExp(string: string) {
}

/**
* Test if the string array is an empty line
* Check if the string array is an empty line
* @param s The string array
* @param skipEmptyLines If 'greedy', trims all spaces to test for emptiness
* @param options Options
* @param options.greedy If true, trims all spaces to test for emptiness. Defaults to false.
* @returns Whether the line is empty
*/
export function testEmptyLine(s: string[], skipEmptyLines?: 'greedy' | boolean) {
return skipEmptyLines === 'greedy' ? s.join('').trim() === '' : 0 in s && s.length === 1 && s[0].length === 0
export function isEmptyLine(s: string[], options: { greedy?: boolean } = {}) {
return options.greedy ? s.join('').trim() === '' : 0 in s && s.length === 1 && s[0].length === 0
}
10 changes: 5 additions & 5 deletions tests/text.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest'

import { parseText } from '../src/text'
import { testEmptyLine } from '../src/utils'
import { isEmptyLine } from '../src/utils'
import { PARSE_TESTS } from './cases'

describe('parseText', () => {
Expand Down Expand Up @@ -34,17 +34,17 @@ describe('parseText', () => {
{ description: ', with empty text', text: '', expected: [] },
{ description: ', with first line only whitespace', text: ' \na,b,c', expected: [[' '], ['a', 'b', 'c']] },
{ description: ', with comments', text: '#comment line 1\n#comment line 2\na,b,c\n#comment line 3\nd,e,f\n', expected: [['a', 'b', 'c'], ['d', 'e', 'f']] },
])('works together with testEmptyLine to skip empty lines$description', ({ text, expected }) => {
const results = [...parseText(text, { comments: '#' })].filter(({ row }) => !testEmptyLine(row, true))
])('works together with isEmptyLine to skip empty lines$description', ({ text, expected }) => {
const results = [...parseText(text, { comments: '#' })].filter(({ row }) => !isEmptyLine(row))

expect(results.map(({ row }) => row)).toEqual(expected)
})

it.for([
{ description: '', text: 'a,b\n\n,\nc,d\n , \n""," "\n\t,\t\n,,,,\n', expected: [['a', 'b'], ['c', 'd']] },
{ description: ', with quotes and delimiters as content', text: 'a,b\n\n,\nc,d\n" , ",","\n""" """,""""""\n\n\n', expected: [['a', 'b'], ['c', 'd'], [' , ', ','], ['" "', '""']] },
])('works together with testEmptyLine to skip empty lines, in greedy mode$description', ({ text, expected }) => {
const results = [...parseText(text)].filter(({ row }) => !testEmptyLine(row, 'greedy'))
])('works together with isEmptyLine to skip empty lines, in greedy mode$description', ({ text, expected }) => {
const results = [...parseText(text)].filter(({ row }) => !isEmptyLine(row, { greedy: true }))

expect(results.map(({ row }) => row)).toEqual(expected)
})
Expand Down
27 changes: 14 additions & 13 deletions tests/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'

import { decode, escapeRegExp, testEmptyLine, toUrl } from '../src/utils'
import { decode, escapeRegExp, isEmptyLine, toUrl } from '../src/utils'

describe('toUrl', () => {
it('creates a valid blob URL and revokes it', async () => {
Expand Down Expand Up @@ -59,20 +59,21 @@ describe('escapeRegExp', () => {
})
})

describe('testEmptyLine', () => {
it.for([true, false, undefined])('detects empty lines correctly with skipEmptyLines being: %s (same behavior!)', (skipEmptyLines) => {
expect(testEmptyLine([''], skipEmptyLines)).toBe(true)
expect(testEmptyLine(['\t'], skipEmptyLines)).toBe(false)
expect(testEmptyLine([' '], skipEmptyLines)).toBe(false)
expect(testEmptyLine(['', ''], skipEmptyLines)).toBe(false)
expect(testEmptyLine(['data'], skipEmptyLines)).toBe(false)
describe('isEmptyLine', () => {
it.for([undefined, {}, { greedy: false }])('detects empty lines correctly with options being: %s (same behavior!)', (options) => {
expect(isEmptyLine([''], options)).toBe(true)
expect(isEmptyLine(['\t'], options)).toBe(false)
expect(isEmptyLine([' '], options)).toBe(false)
expect(isEmptyLine(['', ''], options)).toBe(false)
expect(isEmptyLine(['data'], options)).toBe(false)
})

it('detects empty lines correctly with skipEmptyLines as "greedy"', () => {
expect(testEmptyLine([''], 'greedy')).toBe(true)
expect(testEmptyLine([' '], 'greedy')).toBe(true)
expect(testEmptyLine([' \t', ' '], 'greedy')).toBe(true)
expect(testEmptyLine(['data'], 'greedy')).toBe(false)
it('detects empty lines correctly with options {greedy: true}', () => {
const options = { greedy: true }
expect(isEmptyLine([''], options)).toBe(true)
expect(isEmptyLine([' '], options)).toBe(true)
expect(isEmptyLine([' \t', ' '], options)).toBe(true)
expect(isEmptyLine(['data'], options)).toBe(false)
})
})

Expand Down