Skip to content

Commit

Permalink
fix(verify): allow query parameters on imports (raw css etc)
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Apr 2, 2021
1 parent 029e4d6 commit 51339b1
Show file tree
Hide file tree
Showing 22 changed files with 225 additions and 17 deletions.
18 changes: 12 additions & 6 deletions src/dependencies/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,25 +146,31 @@ function findDependencies(entryPath, seen = new Set()) {
}

function resolveDependency(fromDir, toPath, entryPath) {
const [querylessPath] = toPath.split('?', 1)

let depPath
try {
depPath = require.resolve(path.resolve(fromDir, toPath))
depPath = require.resolve(path.resolve(fromDir, querylessPath))
} catch (err) {
throw new Error(`Unable to resolve "${toPath}" from ${entryPath}`)
throw new Error(`Unable to resolve "${querylessPath}" from ${entryPath}`)
}

let actualPath
try {
actualPath = discoverPathSync(depPath)
} catch (err) {
const paths = (err.suggestions || []).map((suggested) => getDidYouMeanPath(toPath, suggested))
const paths = (err.suggestions || []).map((suggested) =>
getDidYouMeanPath(querylessPath, suggested)
)
const didYouMean = paths ? `Did you mean:\n${paths.join('\n- ')}` : ''
throw new Error(`Unable to resolve "${toPath}" from ${entryPath}. ${didYouMean}`)
throw new Error(`Unable to resolve "${querylessPath}" from ${entryPath}. ${didYouMean}`)
}

if (actualPath !== depPath) {
const didYouMean = getDidYouMeanPath(toPath, actualPath)
throw new Error(`Unable to resolve "${toPath} from ${entryPath}. Did you mean "${didYouMean}"?`)
const didYouMean = getDidYouMeanPath(querylessPath, actualPath)
throw new Error(
`Unable to resolve "${querylessPath} from ${entryPath}. Did you mean "${didYouMean}"?`
)
}

return actualPath
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/verify/css-raw-import-missing/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some license
1 change: 1 addition & 0 deletions test/fixtures/verify/css-raw-import-missing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# some cool
34 changes: 34 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/lib/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict'

Object.defineProperty(exports, '__esModule', {
value: true,
})
exports.default = void 0

var _react = _interopRequireDefault(require('react'))

var _two = _interopRequireDefault(require('./two'))

var _one = _interopRequireDefault(require('./styles/one.css?raw'))

function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {default: obj}
}

class One extends _react.default.PureComponent {
componentDidMount() {
;(0, _two.default)()
}

render() {
return /*#__PURE__*/ _react.default.createElement(
'button',
{
className: _one.default.button,
},
'Click me'
)
}
}

exports.default = One
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.button {
background: #bf1942;
}
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/lib/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function two() {
// do something important
}
19 changes: 19 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "sanity-plugin-css-part",
"version": "1.0.0",
"private": true,
"description": "Just a fixture",
"main": "./lib/one.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"sanity",
"sanity-plugin"
],
"peerDependencies": {
"react": "*"
},
"author": "Some person",
"license": "MIT"
}
13 changes: 13 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/sanity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"paths": {
"source": "./src",
"compiled": "./lib"
},

"parts": [
{
"name": "part:css-part/some/thing",
"path": "one.js"
}
]
}
13 changes: 13 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/src/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import two from './two'
import styles from './styles/one.css?raw'

