Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
A helper to recursively read and write text files to a specified directory.
It's a pain to write tests for tools that interact with the filesystem. It would be useful to write assertions that look something like:
expect(someDirectory.read()).toEqual({
'file1.txt': 'some info',
'file2.log': 'something logged',
nested: {
sub: {
directory: {
'deeply-nested-file.sql': 'SELECT * FROM abc'
},
},
},
})
Similarly, as part of test setup, you might want to write several files, e.g.:
write({
migrations: {
'migration1.sql': 'create table one(id text)',
'migration2.sql': 'create table two(id text)',
down: {
'migration1.sql': 'drop table one',
'migration2.sql': 'drop table two',
},
},
})
The problem is that usually, you have to write a recursive directory-walker function, an object-to-filepath converter function, a nested-object-getter-function and a few more functions that tie them all together.
Then, if you have the energy, you should also write a function that cleans up any extraneous files after tests have been run. Or, you can pull in several dependencies that do some of these things for you, then write some functions that tie them together.
Now, you can just use fs-syncer
, which does all of the above. Here's the API:
import {fsSyncer} from 'fs-syncer'
const syncer = fsSyncer(__dirname + '/migrations', {
'migration1.sql': 'create table one(id text)',
'migration2.sql': 'create table two(id text)',
down: {
'migration1.sql': 'drop table one',
'migration2.sql': 'drop table two',
},
})
syncer.sync() // replaces all content in `./migrations` with what's described in the target state
syncer.read() // returns the filesystem state as an object, in the same format as the target state
// write a file that's not in part of the target state
require('fs').writeFileSync(__dirname + '/migrations/extraneous.txt', 'abc', 'utf8')
syncer.read() // includes `extraneous.txt: 'abc'`
syncer.sync() // 'extraneous.txt' will now have been removed
syncer.write() // like `syncer.sync()`, but doesn't remove extraneous files
⚠️⚠️⚠️ This feature is new and experimental - if you try it out, be aware that the API is in flux. Feedback is welcome! ⚠️⚠️⚠️
If you happen to want to use this in a jest test, there's an opinionated helper which allows you to avoid supplying a baseDir
parameter.
Let's say you want to test a file modification tool, which appends // comments
to all the files it finds under a certain directory, and also creates a log file:
import {testFixture} from 'fs-syncer'
import {fileModificationToolThatYouWantToTest} from '../src/your-library'
test('files are modified', async () => {
const fixture = testFixture({
expect,
targetState: {
'file1.txt': 'hello I am a file',
nested: {
'file2.txt': 'I am also a file',
}
}
})
fixture.sync()
await fileModificationToolThatYouWantToTest.run({
directory: fixture.baseDir,
logFile: 'abc.log',
})
expect(fixture.yaml()).toMatchInlineSnapshot()
})
fixture.yaml()
is a helper that returns a yaml string representing the file tree. It's intended to be human-readable and familiar, and should not be relied on to be valid yaml, it's mostly for test snapshots.
Let's assume the test file containing this test is called my-test-file.test.ts
. When run, the above test will generate a directory fixtures/my-test-file.test.ts/files-are-modified
next to the test file. The directory structure described in targetState
will be created inside that folder. The test above might end up looking something like when run:
import {testFixture} from 'fs-syncer'
import {fileModificationToolThatYouWantToTest} from '../src/your-library'
test('files are modified', async () => {
const fixture = testFixture({
expect,
targetState: {
'file1.txt': 'hello I am a file',
nested: {
'file2.txt': 'I am also a file',
}
}
})
fixture.sync()
await fileModificationToolThatYouWantToTest.run({
directory: fixture.baseDir,
logFile: 'abc.log',
})
expect(fixture.yaml()).toMatchInlineSnapshot(
`"---
abc.log: |-
added content to file1.txt
added content to nested/file2.txt
file1.txt: |-
hello I am a file
// this content was auto-generated by the tool
nested:
file2.txt: |-
hello I am a file
// this content was auto-generated by the tool
"`
)
})
Buffer
s. The library assumes you are solely dealing with utf8 strings.This isn't a mocking library. There's no magic under the hood, it just calls fs.readFileSync
, fs.writeFileSync
and fs.mkdirSync
directly. Which means you can use it anywhere - it could even be a runtime dependency as a wrapper for the fs
module. And using it doesn't have any weird side-effects like breaking jest snapshot testing. Not being a mocking library means you could use it in combination with mock-fs, if you really wanted.
FAQs
A helper to recursively read and write text files to a specified directory
The npm package fs-syncer receives a total of 411 weekly downloads. As such, fs-syncer popularity was classified as not popular.
We found that fs-syncer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.