-
Notifications
You must be signed in to change notification settings - Fork 683
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creates a graphql-cli plugin package called validate-magento-pwa-queries
Creates a compatibility definition file and script to generate markdown from it Creates a graphql-cli extension to validate a project's queries Created a new project / repository called graphql-cli-validate-queries that - based on configuration - goes through all of a project's GraphQL queries and runs them against an endpoint's schema. Updates venia-concept to use this new extension and the graphql-cli tool in general. Resolves #952. Fixes the format of the graphql/template-strings eslint rule Adds script to dev-docs to auto-generate the magento compatibility table Adds a README to the graphql-cli-validate-queries project Adds unit tests to graphql-cli-validate-queries plugin. Installs and wires up Jest for unit testing the validate-queries plugin. Fixed typo mistakes. (#993) * Fixed typo mistakes * Fixed typo mistakes chore: remove duplicate padding property (#941) [BUGFIX] [ISSUE-958] Autocomplete renders loading component on clear (#961) * [BUGFIX] [ISSUE-958] Autocomplete renders loading component on clear Removes invalid TODO in graphql-cli-validate-queries/index.js Adds a JSDoc comment block to the getValidator function in graphql-cli-validate-queries Cleans up the devdoc draft for validate-queries plugin Adds a PWA-specific summarization to the end of the validate-queries command. Adds a new script summarize-validate-queries.js to venia-concept Runs this script at the end of the validate-queries script This script uses the compatibility table to clue developers to compatibility issues and how to resolve them Runs prettier Removes use of reserved word in summarize-validate-queries.js Create compatibility table page (#1016) * Fix auto-generated table markdown and re-order versions to list the latest version first * Incorporate build-compatibility table script into build process * Create a page to display the compatibility table * Update pwa-devdocs/src/technologies/magento-compatibility/index.md Co-Authored-By: jcalcaben <[email protected]> Updates the path to the compatibility table on the docs site Updates the wording around the reporting of version specifics and compatibility in the summarize-validate-queries script Runs prettier and updates summarize-validate-queries. Fixes dependencies and includes plugin in root jest test. The graphql-cli-validate-magento-pwa-queries plugins tests are now run as part of the root test command. This ensures that breaking tests in this project will fail the prepush check. Cleans up yarn.lock changes by selectively installing dependencies via yarn workspace add commands. Renames plugin to be more magento and pwa specific. Runs prettier Removes unneeded summary script file Updates the dev docs for the graphql-cli plugin
- Loading branch information
1 parent
94cdc53
commit a156a48
Showing
19 changed files
with
2,046 additions
and
583 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* This file describes PWA Studio to Magento version compatabilities. | ||
*/ | ||
|
||
// PWA Studio version -> Magento version. | ||
module.exports = { | ||
'>2.0.0': '2.3.1', | ||
'2.0.0': '2.3.0' | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
packages/graphql-cli-validate-magento-pwa-queries/LICENSE.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2019 Adobe Inc. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
65 changes: 65 additions & 0 deletions
65
packages/graphql-cli-validate-magento-pwa-queries/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) [![jest](https://jestjs.io/img/jest-badge.svg)](https://github.com/facebook/jest) | ||
|
||
|
||
# graphql-cli-validate-queries | ||
|
||
Validate your project's GraphQL queries against a schema. | ||
|
||
## Installation | ||
|
||
``` | ||
yarn add graphql-cli graphql-cli-validate-queries | ||
``` | ||
|
||
## Summary | ||
|
||
Given the following `.graphqlconfig`: | ||
|
||
``` | ||
{ | ||
"projects": { | ||
"myApp": { | ||
"schemaPath": "mySchema.json", | ||
"extensions": { | ||
"endpoints": { | ||
"default": "https://myEndpoint.com/graphql" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
The command | ||
``` | ||
graphql-cli get-schema --project myApp | ||
``` | ||
will [download the GraphQL schema](https://oss.prisma.io/content/graphql-cli/06-schema-handling) | ||
from `https://myEndpoint.com/graphql` and store it in `mySchema.json`. | ||
|
||
Then the command | ||
``` | ||
graphql-cli validate-queries --project myApp --filesGlob \"src/**/*.{js,graphql,gql}\" --clients apollo literal | ||
``` | ||
|
||
will validate all `apollo` and `literal` GraphQL queries it finds in `.js`, `.graphql`, or `.gql` files in the `src/` directory | ||
against that schema. | ||
|
||
## Options | ||
|
||
This plugin supports the following command line options: | ||
|
||
| Option | Description | Type | Default | | ||
| --- | --- | --- | --- | | ||
| `--clients`, `-c` | GraphQL clients in use in this project. | `array` | `["apollo"]` | | ||
| `--filesGlob`, `-f` | A glob used to target files for validation. | `string` | `""` | | ||
| `--project`, `-p` | The project name as specified in `.graphqlconfig`. | `string` | `""` | | ||
|
||
## Further Reading | ||
|
||
* [graphql-config](https://github.com/prisma/graphql-config) | ||
* [graphql-cli](https://github.com/graphql-cli/graphql-cli) | ||
* [eslint-plugin-graphql](https://github.com/apollographql/eslint-plugin-graphql) | ||
* [graphql/no-deprecated-fields rule](https://github.com/apollographql/eslint-plugin-graphql#no-deprecated-fields-validation-rule) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const plugin = require('./lib/index.js'); | ||
|
||
module.exports = plugin; |
215 changes: 215 additions & 0 deletions
215
packages/graphql-cli-validate-magento-pwa-queries/lib/__tests__/index.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
const plugin = require('../index'); | ||
|
||
const fs = require('fs'); | ||
const eslint = require('eslint'); | ||
|
||
jest.mock('fs'); | ||
jest.mock('eslint'); | ||
|
||
test('it exports the correct command name', () => { | ||
expect(plugin.command).toBe('validate-magento-pwa-queries'); | ||
}); | ||
|
||
test('it exports a description', () => { | ||
expect(plugin.desc).toBeTruthy(); | ||
}); | ||
|
||
describe('supportedArguments', () => { | ||
test('it supports a project command line argument', () => { | ||
const keys = Object.keys(plugin.supportedArguments); | ||
|
||
expect(keys).toHaveLength(1); | ||
expect(keys).toContain('project'); | ||
}); | ||
}); | ||
|
||
describe('builder', () => { | ||
const mockArgs = { | ||
options: jest.fn() | ||
}; | ||
afterEach(() => { | ||
mockArgs.options.mockClear(); | ||
}); | ||
|
||
test('it is a function', () => { | ||
expect(plugin.builder).toBeInstanceOf(Function); | ||
}); | ||
|
||
test('it calls args.options with the correct supported arguments', () => { | ||
plugin.builder(mockArgs); | ||
|
||
expect(mockArgs.options).toHaveBeenCalled(); | ||
expect(mockArgs.options).toHaveBeenCalledWith( | ||
plugin.supportedArguments | ||
); | ||
}); | ||
}); | ||
|
||
describe('handler', () => { | ||
const mockArgs = { | ||
project: 'myApp' | ||
}; | ||
const mockContext = { | ||
getProjectConfig: jest.fn(() => { | ||
return Promise.resolve({ | ||
config: { | ||
extensions: { | ||
'validate-magento-pwa-queries': { | ||
clients: ['apollo', 'literal'], | ||
filesGlob: '*.graphql' | ||
} | ||
}, | ||
schemaPath: 'unit test' | ||
} | ||
}); | ||
}), | ||
spinner: { | ||
fail: jest.fn(), | ||
start: jest.fn(), | ||
succeed: jest.fn() | ||
} | ||
}; | ||
|
||
let eslintCLIEngineSpy; | ||
let existsSyncSpy; | ||
let mockConsoleLog; | ||
let mockConsoleWarn; | ||
let mockProcessExit; | ||
|
||
beforeAll(() => { | ||
const noop = () => {}; | ||
|
||
// For happy paths, mock a report that indicates no errors. | ||
eslintCLIEngineSpy = jest.spyOn(eslint, 'CLIEngine'); | ||
eslintCLIEngineSpy.mockImplementation(() => ({ | ||
executeOnFiles: jest.fn().mockImplementation(() => ({ | ||
errorCount: 0, | ||
results: { | ||
length: Number.POSITIVE_INFINITY | ||
} | ||
})), | ||
resolveFileGlobPatterns: jest.fn() | ||
})); | ||
|
||
// For happy paths, mock the file existing. | ||
existsSyncSpy = jest.spyOn(fs, 'existsSync'); | ||
existsSyncSpy.mockImplementation(() => true); | ||
|
||
mockConsoleLog = jest.spyOn(console, 'log'); | ||
mockConsoleLog.mockImplementation(noop); | ||
|
||
mockConsoleWarn = jest.spyOn(console, 'warn'); | ||
mockConsoleWarn.mockImplementation(noop); | ||
|
||
mockProcessExit = jest.spyOn(process, 'exit'); | ||
mockProcessExit.mockImplementation(noop); | ||
}); | ||
afterEach(() => { | ||
eslintCLIEngineSpy.mockClear(); | ||
existsSyncSpy.mockClear(); | ||
mockConsoleLog.mockClear(); | ||
mockConsoleWarn.mockClear(); | ||
mockProcessExit.mockClear(); | ||
}); | ||
afterAll(() => { | ||
eslintCLIEngineSpy.mockRestore(); | ||
existsSyncSpy.mockRestore(); | ||
mockConsoleLog.mockRestore(); | ||
mockConsoleWarn.mockRestore(); | ||
mockProcessExit.mockRestore(); | ||
}); | ||
|
||
test('it is a function', () => { | ||
expect(plugin.handler).toBeInstanceOf(Function); | ||
}); | ||
|
||
test('it returns undefined', async () => { | ||
const actual = await plugin.handler(mockContext, mockArgs); | ||
|
||
expect(actual).toBeUndefined(); | ||
}); | ||
|
||
test("it throws if the schema doesn't exist locally", async () => { | ||
// Mock the file not existing. | ||
existsSyncSpy.mockImplementationOnce(() => false); | ||
|
||
await plugin.handler(mockContext, mockArgs); | ||
|
||
expect(existsSyncSpy).toHaveBeenCalled(); | ||
expect(mockContext.spinner.fail).toHaveBeenCalled(); | ||
expect(mockProcessExit).toHaveBeenCalledWith(1); | ||
}); | ||
|
||
test('it creates a validator with the correct configuration', async () => { | ||
const expectedRule = [ | ||
'error', | ||
// These objects are derived from mockArgs. | ||
{ | ||
env: 'apollo', | ||
projectName: 'myApp' | ||
}, | ||
{ | ||
env: 'literal', | ||
projectName: 'myApp' | ||
} | ||
]; | ||
|
||
await plugin.handler(mockContext, mockArgs); | ||
|
||
const lintConfiguration = eslintCLIEngineSpy.mock.calls[0][0]; | ||
|
||
const keys = Object.keys(lintConfiguration); | ||
expect(keys).toHaveLength(4); | ||
expect(keys).toContain('parser'); | ||
expect(keys).toContain('plugins'); | ||
expect(keys).toContain('rules'); | ||
expect(keys).toContain('useEslintrc'); | ||
|
||
expect(lintConfiguration.parser).toBe('babel-eslint'); | ||
|
||
expect(lintConfiguration.plugins).toHaveLength(1); | ||
expect(lintConfiguration.plugins).toContain('graphql'); | ||
|
||
const rulesKeys = Object.keys(lintConfiguration.rules); | ||
expect(rulesKeys).toHaveLength(2); | ||
expect(rulesKeys).toContain('graphql/template-strings'); | ||
expect(rulesKeys).toContain('graphql/no-deprecated-fields'); | ||
|
||
const templateStringsRule = | ||
lintConfiguration.rules['graphql/template-strings']; | ||
expect(templateStringsRule).toEqual(expectedRule); | ||
|
||
const deprecatedFieldsRule = | ||
lintConfiguration.rules['graphql/no-deprecated-fields']; | ||
expect(deprecatedFieldsRule).toEqual(expectedRule); | ||
|
||
expect(lintConfiguration.useEslintrc).toBe(false); | ||
}); | ||
|
||
test('it logs an appropriate message when there are no errors', async () => { | ||
await plugin.handler(mockContext, mockArgs); | ||
|
||
expect(mockConsoleLog).toHaveBeenCalled(); | ||
expect(mockProcessExit).toHaveBeenCalledWith(0); | ||
}); | ||
|
||
test('it warns when there are errors', async () => { | ||
eslintCLIEngineSpy.mockImplementationOnce(() => ({ | ||
executeOnFiles: jest.fn().mockImplementation(() => ({ | ||
errorCount: Number.POSITIVE_INFINITY, | ||
results: { | ||
length: Number.POSITIVE_INFINITY | ||
} | ||
})), | ||
getFormatter: jest.fn().mockImplementation(() => { | ||
return function() {}; | ||
}), | ||
resolveFileGlobPatterns: jest.fn() | ||
})); | ||
|
||
await plugin.handler(mockContext, mockArgs); | ||
|
||
expect(mockConsoleWarn).toHaveBeenCalled(); | ||
expect(mockProcessExit).toHaveBeenCalledWith(1); | ||
}); | ||
}); |
Oops, something went wrong.