Repository: tivac/modular-css
Pull request #558 (2019-01-29 08:01:27)

feat: svelte processor arg & improved test coverage
<!--- Provide a general summary of your changes in the Title above -->

## Description
<!--- Describe your changes in detail -->
The svelte preprocessor can now take a `processor` arg. Also the test coverage around file invalidation for `<style>` is improved!

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

I like good tests & 100% coverage makes me feel warm and fuzzy even if it's mostly worthless.

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
I wrote tests for it! They even pass!

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.


codecov[bot]: # [Codecov](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=h1) Report
> Merging [#558](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=desc) into [master](https://codecov.io/gh/tivac/modular-css/commit/059fd7a62402d2d463129b39f40a88c373192ea0?src=pr&el=desc) will **increase** coverage by `0.09%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/tivac/modular-css/pull/558/graphs/tree.svg?width=650&token=EIUJKcuTE8&height=150&src=pr)](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #558      +/-   ##
==========================================
+ Coverage   98.94%   99.04%   +0.09%     
==========================================
  Files          46       46              
  Lines        1045     1045              
  Branches      162      163       +1     
==========================================
+ Hits         1034     1035       +1     
+ Misses         11       10       -1
```


| [Impacted Files](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/svelte/svelte.js](https://codecov.io/gh/tivac/modular-css/pull/558/diff?src=pr&el=tree#diff-cGFja2FnZXMvc3ZlbHRlL3N2ZWx0ZS5qcw==) | `100% <100%> (+1.31%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=footer). Last update [059fd7a...9ae5067](https://codecov.io/gh/tivac/modular-css/pull/558?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/svelte/svelte.js b/packages/svelte/svelte.js
index 037ee13a..4f996c6b 100644
--- a/packages/svelte/svelte.js
+++ b/packages/svelte/svelte.js
@@ -17,7 +17,8 @@ module.exports = (config = false) => {
     // Defined here to avoid .lastIndex bugs since /g is set
     const linkRegex = /<link\b[^<>]*?\bhref=\s*(?:"([^"]+)"|'([^']+)'|([^>\s]+))[^>]*>/gim;
 
-    const processor = new Processor(config);
+    // Use a passed processor, or set up our own if necessary
+    const { processor = new Processor(config) } = config;
 
     // eslint-disable-next-line no-console, no-empty-function
     const log = config.verbose ? console.log.bind(console, "[svelte]") : () => {};
diff --git a/packages/www/src/guide/usage-svelte.md b/packages/www/src/guide/usage-svelte.md
index 80be1cd9..478e4a02 100644
--- a/packages/www/src/guide/usage-svelte.md
+++ b/packages/www/src/guide/usage-svelte.md
@@ -128,9 +128,9 @@ module.exports = {
 
 If `true` whenever a missing replacement is found like `{css.doesnotexist}` an error will be thrown aborting the file processing. Defaults to `false`.
 
-##### `clean`
+##### `procesor`
 
-If `true` will re-process any previously handled files (and remove any files that dependended on them). Might be useful, but currently also dangerous (see [#522](https://github.com/tivac/modular-css/issues/522)). Defaults to `false`.
+Pass a previously-created `@modular-css/processor` instance into the preprocessor. Will **not** pass through any other options to the processor if this is set, but `strict` will still be honored by the preprocessor.
 
 ##### Shared Options
 


Test patch:
diff --git a/packages/svelte/test/__snapshots__/svelte.test.js.snap b/packages/svelte/test/__snapshots__/svelte.test.js.snap
index fa09f359..26444790 100644
--- a/packages/svelte/test/__snapshots__/svelte.test.js.snap
+++ b/packages/svelte/test/__snapshots__/svelte.test.js.snap
@@ -398,40 +398,60 @@ exports[`/svelte.js should ignore files without <style> blocks 1`] = `
 
 exports[`/svelte.js should ignore files without <style> blocks 2`] = `""`;
 
-exports[`/svelte.js should no-op if all <link>s reference a URL 1`] = `
-"<link rel=\\"stylesheet\\" href=\\"http://example.com/styles.css\\" />
-<link rel=\\"stylesheet\\" href=\\"http://example.com/styles2.css\\" />
-
-<div class=\\"fooga\\">fooga</div>
-"
-`;
-
-exports[`/svelte.js should remove files before reprocessing when config.clean is set 1`] = `
+exports[`/svelte.js should invalidate files before reprocessing (<link>) 1`] = `
 "<div class=\\"source\\">Source</div><script>
     import css from \\"./source.css\\";
 </script>"
 `;
 
-exports[`/svelte.js should remove files before reprocessing when config.clean is set 2`] = `
+exports[`/svelte.js should invalidate files before reprocessing (<link>) 2`] = `
 "/* packages/svelte/test/output/source.css */
 .source {
     color: red;
 }"
 `;
 
-exports[`/svelte.js should remove files before reprocessing when config.clean is set 3`] = `
+exports[`/svelte.js should invalidate files before reprocessing (<link>) 3`] = `
 "<div class=\\"source\\">Source</div><script>
     import css from \\"./source.css\\";
 </script>"
 `;
 
-exports[`/svelte.js should remove files before reprocessing when config.clean is set 4`] = `
+exports[`/svelte.js should invalidate files before reprocessing (<link>) 4`] = `
 "/* packages/svelte/test/output/source.css */
 .source {
     color: blue;
 }"
 `;
 
+exports[`/svelte.js should invalidate files before reprocessing (<style>) 1`] = `
+"<style>/* replaced by modular-css */</style>
+<div class=\\"source\\">Source</div>"
+`;
+
+exports[`/svelte.js should invalidate files before reprocessing (<style>) 2`] = `
+"/* packages/svelte/test/output/source.html */
+.source { color: red; }"
+`;
+
+exports[`/svelte.js should invalidate files before reprocessing (<style>) 3`] = `
+"<style>/* replaced by modular-css */</style>
+<div class=\\"source\\">Source</div>"
+`;
+
+exports[`/svelte.js should invalidate files before reprocessing (<style>) 4`] = `
+"/* packages/svelte/test/output/source.html */
+.source { color: blue; }"
+`;
+
+exports[`/svelte.js should no-op if all <link>s reference a URL 1`] = `
+"<link rel=\\"stylesheet\\" href=\\"http://example.com/styles.css\\" />
+<link rel=\\"stylesheet\\" href=\\"http://example.com/styles2.css\\" />
+
+<div class=\\"fooga\\">fooga</div>
+"
+`;
+
 exports[`/svelte.js should support verbose output: "<link>" 1`] = `
 Array [
   Array [
@@ -631,6 +651,24 @@ Array [
 
 exports[`/svelte.js should throw on both <style> and <link> in one file 1`] = `"@modular-css/svelte: use <style> OR <link>, but not both"`;
 
+exports[`/svelte.js should use an already-created processor 1`] = `
+"<link rel=\\"stylesheet\\" href=\\"http://example.com/styles.css\\" />
+
+<div class=\\"fooga\\">fooga</div>
+<script>
+    import css from \\"./simple.css\\";
+</script>"
+`;
+
+exports[`/svelte.js should use an already-created processor 2`] = `
+"/* fake.css */
+.fake { color: #F00; }
+/* packages/svelte/test/specimens/simple.css */
+.fooga {
+    color: red;
+}"
+`;
+
 exports[`/svelte.js should warn when multiple <link> elements are in the html 1`] = `
 "<link rel=\\"stylesheet\\" href=\\"./simple2.css\\" />
 
diff --git a/packages/svelte/test/svelte.test.js b/packages/svelte/test/svelte.test.js
index f8bf1045..8d650b9f 100644
--- a/packages/svelte/test/svelte.test.js
+++ b/packages/svelte/test/svelte.test.js
@@ -6,6 +6,7 @@ const path = require("path");
 const svelte = require("svelte");
 const dedent = require("dedent");
 
+const Processor = require("@modular-css/processor");
 const namer = require("@modular-css/test-utils/namer.js");
 const logs  = require("@modular-css/test-utils/logs.js");
 
@@ -50,6 +51,31 @@ describe("/svelte.js", () => {
         expect(output.css).toMatchSnapshot();
     });
 
+    it("should use an already-created processor", async () => {
+        const processor = new Processor({ namer });
+
+        await processor.string(
+            "./fake.css",
+            ".fake { color: #F00; }"
+        );
+
+        const filename = require.resolve("./specimens/url.html");
+        const { preprocess } = plugin({
+            processor,
+        });
+
+        const processed = await svelte.preprocess(
+            fs.readFileSync(filename, "utf8"),
+            Object.assign({}, preprocess, { filename })
+        );
+
+        expect(processed.toString()).toMatchSnapshot();
+
+        const output = await processor.output();
+
+        expect(output.css).toMatchSnapshot();
+    });
+
     it.each`
         specimen                    | title
         ${"external.html"}          | ${"no script"}
@@ -218,7 +244,8 @@ describe("/svelte.js", () => {
         expect(processed.toString()).toMatchSnapshot();
     });
     
-    it("should remove files before reprocessing when config.clean is set", async () => {
+
+    it("should invalidate files before reprocessing (<link>)", async () => {
         // V1 of files
         fs.writeFileSync(path.resolve(__dirname, "./output/source.html"), dedent(`
             <link rel="stylesheet" href="./source.css" />
@@ -234,8 +261,6 @@ describe("/svelte.js", () => {
         const filename = require.resolve(`./output/source.html`);
         const { processor, preprocess } = plugin({
             namer,
-
-            clean : true,
         });
 
         let processed = await svelte.preprocess(
@@ -267,4 +292,45 @@ describe("/svelte.js", () => {
 
         expect(output.css).toMatchSnapshot();
     });
+
+    it("should invalidate files before reprocessing (<style>)", async () => {
+        // V1 of files
+        fs.writeFileSync(path.resolve(__dirname, "./output/source.html"), dedent(`
+            <style>.source { color: red; }</style>
+            <div class="{css.source}">Source</div>
+        `));
+
+        const filename = require.resolve(`./output/source.html`);
+        const { processor, preprocess } = plugin({
+            namer,
+        });
+
+        let processed = await svelte.preprocess(
+            fs.readFileSync(filename, "utf8"),
+            Object.assign({}, preprocess, { filename })
+        );
+
+        expect(processed.toString()).toMatchSnapshot();
+
+        let output = await processor.output();
+
+        expect(output.css).toMatchSnapshot();
+
+        // V2 of CSS
+        fs.writeFileSync(path.resolve(__dirname, "./output/source.html"), dedent(`
+            <style>.source { color: blue; }</style>
+            <div class="{css.source}">Source</div>
+        `));
+
+        processed = await svelte.preprocess(
+            fs.readFileSync(filename, "utf8"),
+            Object.assign({}, preprocess, { filename })
+        );
+
+        expect(processed.toString()).toMatchSnapshot();
+
+        output = await processor.output();
+
+        expect(output.css).toMatchSnapshot();
+    });
 });