cspell-lib
Advanced tools
Comparing version 2.0.1 to 2.0.2
import * as Rx from 'rxjs/Rx'; | ||
export declare function lineReaderRx(filename: string, encoding?: string): Rx.Observable<string>; | ||
export declare function textFileStreamRx(filename: string, encoding?: string): Rx.Observable<string>; | ||
export declare function textFileReadLineRx(filename: string, encoding?: string): Rx.Observable<string>; | ||
export declare function stringsToLinesRx(strings: Rx.Observable<string>): Rx.Observable<string>; |
@@ -10,4 +10,5 @@ "use strict"; | ||
const zlib = require("zlib"); | ||
const readline = require("readline"); | ||
function lineReaderRx(filename, encoding) { | ||
return stringsToLinesRx(textFileStreamRx(filename, encoding)); | ||
return textFileReadLineRx(filename, encoding); | ||
} | ||
@@ -32,2 +33,21 @@ exports.lineReaderRx = lineReaderRx; | ||
exports.textFileStreamRx = textFileStreamRx; | ||
function textFileReadLineRx(filename, encoding = 'UTF-8') { | ||
const subject = new Rx.Subject(); | ||
const fnError = (e) => subject.error(e); | ||
const pipes = []; | ||
if (filename.match(/\.gz$/i)) { | ||
pipes.push(zlib.createGunzip()); | ||
} | ||
pipes.push(iconv.decodeStream(encoding)); | ||
const fileStream = fs.createReadStream(filename); | ||
fileStream.on('error', fnError); | ||
const stream = pipes.reduce((s, p) => s.pipe(p).on('error', fnError), fileStream); | ||
const rl = readline.createInterface({ | ||
input: stream, | ||
}); | ||
rl.on('close', () => subject.complete()); | ||
rl.on('line', (text) => subject.next(text)); | ||
return subject; | ||
} | ||
exports.textFileReadLineRx = textFileReadLineRx; | ||
function stringsToLinesRx(strings) { | ||
@@ -34,0 +54,0 @@ return Rx.Observable.concat(strings, Rx.Observable.of('\n')) |
{ | ||
"name": "cspell-lib", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "A library of useful functions used across various cspell tools.", | ||
@@ -17,3 +17,3 @@ "main": "dist/index.js", | ||
"coverage": "NODE_ENV=test nyc npm run test-ts", | ||
"test-ts": "rimraf temp ; NODE_ENV=test mocha --compilers ts:ts-node/register --recursive --bail \"src/**/*.test.ts\"", | ||
"test-ts": "rimraf temp ; NODE_ENV=test mocha --require ts-node/register --recursive --bail \"src/**/*.test.ts\"", | ||
"test": "rimraf temp ; mocha --recursive ./dist/**/*.test.js" | ||
@@ -35,21 +35,21 @@ }, | ||
"devDependencies": { | ||
"@types/chai": "^4.0.4", | ||
"@types/fs-extra": "^4.0.3", | ||
"@types/chai": "^4.1.2", | ||
"@types/fs-extra": "^5.0.0", | ||
"@types/lorem-ipsum": "^1.0.2", | ||
"@types/mocha": "^2.2.44", | ||
"@types/node": "^8.0.47", | ||
"@types/mocha": "^2.2.48", | ||
"@types/node": "^9.4.6", | ||
"chai": "^4.1.2", | ||
"fs-extra": "^4.0.2", | ||
"fs-extra": "^5.0.0", | ||
"lorem-ipsum": "^1.0.4", | ||
"mocha": "^4.0.1", | ||
"nyc": "^11.3.0", | ||
"mocha": "^5.0.1", | ||
"nyc": "^11.5.0", | ||
"rimraf": "^2.6.2", | ||
"ts-node": "^3.3.0", | ||
"tslint": "^5.8.0", | ||
"typescript": "^2.5.3" | ||
"ts-node": "^5.0.0", | ||
"tslint": "^5.9.1", | ||
"typescript": "^2.7.2" | ||
}, | ||
"dependencies": { | ||
"iconv-lite": "^0.4.19", | ||
"rxjs": "^5.5.2", | ||
"rxjs-stream": "^1.0.4" | ||
"rxjs": "^5.5.6", | ||
"rxjs-stream": "^1.1.0" | ||
}, | ||
@@ -56,0 +56,0 @@ "nyc": { |
import { expect } from 'chai'; | ||
import * as fReader from './fileReader'; | ||
import * as Rx from 'rxjs/Rx'; | ||
import * as fs from 'fs'; | ||
import * as fs from 'fs-extra'; | ||
import * as path from 'path'; | ||
describe('Validate the fileReader', () => { | ||
const fileCities = path.join(__dirname, '..', '..', 'samples', 'cities.txt'); | ||
const sampleCities = [ | ||
'New York', | ||
'New Amsterdam', | ||
'Las Angles', | ||
'San Francisco', | ||
'New Delhi', | ||
'Mexico City', | ||
'London', | ||
'Paris', | ||
'' | ||
]; | ||
const samplePath = path.join(__dirname, '..', '..', 'samples'); | ||
const fileCities = path.join(samplePath, 'cities.txt'); | ||
const sampleFiles = [ | ||
'cities.txt', | ||
'cities.CRLF.txt', | ||
'cities.noEOL.txt', | ||
].map(f => path.join(samplePath, f)); | ||
@@ -56,11 +51,29 @@ it('tests stringsToLines', () => { | ||
it('tests reading the cities sample', () => { | ||
return fReader.lineReaderRx(fileCities) | ||
it('tests reading the cities sample', async () => { | ||
const lines = await fReader.lineReaderRx(fileCities) | ||
.toArray() | ||
.toPromise() | ||
.then(lines => { | ||
expect(lines).to.be.deep.equal(sampleCities); | ||
}); | ||
.toPromise(); | ||
const file = await fs.readFile(fileCities, 'utf8'); | ||
expect(lines).to.be.deep.equal(file.split('\n')); | ||
}); | ||
it('tests streamFileLineByLineRx', async () => { | ||
await Promise.all(sampleFiles | ||
.map(async filename => { | ||
const lines = await fReader.streamFileLineByLineRx(filename) | ||
.toArray() | ||
.toPromise(); | ||
const file = await fs.readFile(filename, 'utf8'); | ||
expect(lines, `compare to file: ${filename}`).to.be.deep.equal(file.split(/\r?\n/)); | ||
})); | ||
}); | ||
it('tests streamFileLineByLineRx 2', async () => { | ||
const lines = await fReader.streamFileLineByLineRx(__filename) | ||
.toArray() | ||
.toPromise(); | ||
const file = await fs.readFile(__filename, 'utf8'); | ||
expect(lines).to.be.deep.equal(file.split('\n')); | ||
}); | ||
it('test missing file', () => { | ||
@@ -67,0 +80,0 @@ return fReader.lineReaderRx(__filename + 'not.found') |
@@ -8,3 +8,11 @@ // cSpell:ignore curr | ||
import * as zlib from 'zlib'; | ||
import * as readline from 'readline'; | ||
const defaultEncoding = 'utf8'; | ||
/** | ||
* Reads a file line by line. The last value emitted by the Observable is always an empty string. | ||
* @param filename | ||
* @param encoding defaults to 'utf8' | ||
*/ | ||
export function lineReaderRx(filename: string, encoding?: string): Rx.Observable<string> { | ||
@@ -14,6 +22,7 @@ return stringsToLinesRx(textFileStreamRx(filename, encoding)); | ||
export function textFileStreamRx(filename: string, encoding: string = 'UTF-8'): Rx.Observable<string> { | ||
const subject = new Rx.Subject<string>(); | ||
const fnError = (e: Error) => subject.error(e); | ||
function prepareFileStream( | ||
filename: string, | ||
encoding: string, | ||
fnError: (e: Error) => void, | ||
) { | ||
const pipes: NodeJS.ReadWriteStream[] = []; | ||
@@ -27,8 +36,44 @@ if (filename.match(/\.gz$/i)) { | ||
const stream = pipes.reduce<NodeJS.ReadableStream>((s, p) => s.pipe(p!).on('error', fnError), fileStream); | ||
stream.on('end', () => subject.complete()); | ||
const streamData = Rx.Observable.fromEvent<string>(stream, 'data'); | ||
streamData.subscribe(s => subject.next(s)); | ||
return stream; | ||
} | ||
export function textFileStreamRx(filename: string, encoding: string = defaultEncoding): Rx.Observable<string> { | ||
const subject = new Rx.Subject<string>(); | ||
const fnError = (e: Error) => subject.error(e); | ||
const fnComplete = () => subject.complete(); | ||
const stream = prepareFileStream(filename, encoding, fnError); | ||
stream.on('end', fnComplete); | ||
stream.on('data', s => subject.next(s)); | ||
return subject; | ||
} | ||
/** | ||
* Emit a file line by line | ||
* @param filename full path to the file to read. | ||
* @param encoding defaults to 'utf8' | ||
*/ | ||
export function streamFileLineByLineRx(filename: string, encoding: string = defaultEncoding): Rx.Observable<string> { | ||
const subject = new Rx.Subject<string>(); | ||
let data = '.'; | ||
const fnError = (e: Error) => subject.error(e); | ||
const fnComplete = () => { | ||
// readline will consume the last newline without emitting an empty last line. | ||
// If the last data read contains a new line, then emit an empty string. | ||
if (data.match(/(?:(?:\r?\n)|(?:\r))$/)) { | ||
subject.next(''); | ||
} | ||
subject.complete(); | ||
}; | ||
const stream = prepareFileStream(filename, encoding, fnError); | ||
// We want to capture the last line. | ||
stream.on('data', d => data = d); | ||
const rl = readline.createInterface({ | ||
input: stream, | ||
terminal: false, | ||
}); | ||
rl.on('close', fnComplete); | ||
rl.on('line', (text: string) => subject.next(text)); | ||
return subject; | ||
} | ||
export function stringsToLinesRx(strings: Rx.Observable<string>): Rx.Observable<string> { | ||
@@ -44,2 +89,1 @@ return Rx.Observable.concat(strings, Rx.Observable.of('\n')) | ||
} | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
52561
528
Updatedrxjs@^5.5.6
Updatedrxjs-stream@^1.1.0