export default class One extends React.PureComponent {
componentDidMount() {
two()
}

render() {
return <button className={styles.button}>Click me</button>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.button {
background: #bf1942;
}
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import-missing/src/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function two() {
// do something important
}
1 change: 1 addition & 0 deletions test/fixtures/verify/css-raw-import/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some license
1 change: 1 addition & 0 deletions test/fixtures/verify/css-raw-import/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# some cool
34 changes: 34 additions & 0 deletions test/fixtures/verify/css-raw-import/lib/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict'

Object.defineProperty(exports, '__esModule', {
value: true,
})
exports.default = void 0

var _react = _interopRequireDefault(require('react'))

var _two = _interopRequireDefault(require('./two'))

var _one = _interopRequireDefault(require('./styles/One.css?raw'))

function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {default: obj}
}

class One extends _react.default.PureComponent {
componentDidMount() {
;(0, _two.default)()
}

render() {
return /*#__PURE__*/ _react.default.createElement(
'button',
{
className: _one.default.button,
},
'Click me'
)
}
}

exports.default = One
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import/lib/styles/One.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.button {
background: #bf1942;
}
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import/lib/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function two() {
// do something important
}
19 changes: 19 additions & 0 deletions test/fixtures/verify/css-raw-import/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "sanity-plugin-css-part",
"version": "1.0.0",
"private": true,
"description": "Just a fixture",
"main": "./lib/one.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"sanity",
"sanity-plugin"
],
"peerDependencies": {
"react": "*"
},
"author": "Some person",
"license": "MIT"
}
13 changes: 13 additions & 0 deletions test/fixtures/verify/css-raw-import/sanity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"paths": {
"source": "./src",
"compiled": "./lib"
},

"parts": [
{
"name": "part:css-part/some/thing",
"path": "one.js"
}
]
}
13 changes: 13 additions & 0 deletions test/fixtures/verify/css-raw-import/src/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import two from './two'
import styles from './styles/One.css?raw'

export default class One extends React.PureComponent {
componentDidMount() {
two()
}

render() {
return <button className={styles.button}>Click me</button>
}
}
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import/src/styles/One.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.button {
background: #bf1942;
}
3 changes: 3 additions & 0 deletions test/fixtures/verify/css-raw-import/src/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function two() {
// do something important
}
38 changes: 27 additions & 11 deletions test/verify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,63 +25,63 @@ tap.test('throws on missing license key', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'missing-license-key')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'missing "license" key')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on missing license file', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'missing-license')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'does not contain a LICENSE-file')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on non-spdx license', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'non-spdx-license')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'SPDX license ID')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on referenced files being ignored by npm (package.json)', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'npm-ref-ignored-file')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'ignored from being published: "types.d.ts"')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on referenced files being ignored by npm (sanity.json)', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'part-ref-ignored-file')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'ignored from being published: "lib/ignored.js"')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on invalid dist config', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'invalid-dist-config')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'must be an object, got:\n[]')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('throws on invalid dist config (syntax)', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'invalid-dist-config-syntax')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, 'Unexpected end of JSON input')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1, 'should have exit code 1')
})

tap.test('warns on "useless" files', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'useless-files')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, '".eslintignore", ".prettierrc"')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 0)
})

Expand All @@ -105,14 +105,30 @@ tap.test('verifies plugin with CSS-part referenced (missing)', options, async (t
const fixtureDir = path.join(baseFixturesDir, 'css-part-missing')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, `references file ("styles/one.css") that does not exist in compiled`)
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1)
})

tap.test('verifies plugin with import referencing missing CSS file', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'css-import')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, /unable to resolve.*?one\.css.*?did you mean.*?One.css/i)
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1)
})

tap.test('verifies plugin with import referencing missing ?raw CSS file', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'css-raw-import-missing')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, /unable to resolve.*?one\.css.*?did you mean.*?One.css/i)
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1)
})

tap.test('verifies plugin with import referencing valid ?raw CSS file', options, async (t) => {
const fixtureDir = path.join(baseFixturesDir, 'css-raw-import')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.equal(stderr, '', 'should have empty stderr')
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(exitCode, 1)
})
Expand All @@ -121,7 +137,7 @@ tap.test('verifies plugin with css modules referencing missing CSS file', option
const fixtureDir = path.join(baseFixturesDir, 'css-bad-composes')
const {stdout, stderr, exitCode} = await execa(sanipack, ['verify', fixtureDir], {reject: false})
t.includes(stderr, /unable to resolve.*?baseButton\.css/i)
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1)
})

Expand All @@ -131,7 +147,7 @@ tap.test('verifies plugin with css importing incorrectly cased CSS file', option
reject: false,
})
t.includes(stderr, /unable to resolve.*?Button\.css.*?did you mean.*?button.css/i)
t.includes(stdout, 'good to publish', 'should have success in stdout')
t.equal(stdout, '', 'should have empty stdout')
t.equal(exitCode, 1)
})

Expand Down

0 comments on commit 51339b1

Please sign in to comment.