Provide primitives for "if this file exists, then so should this" sort of rules
See original GitHub issueBasically, provide some kind of way to simplify rules like these
// Check that every file touched has a corresponding test file
const correspondingTestsForModifiedFiles = modifiedFiles.map(f => {
const newPath = path.dirname(f);
const name = path.basename(f);
return `${newPath}/__tests__/${name}`;
});
const testFilesThatDontExist = correspondingTestsForModifiedFiles
.filter(f => !f.includes('__stories__')) // skip stories
.filter(f => !fs.existsSync(f));
if (testFilesThatDontExist.length > 0 && !skipTests) {
const output = `Missing Test Files:
${testFilesThatDontExist.map(f => `- \`${f}\``).join('\n')}
If these files are supposed to not exist, please update your PR body to include "Skip New Tests".`;
warn(output);
}
// Find changed React components
const changedComponents = modifiedFiles.filter(file => {
const content = fs.readFileSync(file).toString();
return content.includes('React');
});
// Check for images in PR description if new components added
if (changedComponents.length > 0 && !skipVisualDiff && !hasScreenShots) {
const output = `Should there be images to represent these components:
${changedComponents.map(f => `- \`${f}\``).join('\n')}
If these changes are not visual, please update your PR body to include "Skip Visual Diff".`;
warn(output);
}
// Check that every component touched has a corresponding story
const correspondingStoriesForChangedComponents = uniq(
changedComponents.map(f => {
const newPath = path.dirname(f);
return `${newPath}/__stories__/index.js`;
})
);
const missingStories = correspondingStoriesForChangedComponents.filter(
f => !fs.existsSync(f)
);
and
// Custom modifiers for people submitting PRs to be able to say "skip this"
const trivialPR = bodyAndTitle.includes("trivial")
const acceptedNoTests = bodyAndTitle.includes("skip new tests")
const typescriptOnly = (file: string) => includes(file, ".ts")
const filesOnly = (file: string) => fs.existsSync(file) && fs.lstatSync(file).isFile()
// Custom subsets of known files
const modifiedAppFiles = modified.filter(p => includes(p, "lib/")).filter(p => filesOnly(p) && typescriptOnly(p))
// Modified or Created can be treated the same a lot of the time
const touchedFiles = modified.concat(danger.git.created_files).filter(p => filesOnly(p))
const touchedAppOnlyFiles = touchedFiles.filter(
p => includes(p, "src/lib/") && !includes(p, "__tests__") && typescriptOnly(p)
)
const touchedComponents = touchedFiles.filter(p => includes(p, "src/lib/components") && !includes(p, "__tests__"))
// Rules
// When there are app-changes and it's not a PR marked as trivial, expect
// there to be CHANGELOG changes.
const changelogChanges = includes(modified, "CHANGELOG.md")
if (modifiedAppFiles.length > 0 && !trivialPR && !changelogChanges) {
fail("No CHANGELOG added.")
}
// Check that every file touched has a corresponding test file
const correspondingTestsForAppFiles = touchedAppOnlyFiles.map(f => {
const newPath = path.dirname(f)
const name = path.basename(f).replace(".ts", "-tests.ts")
return `${newPath}/__tests__/${name}`
})
// New app files should get new test files
// Allow warning instead of failing if you say "Skip New Tests" inside the body, make it explicit.
const testFilesThatDontExist = correspondingTestsForAppFiles
.filter(f => !f.includes("Index-tests.tsx")) // skip indexes
.filter(f => !f.includes("types-tests.ts")) // skip type definitions
.filter(f => !f.includes("__stories__")) // skip stories
.filter(f => !f.includes("AppRegistry")) // skip registry, kinda untestable
.filter(f => !f.includes("Routes")) // skip routes, kinda untestable
.filter(f => !f.includes("NativeModules")) // skip modules that are native, they are untestable
.filter(f => !f.includes("lib/relay/")) // skip modules that are native, they are untestable
.filter(f => !f.includes("Storybooks/")) // skip modules that are native, they are untestable
.filter(f => !fs.existsSync(f))
if (testFilesThatDontExist.length > 0) {
const callout = acceptedNoTests ? warn : fail
const output = `Missing Test Files:
${testFilesThatDontExist.map(f => `- \`${f}\``).join("\n")}
If these files are supposed to not exist, please update your PR body to include "Skip New Tests".`
callout(output)
}
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:8 (8 by maintainers)
Top Results From Across the Web
Manipulating File Names - Lugaru Software Ltd.
First (for either primitive), if the specified file name is an absolute pathname, Epsilon simply checks to see if the file exists, and...
Read more >How to check if a variable's type is primitive? - Stack Overflow
So by this rule, type and function are not primitive? I'm sure there is a way for OP to rephrase his/her code so...
Read more >Polar Syntax - Oso Library Documentation
Rules allow you to express conditional statements ("if this then that"). A rule in Polar takes the form HEAD if BODY; where HEAD...
Read more >Extensibility - Fluent Assertions
It's the returned assertions class that provides the actual assertion methods. ... FailWith("You can't assert a file exist if you don't pass a...
Read more >Chapter 5. The Rule Language - JBoss.org
In a DRL file you can have multiple rules, queries and functions, as well as some ... 1: rule one 2: when 3:...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Micromatch is a good call, because jest uses it - and there’s probably a big overlap in Jest and Danger users.
My preference is always to keep the Danger dep tree matching with Jest when I have any choices to make.
OK, so, let’s vendor in the micromatch index.js into danger somewhere, add it to the git DSL - if you get it working in a PR, I can handle all of the documentation side of it and wrap it up
No I think you’re a bit off base , Danger doesn’t provide rules - Danger provides tools to make rules. This issue is about providing another API function which does a good job of making it easy to do file checking.
An example of resolving this issue is chainsmoker by @paulmelnikow
Perhaps Danger could depend on it, and expose the chainsmoker as default export: