Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

automutate

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

automutate - npm Package Compare versions

Comparing version 0.3.1 to 0.3.3

test/cases/casesCrawler.js

4

package.json
{
"name": "automutate",
"version": "0.3.1",
"description": "Generic framework to fix linting errors in code.",
"version": "0.3.3",
"description": "Applies waves of mutations provided by other tools, such as linters.",
"index": "lib/index.js",

@@ -6,0 +6,0 @@ "directories": {

@@ -5,5 +5,5 @@ # automutate

There are [various](https://github.com/eslint/eslint) [linters](https://github.com/palantir/tslint) [in](https://github.com/stylelint/stylelint) [the](https://github.com/lesshint/lesshint) [world](https://github.com/sasstools/sass-lint) and most are adding or have added ways to `--fix` rule failures automatically.
There are [many](https://github.com/eslint/eslint) [linters](https://github.com/palantir/tslint) [in](https://github.com/stylelint/stylelint) [the](https://github.com/lesshint/lesshint) [world](https://github.com/sasstools/sass-lint) and most are adding or have added ways to `--fix` rule failures automatically.
This is great but hard to do for a couple of reasons:
* **Overlapping rule failures** - The possibility of mutations appling to overlapping sets of characters requires logic to handle applying one, then re-runing linting, and so on.
* **Overlapping rule failures** - The possibility of mutations appling to overlapping sets of characters requires logic to handle applying one, then re-running linting, and so on.
* **Code bloat verses duplication** - Most linters either provide hooks to apply fixes themselves (which can result in code bloat) or have an external project (which duplicates logic for finding rules).

@@ -51,3 +51,4 @@

"type": "text-insert"
}]
}
]
}

@@ -54,0 +55,0 @@ ```

@@ -6,3 +6,3 @@ "use strict";

/**
* Generates AutoMutator instances for testing.
* Creates AutoMutators for testing.
*/

@@ -19,10 +19,13 @@ class AutoMutatorFactory {

/**
* @param Name of a .less file to automutate.
* Creates an AutoMutator for testing.
*
* @param fileName Name of a .less file to automutate.
* @param settingsFileName Name of its settings file, if any.
* @returns A new AutoMutator for testing.
*/
create(fileName) {
create(fileName, settingsFileName) {
const logger = new logger_1.Logger();
return new automutator_1.AutoMutator(new fileMutationsApplier_1.FileMutationsApplier(logger), this.mutationsProviderFactory(fileName), logger);
return new automutator_1.AutoMutator(new fileMutationsApplier_1.FileMutationsApplier(logger), this.mutationsProviderFactory(fileName, settingsFileName), logger);
}
}
exports.AutoMutatorFactory = AutoMutatorFactory;

@@ -10,10 +10,11 @@ import { AutoMutator } from "../../lib/automutator";

* @param fileName Name of a file to mutate.
* @param settingsFileName Name of its settings file, if any.
* @returns A mutation provider for the file.
*/
export interface IMutationsProviderFactory {
(fileName: string): IMutationsProvider;
(fileName: string, settingsFileName?: string): IMutationsProvider;
}
/**
* Generates AutoMutator instances for testing.
* Creates AutoMutators for testing.
*/

@@ -36,6 +37,9 @@ export class AutoMutatorFactory {

/**
* @param Name of a .less file to automutate.
* Creates an AutoMutator for testing.
*
* @param fileName Name of a .less file to automutate.
* @param settingsFileName Name of its settings file, if any.
* @returns A new AutoMutator for testing.
*/
public create(fileName: string) {
public create(fileName: string, settingsFileName?: string) {
const logger = new Logger();

@@ -45,5 +49,5 @@

new FileMutationsApplier(logger),
this.mutationsProviderFactory(fileName),
this.mutationsProviderFactory(fileName, settingsFileName),
logger);
}
}

@@ -8,9 +8,9 @@ # Case testers

1. A method to create a mutation provider for each file.
2. The file extension to read files in test cases from.
2. Names of files that test cases are composed of.
Its `create` method takes in a a directory path containing test case directories.
Its `describe` method takes in a a directory path containing test case directories.
## Sample Usage
Define a test file with TypeScript similar to the following:
Define a test file with JavaScript or TypeScript similar to the following:

@@ -25,7 +25,13 @@ ```typescript

const testsFactory = new TestsFactory(
fileName => new MyMutationsProvider(fileName),
".txt");
(fileName, settingsFileName) => new MyMutationsProvider(fileName, settingsFileName)
{
actual: "actual.txt",
expected: "expected.txt",
original: "original.txt",
settings: "settings.txt"
});
await testsFactory.create(path.join(__dirname, "cases"));
await testsFactory.describe(path.join(__dirname, "cases"));
})();
```

@@ -32,0 +38,0 @@

@@ -30,3 +30,3 @@ "use strict";

* @returns A Promise for running the test case.
* @todo Promise-ify this
* @todo Make this async (parallel)...
*/

@@ -37,4 +37,4 @@ run() {

yield this.arrangeFiles();
const autoMutator = this.autoMutatorFactory.create(this.settings.actual);
const expectedContents = fs.readFileSync(this.settings.expected).toString();
const autoMutator = this.autoMutatorFactory.create(this.settings.actual, this.settings.settings);
// Act

@@ -48,13 +48,10 @@ yield autoMutator.run();

/**
* Resets the expected file to the original file contents.
* Resets the test case files.
*
* @returns A Promise for resetting the expected file.
* @todo How to react to the reader finishing piping?
* @returns A Promise for the resetting the test case files.
* @todo Make this async (parallel)...
*/
arrangeFiles() {
return new Promise(resolve => {
const reader = fs.createReadStream(this.settings.original);
reader.on("close", resolve);
reader.pipe(fs.createWriteStream(this.settings.actual));
setTimeout(() => reader.close(), 100);
return __awaiter(this, void 0, void 0, function* () {
fs.writeFileSync(this.settings.actual, fs.readFileSync(this.settings.original));
});

@@ -61,0 +58,0 @@ }

@@ -8,7 +8,7 @@ import { expect } from "chai";

/**
* Settings for a single test case.
* File names or contents for test cases.
*/
export interface ITestCaseSettings {
/**
* File path for the mutation result.
* File name or contents for the mutation result.
*/

@@ -18,3 +18,3 @@ actual: string;

/**
* File path for what the mutation result should be.
* File name or contents for what the mutation result should be.
*/

@@ -24,5 +24,10 @@ expected: string;

/**
* File path for the original file contents.
* File name or contents for the original file contents.
*/
original: string;
/**
* File name or contents for the settings file.
*/
settings: string;
}

@@ -35,10 +40,10 @@

/**
* Settings for the test case.
* Generates AutoMutator instances for testing.
*/
private readonly settings: ITestCaseSettings;
private readonly autoMutatorFactory: AutoMutatorFactory;
/**
* Generates AutoMutator instances for testing.
* Settings for the test case.
*/
private readonly autoMutatorFactory: AutoMutatorFactory;
private readonly settings: ITestCaseSettings;

@@ -60,3 +65,3 @@ /**

* @returns A Promise for running the test case.
* @todo Promise-ify this
* @todo Make this async (parallel)...
*/

@@ -66,4 +71,4 @@ public async run(): Promise<void> {

await this.arrangeFiles();
const autoMutator: AutoMutator = this.autoMutatorFactory.create(this.settings.actual);
const expectedContents: string = fs.readFileSync(this.settings.expected).toString();
const autoMutator: AutoMutator = this.autoMutatorFactory.create(this.settings.actual, this.settings.settings);

@@ -79,18 +84,10 @@ // Act

/**
* Resets the expected file to the original file contents.
* Resets the test case files.
*
* @returns A Promise for resetting the expected file.
* @todo How to react to the reader finishing piping?
* @returns A Promise for the resetting the test case files.
* @todo Make this async (parallel)...
*/
private arrangeFiles(): Promise<void> {
return new Promise<void>(resolve => {
const reader = fs.createReadStream(this.settings.original);
reader.on("close", resolve);
reader.pipe(fs.createWriteStream(this.settings.actual));
setTimeout(() => reader.close(), 100);
});
private async arrangeFiles(): Promise<void> {
fs.writeFileSync(this.settings.actual, fs.readFileSync(this.settings.original));
}
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
const fs = require("fs");
const path = require("path");
const testCaseFactory_1 = require("./testCaseFactory");
const autoMutatorFactory_1 = require("./autoMutatorFactory");
const casesCrawler_1 = require("./casesCrawler");
const testCase_1 = require("./testCase");
/**

@@ -24,24 +16,41 @@ * Creates tests for provided cases.

*/
constructor(mutationsProviderFactory, extension) {
this.caseFactory = new testCaseFactory_1.TestCaseFactory(new autoMutatorFactory_1.AutoMutatorFactory(mutationsProviderFactory), extension);
constructor(mutationsProviderFactory, settings) {
this.autoMutatorFactory = new autoMutatorFactory_1.AutoMutatorFactory(mutationsProviderFactory);
this.settings = settings;
this.casesCrawler = new casesCrawler_1.CasesCrawler(this.settings.original, (directoryName) => this.runTest(directoryName));
}
/**
* Creates tests for the a cases directory.
* Describes tests for the cases directory.
*
* @param casesPath Path to the test cases.
* @returns A Promise for creating tests for the cases directory.
* @todo Promise-ify this.
*/
create(casesPath) {
const caseNames = fs.readdirSync(casesPath);
describe("cases", () => {
for (const caseName of caseNames) {
it(caseName, () => __awaiter(this, void 0, void 0, function* () {
return (yield this.caseFactory.create(path.join(casesPath, caseName)))
.run();
}));
}
});
describe(casesPath) {
this.casesCrawler.crawl("cases", casesPath);
}
/**
* Creates and runs a test case.
*
* @param casePath Path to the test case.
* @returns A Promise for running the test case.
*/
runTest(casePath) {
return (new testCase_1.TestCase(this.createTestCaseSettings(casePath), this.autoMutatorFactory))
.run();
}
/**
* Creates settings for a test case.
*
* @param casePath Path to a test case.
* @returns Settings for the test case.
*/
createTestCaseSettings(casePath) {
return {
actual: path.join(casePath, this.settings.actual),
expected: path.join(casePath, this.settings.expected),
original: path.join(casePath, this.settings.original),
settings: path.join(casePath, this.settings.settings)
};
}
}
exports.TestsFactory = TestsFactory;

@@ -1,7 +0,6 @@

import * as fs from "fs";
import * as path from "path";
import { TestCaseFactory } from "./testCaseFactory";
import { IMutationsProviderFactory } from "./autoMutatorFactory";
import { AutoMutatorFactory } from "./autoMutatorFactory";
import { AutoMutatorFactory, IMutationsProviderFactory } from "./autoMutatorFactory";
import { CasesCrawler } from "./casesCrawler";
import { ITestCaseSettings, TestCase } from "./testCase";

@@ -15,5 +14,15 @@ /**

*/
private readonly caseFactory: TestCaseFactory;
private readonly autoMutatorFactory: AutoMutatorFactory;
/**
* Settings for the test cases.
*/
private readonly settings: ITestCaseSettings;
/**
* Crawls a directory structure for test case settings.
*/
private readonly casesCrawler: CasesCrawler;
/**
* Initializes a new instance of the TestsFactory class.

@@ -24,27 +33,45 @@ *

*/
public constructor(mutationsProviderFactory: IMutationsProviderFactory, extension: string) {
this.caseFactory = new TestCaseFactory(
new AutoMutatorFactory(mutationsProviderFactory),
extension);
public constructor(mutationsProviderFactory: IMutationsProviderFactory, settings: ITestCaseSettings) {
this.autoMutatorFactory = new AutoMutatorFactory(mutationsProviderFactory);
this.settings = settings;
this.casesCrawler = new CasesCrawler(
this.settings.original,
(directoryName: string): Promise<void> => this.runTest(directoryName));
}
/**
* Creates tests for the a cases directory.
* Describes tests for the cases directory.
*
* @param casesPath Path to the test cases.
* @returns A Promise for creating tests for the cases directory.
* @todo Promise-ify this.
*/
public create(casesPath: string): void {
const caseNames: string[] = fs.readdirSync(casesPath);
public describe(casesPath: string): void {
this.casesCrawler.crawl("cases", casesPath);
}
describe("cases", (): void => {
for (const caseName of caseNames) {
it(caseName, async (): Promise<void> => {
return (await this.caseFactory.create(path.join(casesPath, caseName)))
.run();
});
}
});
/**
* Creates and runs a test case.
*
* @param casePath Path to the test case.
* @returns A Promise for running the test case.
*/
private runTest(casePath: string): Promise<void> {
return (new TestCase(this.createTestCaseSettings(casePath), this.autoMutatorFactory))
.run();
}
/**
* Creates settings for a test case.
*
* @param casePath Path to a test case.
* @returns Settings for the test case.
*/
private createTestCaseSettings(casePath: string): ITestCaseSettings {
return {
actual: path.join(casePath, this.settings.actual),
expected: path.join(casePath, this.settings.expected),
original: path.join(casePath, this.settings.original),
settings: path.join(casePath, this.settings.settings)
};
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc