diff --git a/.gitignore b/.gitignore index 07d2252..26b155c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,285 @@ -node_modules -out \ No newline at end of file +.vscode-test + +# Created by https://www.gitignore.io/api/linux,macos,windows,intellij,sublimetext,visualstudiocode,node +# Edit at https://www.gitignore.io/?templates=linux,macos,windows,intellij,sublimetext,visualstudiocode,node + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +# JetBrains templates +**___jb_tmp___ + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/linux,macos,windows,intellij,sublimetext,visualstudiocode,node \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..94d339e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "printWidth": 140, + "semi": true, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "trailingComma": "es5", + "bracketSpacing": true, + "arrowParens": "avoid", + "insertPragma": false +} diff --git a/.travis.yml b/.travis.yml index 5bebaf8..8312b08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,23 @@ +# https://vscode-docs.readthedocs.io/en/latest/extensions/testing-extensions/#running-tests-automatically-on-travis-ci-build-machines +sudo: false + +os: + - osx + - linux + +before_install: + - if [ $TRAVIS_OS_NAME == "linux" ]; then + export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0; + sh -e /etc/init.d/xvfb start; + sleep 3; + fi + language: node_js node_js: - 10 install: - yarn + - yarn vscode:prepublish + script: - - yarn build + - yarn test --silent diff --git a/package.json b/package.json index 9ae763f..b711694 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.3.3", "@types/babel-traverse": "^6.25.5", + "@types/chai": "^4.1.7", "@types/mocha": "^2.2.42", "@types/node": "^10.12.21", "@types/parse5": "^5.0.0", @@ -131,6 +132,7 @@ "@types/styled-system": "^4.1.1", "all-contributors-cli": "^6.6.1", "babel-loader": "^8.0.5", + "chai": "^4.2.0", "cross-env": "^5.2.0", "css-loader": "^2.1.1", "file-loader": "^3.0.1", diff --git a/src/extension/Manager.ts b/src/extension/Manager.ts index 1542c96..c7d6ffd 100644 --- a/src/extension/Manager.ts +++ b/src/extension/Manager.ts @@ -1,10 +1,9 @@ -import * as vscode from "vscode"; -import { FileHandler, EditableBlock } from "./file-handlers/types"; -import CSSFileInspector from "./file-handlers/css-file"; -import StyledComponentsInspector from "./file-handlers/js"; -import DecoratedClassComponentsInspector from "./file-handlers/ts"; -import HtmlInspector from "./file-handlers/html"; -import { isAngularComponentRegex } from "./file-handlers/utils"; +import * as vscode from 'vscode'; +import CSSFileInspector from './file-handlers/css-file'; +import HtmlInspector from './file-handlers/html'; +import StyledComponentsInspector from './file-handlers/js'; +import DecoratedClassComponentsInspector from './file-handlers/ts'; +import { EditableBlock, FileHandler, SupportedFiletypes, UpdateActiveBlockType } from './file-handlers/types'; export default class Manager { // These are protected to allow unit test access because manager is extended @@ -12,41 +11,27 @@ export default class Manager { protected panel: vscode.WebviewPanel; protected activeBlock: EditableBlock | undefined; protected inspector: FileHandler | undefined; - protected languageId: string = ""; + protected languageId: SupportedFiletypes = ''; constructor(panel: vscode.WebviewPanel) { this.panel = panel; vscode.window.onDidChangeActiveTextEditor(activeEditor => { - const languageId = activeEditor - ? activeEditor.document.languageId - : undefined; - - if ( - languageId === "html" || - languageId === "svelte" || - languageId === "vue" - ) { + const languageId = activeEditor ? activeEditor.document.languageId : undefined; + + if (languageId === 'html' || languageId === 'svelte' || languageId === 'vue') { this.inspector = HtmlInspector; this.activeEditor = activeEditor; this.languageId = languageId; - } else if ( - languageId === "css" || - languageId === "scss" || - languageId === "postcss" - ) { + } else if (languageId === 'css' || languageId === 'scss' || languageId === 'postcss') { this.inspector = CSSFileInspector; this.activeEditor = activeEditor; this.languageId = languageId; - } else if ( - languageId === "javascript" || - languageId === "javascriptreact" || - languageId === "typescriptreact" - ) { + } else if (languageId === 'javascript' || languageId === 'javascriptreact' || languageId === 'typescriptreact') { this.inspector = StyledComponentsInspector; this.activeEditor = activeEditor; this.languageId = languageId; - } else if (languageId === "typescript") { + } else if (languageId === 'typescript') { this.inspector = DecoratedClassComponentsInspector; this.activeEditor = activeEditor; this.languageId = languageId; @@ -54,61 +39,49 @@ export default class Manager { }); vscode.workspace.onDidChangeTextDocument(({ document }) => { - if (this.isAcceptableLaguage(document.languageId)) { + if (this.isAcceptableLaguage(document.languageId as SupportedFiletypes)) { this.parseFromActiveEditor(); } }); vscode.window.onDidChangeTextEditorSelection(({ textEditor }) => { - if ( - textEditor && - this.isAcceptableLaguage(textEditor.document.languageId) - ) { + if (textEditor && this.isAcceptableLaguage(textEditor.document.languageId as SupportedFiletypes)) { this.activeEditor = textEditor; this.parseFromActiveEditor(); } }); } - isAcceptableLaguage(languageId: string): boolean { + isAcceptableLaguage(languageId: SupportedFiletypes): boolean { return ( - languageId === "html" || - languageId === "css" || - languageId === "scss" || - languageId === "postcss" || - languageId === "javascript" || - languageId === "typescript" || - languageId === "javascriptreact" || - languageId === "typescriptreact" || - languageId === "svelte" || - languageId === "vue" + languageId === 'html' || + languageId === 'css' || + languageId === 'scss' || + languageId === 'postcss' || + languageId === 'javascript' || + languageId === 'typescript' || + languageId === 'javascriptreact' || + languageId === 'typescriptreact' || + languageId === 'svelte' || + languageId === 'vue' ); } parseFromActiveEditor(): void { if (this.activeEditor) { const activeFileContent = this.activeEditor.document.getText(); - const payload = this.getPayloadForBlock( - activeFileContent, - this.activeEditor.selection.active - ); + const payload = this.getPayloadForBlock(activeFileContent, this.activeEditor.selection.active); this.panel.webview.postMessage({ - type: "activeBlock", - payload + type: 'activeBlock', + payload, }); } } - getPayloadForBlock( - activeFileContent: string, - cursorPosition: vscode.Position - ) { + getPayloadForBlock(activeFileContent: string, cursorPosition: vscode.Position) { let payload = null; if (this.inspector) { - const blocks = this.inspector.getEditableBlocks( - activeFileContent, - this.languageId - ); + const blocks = this.inspector.getEditableBlocks(activeFileContent, this.languageId); const activeBlock = this.getActiveBlock(cursorPosition, blocks); this.activeBlock = activeBlock; @@ -134,11 +107,7 @@ export default class Manager { (source && source.end && source.end.column) || 0 ); - return this.isCursorWithinBlock( - ruleStartPosition, - ruleEndPosition, - cursorPositon - ); + return this.isCursorWithinBlock(ruleStartPosition, ruleEndPosition, cursorPositon); }); if (blocksWithinCursor.length === 1) { @@ -149,9 +118,7 @@ export default class Manager { const { source } = rule; const { source: closestBlockSource } = closestRule; if ( - (closestBlockSource && - closestBlockSource.start && - (closestBlockSource.start.line as any)) < + (closestBlockSource && closestBlockSource.start && (closestBlockSource.start.line as any)) < (source && source.start && (source.start.line as any)) ) { closestRule = rule; @@ -162,28 +129,16 @@ export default class Manager { } } - isCursorWithinBlock( - ruleStart: vscode.Position, - ruleEnd: vscode.Position, - cursorPosition: vscode.Position - ) { - return ( - cursorPosition.isAfterOrEqual(ruleStart) && - cursorPosition.isBeforeOrEqual(ruleEnd) - ); + isCursorWithinBlock(ruleStart: vscode.Position, ruleEnd: vscode.Position, cursorPosition: vscode.Position) { + return cursorPosition.isAfterOrEqual(ruleStart) && cursorPosition.isBeforeOrEqual(ruleEnd); } - async updateActiveBlock(prop: string, value: string, type: "add" | "remove") { + async updateActiveBlock(prop: string, value: string, type: UpdateActiveBlockType) { if (this.activeBlock && this.inspector) { - let updatedCSS = ""; - - if (type === "add") { - updatedCSS = this.inspector.updateProperty( - this.activeBlock, - prop, - value, - this.languageId - ); + let updatedCSS = ''; + + if (type === 'add') { + updatedCSS = this.inspector.updateProperty(this.activeBlock, prop, value, this.languageId); } else { updatedCSS = this.inspector.removeProperty(this.activeBlock, prop); } @@ -201,21 +156,12 @@ export default class Manager { ); await this.activeEditor.edit(editBuilder => { - editBuilder.replace( - new vscode.Range(ruleStartPosition, ruleEndPosition), - updatedCSS - ); + editBuilder.replace(new vscode.Range(ruleStartPosition, ruleEndPosition), updatedCSS); }); if (this.activeEditor && this.inspector) { const activeFileContent = this.activeEditor.document.getText(); - const blocks = this.inspector.getEditableBlocks( - activeFileContent, - this.languageId - ); - const activeRule = this.getActiveBlock( - this.activeEditor.selection.active, - blocks - ); + const blocks = this.inspector.getEditableBlocks(activeFileContent, this.languageId); + const activeRule = this.getActiveBlock(this.activeEditor.selection.active, blocks); this.activeBlock = activeRule; } } diff --git a/src/extension/file-handlers/types.ts b/src/extension/file-handlers/types.ts index 7828d1e..2a5e533 100644 --- a/src/extension/file-handlers/types.ts +++ b/src/extension/file-handlers/types.ts @@ -1,5 +1,20 @@ import { Declaration, NodeSource, Rule } from "postcss"; +export type SupportedFiletypes = + | "html" + | "css" + | "scss" + | "postcss" + | "javascript" + | "typescript" + | "javascriptreact" + | "typescriptreact" + | "svelte" + | "vue" + | ""; + +export type UpdateActiveBlockType = "add" | "remove"; + /** * File handler is responsible for parsing and extracting EditableBlocks. * Also deals with updating CSS properties. diff --git a/src/extension/test/extension.test.ts b/src/extension/test/extension.test.ts index 3a56e86..3dcec00 100644 --- a/src/extension/test/extension.test.ts +++ b/src/extension/test/extension.test.ts @@ -1,181 +1,185 @@ +import { expect, assert } from 'chai'; +import { suite, test } from 'mocha-typescript'; // https://www.npmjs.com/package/mocha-typescript +import * as vscode from 'vscode'; +import Manager from '../Manager'; +import angularTestCases from './test-cases/angular.test-case'; +import cssTestCases from './test-cases/css-file.test-case'; +import htmlTestCases from './test-cases/html.test-case'; +import reactTestCases from './test-cases/react.test-case'; +import scssTestCases from './test-cases/scss-file.test-case'; +import svelteTestCases from './test-cases/svelte.test-case'; +import vueTestCases from './test-cases/vue.test-case'; +import { TestCaseSetup } from './test-types'; +import { createMockWebviewPanel, getCursorPositionPosition, getTestFile } from './test-utils'; + /** - * TODO: - * Add tests for all file types - * Add tests that change and then validate overall file to ensure output is the expected output (todo: create an array of before and after strings to make it dynamic) - * UI unit tests + * Array of all tests case setup data structures + * This will iterate through all test cases for the of the test case setup objects in the array */ +const allTestCases: TestCaseSetup[] = [ + cssTestCases, + scssTestCases, + htmlTestCases, + reactTestCases, + angularTestCases, + svelteTestCases, + vueTestCases, +]; + +for (const testCaseSetup of allTestCases) { + console.log('Starting test case:', testCaseSetup.name); + + describe(testCaseSetup.name, () => { + // store the original CSS string from when the document is read from the disk the first time + // Each new test will use this to ensure a clean file + let originalTextContent: string; + let testCases: TestCaseSetup = testCaseSetup; + + /** Extend Manager class so that we can access protected class properties */ + @suite('Manager.ts Test Suite') + class ManagerTest extends Manager { + get currActiveEditor() { + return this.activeEditor as vscode.TextEditor; + } -// The module 'assert' provides assertion methods from node -import * as assert from "assert"; -import { suite, test } from "mocha-typescript"; // https://www.npmjs.com/package/mocha-typescript -import * as vscode from "vscode"; -import Manager from "../Manager"; -import { - createMockWebviewPanel, - getCursorPositionPosition, - getTestFile -} from "./test-utils"; -import CSSFileInspector from "../file-handlers/css-file"; - -describe("Test CSS Files", () => { - // store the original CSS string from when the document is read from the disk the first time - // Each new test will use this to ensure a clean file - let originalTextContent: string; - - /** Extend Manager class so that we can access protected class properties */ - @suite - class ManagerTest extends Manager { - constructor() { - super(createMockWebviewPanel()); - } - - // Runs once before all tests - static async before() { - // Get text from file - otherwise the file is read from the open editors with mutated data - let document = await vscode.workspace.openTextDocument( - getTestFile("test-css.css") - ); - originalTextContent = document.getText(); - } - - // equivalent to beforeEach - async before() { - const document = await vscode.workspace.openTextDocument({ - content: originalTextContent, - language: "css" - }); - const editor = await vscode.window.showTextDocument(document); - this.activeEditor = editor; - this.inspector = CSSFileInspector; - this.languageId = "css"; - this.activeBlock = undefined; - } + constructor() { + super(createMockWebviewPanel()); + } - @test("Parse CSS Blocks") async parseCSSBlocks() { - if (this.activeEditor) { - const text = this.activeEditor.document.getText(); - let payload = this.getPayloadForBlock( - text, - getCursorPositionPosition(5, 25) - ); - - assert.deepEqual(payload, { - border: "1px solid #ccc", - padding: "10px", - color: "#333" - }); + // before (runs once) + static async before() { + // Get text from file - otherwise the file is read from the open editors with mutated data + let document = await vscode.workspace.openTextDocument(getTestFile(testCases.testFileName)); + originalTextContent = document.getText(); + } - payload = this.getPayloadForBlock( - text, - getCursorPositionPosition(11, 22) - ); + // beforeEach + async before() { + await this.resetDocument(); + } - assert.deepEqual(payload, { - "border-color": "green" + // Set text document back to original state + async resetDocument(content: string = originalTextContent) { + const document = await vscode.workspace.openTextDocument({ + content, + language: testCases.languageId, }); + const editor = await vscode.window.showTextDocument(document); + this.activeEditor = editor; + this.inspector = testCases.inspector; + this.languageId = testCases.languageId; + this.activeBlock = undefined; + } - payload = this.getPayloadForBlock( - text, - getCursorPositionPosition(15, 20) - ); - - assert.deepEqual(payload, { - "border-color": "red" - }); + @test(`Parse CSS Blocks: (${testCases.parseTestCases.length} test cases)`) + async parseCSSBlocks() { + const text = this.currActiveEditor.document.getText(); + let i = 0; - payload = this.getPayloadForBlock( - text, - getCursorPositionPosition(19, 23) - ); + for (const testCase of testCases.parseTestCases) { + let payload = this.getPayloadForBlock(text, getCursorPositionPosition(testCase.line, testCase.column)); - assert.deepEqual(payload, { - "border-color": "yellow" - }); + expect(payload).to.deep.equal(testCase.expected, `Test case ${i} failed`); - payload = this.getPayloadForBlock( - text, - getCursorPositionPosition(21, 0) - ); + i++; + } + } - assert.equal(payload, null); - } else { - assert(false, "Active Editor was not initialized"); + @test(`Update CSS Property: (${testCases.updateCssTestCases.length} test cases)`) + async updateCssProperty() { + let i = 0; + + for (const testCase of testCases.updateCssTestCases) { + await this.resetDocument(); + const text = this.currActiveEditor.document.getText(); + // set active block + this.getPayloadForBlock(text, getCursorPositionPosition(testCase.line, testCase.column)); + // update CSS + await this.updateActiveBlock(testCase.prop, testCase.value, testCase.type); + // re-fetch active block + let payload = this.getPayloadForBlock( + this.currActiveEditor.document.getText(), + getCursorPositionPosition(testCase.line, testCase.column) + ); + + expect(payload).to.deep.equal(testCase.expected, `Test case ${i} failed`); + + i++; + } } - } - @test("Update CSS Property") async updateCssProperty() { - if (this.activeEditor) { - // set activeBlock - this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); - - await this.updateActiveBlock("color", "#444", "add"); - - let payload = this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); - - assert.deepEqual(payload, { - border: "1px solid #ccc", - padding: "10px", - color: "#444" - }); - } else { - assert(false, "Active Editor was not initialized"); + @test(`Add CSS Property: (${testCases.addCssTestCases.length} test cases)`) + async addCssProperty() { + let i = 0; + + for (const testCase of testCases.addCssTestCases) { + await this.resetDocument(); + const text = this.currActiveEditor.document.getText(); + // set active block + this.getPayloadForBlock(text, getCursorPositionPosition(testCase.line, testCase.column)); + // update CSS + await this.updateActiveBlock(testCase.prop, testCase.value, testCase.type); + // re-fetch active block + let payload = this.getPayloadForBlock( + this.currActiveEditor.document.getText(), + getCursorPositionPosition(testCase.line, testCase.column) + ); + + expect(payload).to.deep.equal(testCase.expected, `Test case ${i} failed`); + + i++; + } } - } - @test("Add CSS Property") async addCssProperty() { - if (this.activeEditor) { - // set activeBlock - this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); - - await this.updateActiveBlock("background-color", "white", "add"); - - let payload = this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); - - assert.deepEqual(payload, { - border: "1px solid #ccc", - padding: "10px", - color: "#333", - "background-color": "white" - }); - } else { - assert(false, "Active Editor was not initialized"); + @test(`Remove CSS Property: (${testCases.removeCssTestCases.length} test cases)`) + async removeCssProperty() { + let i = 0; + + for (const testCase of testCases.removeCssTestCases) { + await this.resetDocument(); + const text = this.currActiveEditor.document.getText(); + // set active block + this.getPayloadForBlock(text, getCursorPositionPosition(testCase.line, testCase.column)); + // update CSS + await this.updateActiveBlock(testCase.prop, testCase.value, testCase.type); + // re-fetch active block + let payload = this.getPayloadForBlock( + this.currActiveEditor.document.getText(), + getCursorPositionPosition(testCase.line, testCase.column) + ); + + expect(payload).to.deep.equal(testCase.expected, `Test case ${i} failed`); + + i++; + } } - } - @test("Remove CSS Property") async removeCssProperty() { - if (this.activeEditor) { - // set activeBlock - this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); + @test(`Confirm Integrity After Modifications: (${testCases.modificationIntegrityTestCases.length} test cases)`) + async confirmIntegrity() { + let i = 0; - await this.updateActiveBlock("color", "#333", "remove"); + for (const testCase of testCases.modificationIntegrityTestCases) { + // reset document but provide contents instead of from file that is used from other test-cases + await this.resetDocument(testCase.inputCssString); + let text = this.currActiveEditor.document.getText(); - let payload = this.getPayloadForBlock( - this.activeEditor.document.getText(), - getCursorPositionPosition(5, 25) - ); + // Perform all transformations + for (const transformation of testCase.transformations) { + // set active block + this.getPayloadForBlock(text, getCursorPositionPosition(transformation.line, transformation.column)); + // update CSS + await this.updateActiveBlock(transformation.prop, transformation.value, transformation.type); + // Update the text with the updated code + text = this.currActiveEditor.document.getText(); + } - assert.deepEqual(payload, { - border: "1px solid #ccc", - padding: "10px" - }); - } else { - assert(false, "Active Editor was not initialized"); + const updatedDocumentText = this.currActiveEditor.document.getText(); + + expect(updatedDocumentText.trim()).to.deep.equal(testCase.outputCssString.trim(), `Test case ${i} failed`); + + i++; + } } } - } -}); + }); +} diff --git a/src/extension/test/index.ts b/src/extension/test/index.ts index 1f15001..5d526b0 100644 --- a/src/extension/test/index.ts +++ b/src/extension/test/index.ts @@ -10,14 +10,14 @@ // to report the results back to the caller. When the tests are finished, return // a possible error to the callback or null if none. -import * as testRunner from "vscode/lib/testrunner"; +import * as testRunner from 'vscode/lib/testrunner'; // You can directly control Mocha options by configuring the test runner below // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options // for more info testRunner.configure({ // ui: "tdd", // the TDD UI is being used in extension.test.ts (suite, test, etc.) - useColors: true // colored output from test results + useColors: true, // colored output from test results }); module.exports = testRunner; diff --git a/src/extension/test/test-cases/angular.test-case.ts b/src/extension/test/test-cases/angular.test-case.ts new file mode 100644 index 0000000..4157d5a --- /dev/null +++ b/src/extension/test/test-cases/angular.test-case.ts @@ -0,0 +1,246 @@ +import { TestCaseSetup } from '../test-types'; +import DecoratedClassComponentsInspector from '../../file-handlers/ts'; + +const testCases: TestCaseSetup = { + name: 'Test Angular Files', + inspector: DecoratedClassComponentsInspector, + languageId: 'typescript', + testFileName: 'test-angular.component.ts', + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [], +}; + +// prettier-ignore +testCases.parseTestCases = [ + { line: 11, column: 25, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 12, column: 27, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 13, column: 29, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 17, column: 21, expected: { 'padding': '4em', 'background': 'papayawhip' } }, + { line: 17, column: 22, expected: { 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 11, column: 25, prop: 'color', value: '#444', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#444' } }, + { line: 11, column: 25, prop: 'color', value: '#555', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#555' } }, + { line: 11, column: 25, prop: 'font-size', value: '3.0em', type: 'add', expected: { 'font-size': '3.0em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 17, column: 22, prop: 'background', value: 'black', type: 'add', expected: { 'padding': '4em', 'background': 'black' } }, + { line: 17, column: 22, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { 'padding': '10px 10px 10px 10px', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 11, column: 25, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 17, column: 22, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 11, column: 25, prop: 'font-size', value: '', type: 'remove', expected: { 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 11, column: 25, prop: 'text-align', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'color': 'palevioletred' } }, + { line: 11, column: 25, prop: 'color', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'text-align': 'center' } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 18, column: 21, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 18, column: 21, prop: 'text-align', value: 'center', type: 'add' }, + { line: 18, column: 21, prop: 'color', value: 'palevioletred', type: 'add' }, + ], + inputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + + .section { + padding: 4em; + background: papayawhip; + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + outputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + + .section { + padding: 4em; + background: papayawhip; + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 18, column: 21, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 18, column: 21, prop: 'text-align', value: 'center', type: 'add' }, + { line: 18, column: 21, prop: 'color', value: 'palevioletred', type: 'add' }, + { line: 18, column: 21, prop: 'padding', value: '', type: 'remove' }, + { line: 18, column: 21, prop: 'background', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'font-size', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'text-align', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + + .section { + padding: 4em; + background: papayawhip; + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + outputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + } + + .section { + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 18, column: 21, prop: 'padding', value: '', type: 'remove' }, + { line: 18, column: 21, prop: 'background', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'font-size', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'text-align', value: '', type: 'remove' }, + { line: 12, column: 25, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + font-size: 1.5em; + text-align: center; + color: palevioletred; + } + + .section { + padding: 4em; + background: papayawhip; + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + outputCssString: ` +// Mocked decorator to allow typescript to compile +function Component(target: any) { + return function(target: any) {}; +} + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styles: [ + \` + .h1 { + } + + .section { + } + \` + ] +}) +export class AppComponent { + title = 'fabulous-test'; +} +`, + } +]; + +export default testCases; diff --git a/src/extension/test/test-cases/css-file.test-case.ts b/src/extension/test/test-cases/css-file.test-case.ts new file mode 100644 index 0000000..af8a535 --- /dev/null +++ b/src/extension/test/test-cases/css-file.test-case.ts @@ -0,0 +1,82 @@ +import { TestCaseSetup } from "../test-types"; +import CSSFileInspector from "../../file-handlers/css-file"; + +const testCases: TestCaseSetup = { + name: "Test CSS Files", + inspector: CSSFileInspector, + languageId: "css", + testFileName: "test-css.css", + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [] +}; +// prettier-ignore +testCases.parseTestCases = [ + { line: 5, column: 25, expected: { border: "1px solid #ccc", padding: "10px", color: "#333" } }, + { line: 11, column: 22, expected: { "border-color": "green" } }, + { line: 15, column: 20, expected: { "border-color": "red" } }, + { line: 19, column: 23, expected: { "border-color": "yellow" } }, + { line: 21, column: 0, expected: null }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 5, column: 25, prop: 'color', value: '#444', type: 'add', expected: { border: "1px solid #ccc", padding: "10px", color: "#444" } }, + { line: 5, column: 25, prop: 'color', value: '#555', type: 'add', expected: { border: "1px solid #ccc", padding: "10px", color: "#555" } }, + { line: 5, column: 25, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { border: "1px solid #ccc", padding: "10px 10px 10px 10px", color: "#333" } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 11, column: 22, prop: 'color', value: '#444', type: 'add', expected: { "border-color": "green", color: "#444" } }, + { line: 11, column: 22, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { "border-color": "green", padding: "10px 10px 10px 10px" } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 5, column: 25, prop: 'color', value: "", type: 'remove', expected: { border: "1px solid #ccc", padding: "10px" } }, + { line: 5, column: 25, prop: 'border', value: "", type: 'remove', expected: { padding: "10px", color: "#333" } }, + { line: 5, column: 25, prop: 'padding', value: "", type: 'remove', expected: { border: "1px solid #ccc", color: "#333" } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 6, column: 20, prop: 'border-color', value: '#444', type: 'add' }, + { line: 10, column: 23, prop: 'border', value: '1px solid #ccc', type: 'add' }, + { line: 2, column: 22, prop: 'border-color', value: "", type: 'remove' }, + ], + inputCssString: ` +.success { + border-color: green; +} + +.error { + border-color: red; +} + +.warning { + border-color: yellow; +} +`, + outputCssString: ` +.success { +} + +.error { + border-color: #444; +} + +.warning { + border-color: yellow; + border: 1px solid #ccc; +} +` + } +]; + +export default testCases; diff --git a/src/extension/test/test-cases/html.test-case.ts b/src/extension/test/test-cases/html.test-case.ts new file mode 100644 index 0000000..8484e38 --- /dev/null +++ b/src/extension/test/test-cases/html.test-case.ts @@ -0,0 +1,145 @@ +import { TestCaseSetup } from '../test-types'; +import HtmlInspector from '../../file-handlers/html'; + +const testCases: TestCaseSetup = { + name: 'Test HTML Files', + inspector: HtmlInspector, + languageId: 'html', + testFileName: 'test-html.html', + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [], +}; + +// prettier-ignore +testCases.parseTestCases = [ + { line: 4, column: 25, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 5, column: 25, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 6, column: 25, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 10, column: 21, expected: { 'padding': '4em', 'background': 'papayawhip' } }, + { line: 11, column: 21, expected: { 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 4, column: 25, prop: 'color', value: '#444', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#444' } }, + { line: 4, column: 25, prop: 'color', value: '#555', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#555' } }, + { line: 4, column: 25, prop: 'font-size', value: '3.0em', type: 'add', expected: { 'font-size': '3.0em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 10, column: 15, prop: 'background', value: 'black', type: 'add', expected: { 'padding': '4em', 'background': 'black' } }, + { line: 10, column: 15, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { 'padding': '10px 10px 10px 10px', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 4, column: 25, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 10, column: 15, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 4, column: 20, prop: 'font-size', value: '', type: 'remove', expected: { 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 4, column: 20, prop: 'text-align', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'color': 'palevioletred' } }, + { line: 4, column: 20, prop: 'color', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'text-align': 'center' } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 11, column: 21, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 11, column: 21, prop: 'text-align', value: 'center', type: 'add' }, + { line: 11, column: 21, prop: 'color', value: 'palevioletred', type: 'add' }, + ], + inputCssString: ` + + + + + +`, + outputCssString: ` + + + + + +`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 10, column: 15, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 10, column: 15, prop: 'text-align', value: 'center', type: 'add' }, + { line: 10, column: 15, prop: 'color', value: 'palevioletred', type: 'add' }, + { line: 4, column: 15, prop: 'font-size', value: '', type: 'remove' }, + { line: 4, column: 15, prop: 'text-align', value: '', type: 'remove' }, + { line: 4, column: 15, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` + + + + + +`, + outputCssString: ` + + + + + +`, + }, +]; + +export default testCases; diff --git a/src/extension/test/test-cases/react.test-case.ts b/src/extension/test/test-cases/react.test-case.ts new file mode 100644 index 0000000..b4fb40e --- /dev/null +++ b/src/extension/test/test-cases/react.test-case.ts @@ -0,0 +1,173 @@ +import { TestCaseSetup } from '../test-types'; +import StyledComponentsInspector from '../../file-handlers/js'; + +const testCases: TestCaseSetup = { + name: 'Test React Files', + inspector: StyledComponentsInspector, + languageId: 'typescriptreact', + testFileName: 'test-react.tsx', + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [], +}; + +// prettier-ignore +testCases.parseTestCases = [ + { line: 7, column: 19, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 8, column: 21, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 9, column: 23, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 15, column: 15, expected: { 'padding': '4em', 'background': 'papayawhip' } }, + { line: 16, column: 16, expected: { 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 7, column: 19, prop: 'color', value: '#444', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#444' } }, + { line: 7, column: 19, prop: 'color', value: '#555', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#555' } }, + { line: 7, column: 19, prop: 'font-size', value: '3.0em', type: 'add', expected: { 'font-size': '3.0em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 15, column: 15, prop: 'background', value: 'black', type: 'add', expected: { 'padding': '4em', 'background': 'black' } }, + { line: 15, column: 15, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { 'padding': '10px 10px 10px 10px', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 7, column: 19, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 15, column: 15, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 7, column: 19, prop: 'font-size', value: '', type: 'remove', expected: { 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 7, column: 19, prop: 'text-align', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'color': 'palevioletred' } }, + { line: 7, column: 19, prop: 'color', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'text-align': 'center' } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 16, column: 15, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 16, column: 15, prop: 'text-align', value: 'center', type: 'add' }, + { line: 16, column: 15, prop: 'color', value: 'palevioletred', type: 'add' }, + ], + inputCssString: ` +import React from 'react'; + +import styled from 'styled-components'; + +// Create a react component that renders an <h1> which is +// centered, palevioletred and sized at 1.5em +const Title = styled.h1\` + font-size: 1.5em; + text-align: center; + color: palevioletred; +\`; + +// Create a <Wrapper> react component that renders a <section> with +// some padding and a papayawhip background +const Wrapper = styled.section\` + padding: 4em; + background: papayawhip; +\`; + +// Use them like any other React component – except they're styled! +<Wrapper> + <Title>Hello World, this is my first styled component! +; +`, + outputCssString: ` +import React from 'react'; + +import styled from 'styled-components'; + +// Create a react component that renders an <h1> which is +// centered, palevioletred and sized at 1.5em +const Title = styled.h1\` + font-size: 1.5em; + text-align: center; + color: palevioletred; +\`; + +// Create a <Wrapper> react component that renders a <section> with +// some padding and a papayawhip background +const Wrapper = styled.section\` + padding: 4em; + background: papayawhip; + font-size: 1.5em; + text-align: center; + color: palevioletred; +\`; + +// Use them like any other React component – except they're styled! +<Wrapper> + <Title>Hello World, this is my first styled component! +; +`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 16, column: 15, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 16, column: 15, prop: 'text-align', value: 'center', type: 'add' }, + { line: 16, column: 15, prop: 'color', value: 'palevioletred', type: 'add' }, + { line: 8, column: 19, prop: 'font-size', value: '', type: 'remove' }, + { line: 8, column: 19, prop: 'text-align', value: '', type: 'remove' }, + { line: 8, column: 19, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` +import React from 'react'; + +import styled from 'styled-components'; + +// Create a react component that renders an <h1> which is +// centered, palevioletred and sized at 1.5em +const Title = styled.h1\` + font-size: 1.5em; + text-align: center; + color: palevioletred; +\`; + +// Create a <Wrapper> react component that renders a <section> with +// some padding and a papayawhip background +const Wrapper = styled.section\` + padding: 4em; + background: papayawhip; +\`; + +// Use them like any other React component – except they're styled! +<Wrapper> + <Title>Hello World, this is my first styled component! +; +`, + outputCssString: ` +import React from 'react'; + +import styled from 'styled-components'; + +// Create a react component that renders an <h1> which is +// centered, palevioletred and sized at 1.5em +const Title = styled.h1\` +\`; + +// Create a <Wrapper> react component that renders a <section> with +// some padding and a papayawhip background +const Wrapper = styled.section\` + padding: 4em; + background: papayawhip; + font-size: 1.5em; + text-align: center; + color: palevioletred; +\`; + +// Use them like any other React component – except they're styled! +<Wrapper> + <Title>Hello World, this is my first styled component! +; +`, + }, +]; + +export default testCases; diff --git a/src/extension/test/test-cases/scss-file.test-case.ts b/src/extension/test/test-cases/scss-file.test-case.ts new file mode 100644 index 0000000..a2bfd9e --- /dev/null +++ b/src/extension/test/test-cases/scss-file.test-case.ts @@ -0,0 +1,123 @@ +import { TestCaseSetup } from "../test-types"; +import CSSFileInspector from "../../file-handlers/css-file"; + +const testCases: TestCaseSetup = { + name: "Test SCSS Files", + inspector: CSSFileInspector, + languageId: "scss", + testFileName: "test-scss.scss", + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [] +}; +// prettier-ignore +testCases.parseTestCases = [ + { line: 2, column: 25, expected: { border: "1px solid #ccc", padding: "10px", color: "#333" } }, + { line: 9, column: 16, expected: { display: "flex", "flex-wrap": "wrap" } }, + { line: 19, column: 22, expected: { "border-color": "green" } }, + { line: 23, column: 26, expected: { "border-color": "red" } }, + { line: 100, column: 0, expected: null }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 2, column: 25, prop: "color", value: "#444", type: "add", expected: { border: "1px solid #ccc", padding: "10px", color: "#444" } }, + { line: 2, column: 25, prop: "color", value: "#555", type: "add", expected: { border: "1px solid #ccc", padding: "10px", color: "#555" } }, + { line: 2, column: 25, prop: "padding", value: "10px 10px 10px 10px", type: "add", expected: { border: "1px solid #ccc", padding: "10px 10px 10px 10px", color: "#333" } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 4, column: 14, prop: "border-color", value: "black", type: "add", expected: { "border-color": "black", border: "1px solid #ccc", padding: "10px", color: "#333" } }, + { line: 14, column: 26, prop: "padding", value: "10px 10px 10px 10px", type: "add", expected: { padding: "10px 10px 10px 10px" } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 2, column: 25, prop: "color", value: "", type: "remove", expected: { border: "1px solid #ccc", padding: "10px" } }, + { line: 2, column: 25, prop: "border", value: "", type: "remove", expected: { padding: "10px", color: "#333" } }, + { line: 2, column: 25, prop: "padding", value: "", type: "remove", expected: { border: "1px solid #ccc", color: "#333" } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 10, column: 16, prop: "border", value: "1px solid #ccc", type: "add" }, + { line: 2, column: 22, prop: "border", value: "", type: "remove" }, + ], + inputCssString: ` +/* This CSS will print because %message-shared is extended. */ +%message-shared { + border: 1px solid #ccc; + padding: 10px; + color: #333; +} + +// This CSS won't print because %equal-heights is never extended. +%equal-heights { + display: flex; + flex-wrap: wrap; +} + +.message { + @extend %message-shared; +} + +.success { + @extend %message-shared; + border-color: green; +} + +.error { + @extend %message-shared; + border-color: red; +} + +.warning { + @extend %message-shared; + border-color: yellow; +} + +`, + outputCssString: ` +/* This CSS will print because %message-shared is extended. */ +%message-shared { + padding: 10px; + color: #333; +} + +// This CSS won't print because %equal-heights is never extended. +%equal-heights { + display: flex; + flex-wrap: wrap; + border: 1px solid #ccc; +} + +.message { + @extend %message-shared; +} + +.success { + @extend %message-shared; + border-color: green; +} + +.error { + @extend %message-shared; + border-color: red; +} + +.warning { + @extend %message-shared; + border-color: yellow; +} + +` + } +]; + +export default testCases; diff --git a/src/extension/test/test-cases/svelte.test-case.ts b/src/extension/test/test-cases/svelte.test-case.ts new file mode 100644 index 0000000..bc13772 --- /dev/null +++ b/src/extension/test/test-cases/svelte.test-case.ts @@ -0,0 +1,137 @@ +import { TestCaseSetup } from '../test-types'; +import HtmlInspector from '../../file-handlers/html'; + +const testCases: TestCaseSetup = { + name: 'Test Svelte Files', + inspector: HtmlInspector, + languageId: 'svelte', + testFileName: 'test-svelte.svelte', + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [], +}; + +// prettier-ignore +testCases.parseTestCases = [ + { line: 2, column: 15, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 3, column: 15, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 4, column: 15, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 8, column: 10, expected: { 'padding': '4em', 'background': 'papayawhip' } }, + { line: 9, column: 10, expected: { 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 2, column: 15, prop: 'color', value: '#444', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#444' } }, + { line: 2, column: 15, prop: 'color', value: '#555', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#555' } }, + { line: 2, column: 15, prop: 'font-size', value: '3.0em', type: 'add', expected: { 'font-size': '3.0em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 8, column: 10, prop: 'background', value: 'black', type: 'add', expected: { 'padding': '4em', 'background': 'black' } }, + { line: 8, column: 10, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { 'padding': '10px 10px 10px 10px', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 2, column: 15, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 8, column: 10, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 2, column: 15, prop: 'font-size', value: '', type: 'remove', expected: { 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 2, column: 15, prop: 'text-align', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'color': 'palevioletred' } }, + { line: 2, column: 15, prop: 'color', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'text-align': 'center' } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 9, column: 17, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 9, column: 17, prop: 'text-align', value: 'center', type: 'add' }, + { line: 9, column: 17, prop: 'color', value: 'palevioletred', type: 'add' }, + ], + inputCssString: ` + + +

Styled!

+`, + outputCssString: ` + + +

Styled!

+`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 8, column: 10, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 8, column: 10, prop: 'text-align', value: 'center', type: 'add' }, + { line: 8, column: 10, prop: 'color', value: 'palevioletred', type: 'add' }, + { line: 2, column: 15, prop: 'font-size', value: '', type: 'remove' }, + { line: 2, column: 15, prop: 'text-align', value: '', type: 'remove' }, + { line: 2, column: 15, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` + + +

Styled!

+`, + outputCssString: ` + + +

Styled!

+`, + }, +]; + +export default testCases; diff --git a/src/extension/test/test-cases/vue.test-case.ts b/src/extension/test/test-cases/vue.test-case.ts new file mode 100644 index 0000000..4f6152e --- /dev/null +++ b/src/extension/test/test-cases/vue.test-case.ts @@ -0,0 +1,251 @@ +import { TestCaseSetup } from '../test-types'; +import HtmlInspector from '../../file-handlers/html'; + +const testCases: TestCaseSetup = { + name: 'Test Vue Files', + inspector: HtmlInspector, + languageId: 'vue', + testFileName: 'test-vue.vue', + parseTestCases: [], + updateCssTestCases: [], + addCssTestCases: [], + removeCssTestCases: [], + modificationIntegrityTestCases: [], +}; + +// prettier-ignore +testCases.parseTestCases = [ + { line: 19, column: 19, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 20, column: 19, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 21, column: 19, expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 25, column: 10, expected: { 'padding': '4em', 'background': 'papayawhip' } }, + { line: 26, column: 10, expected: { 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.updateCssTestCases = [ + { line: 19, column: 19, prop: 'color', value: '#444', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#444' } }, + { line: 19, column: 19, prop: 'color', value: '#555', type: 'add', expected: { 'font-size': '1.5em', 'text-align': 'center', 'color': '#555' } }, + { line: 19, column: 19, prop: 'font-size', value: '3.0em', type: 'add', expected: { 'font-size': '3.0em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 25, column: 10, prop: 'background', value: 'black', type: 'add', expected: { 'padding': '4em', 'background': 'black' } }, + { line: 25, column: 10, prop: 'padding', value: '10px 10px 10px 10px', type: 'add', expected: { 'padding': '10px 10px 10px 10px', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.addCssTestCases = [ + { line: 19, column: 19, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'font-size': '1.5em', 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 25, column: 10, prop: 'border-color', value: 'black', type: 'add', expected: { 'border-color': 'black', 'padding': '4em', 'background': 'papayawhip' } }, +]; + +// prettier-ignore +testCases.removeCssTestCases = [ + { line: 19, column: 19, prop: 'font-size', value: '', type: 'remove', expected: { 'text-align': 'center', 'color': 'palevioletred' } }, + { line: 19, column: 19, prop: 'text-align', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'color': 'palevioletred' } }, + { line: 19, column: 19, prop: 'color', value: '', type: 'remove', expected: { 'font-size': '1.5em', 'text-align': 'center' } }, +]; + +// prettier-ignore +testCases.modificationIntegrityTestCases = [ + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 26, column: 15, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 26, column: 15, prop: 'text-align', value: 'center', type: 'add' }, + { line: 26, column: 15, prop: 'color', value: 'palevioletred', type: 'add' }, + ], + inputCssString: ` + + + + + + + + + + +`, + outputCssString: ` + + + + + + + + +`, + }, + { + // The order of these is important because it could change the line numbers based on operation + transformations: [ + { line: 25, column: 10, prop: 'font-size', value: '1.5em', type: 'add' }, + { line: 25, column: 10, prop: 'text-align', value: 'center', type: 'add' }, + { line: 25, column: 10, prop: 'color', value: 'palevioletred', type: 'add' }, + { line: 19, column: 19, prop: 'font-size', value: '', type: 'remove' }, + { line: 19, column: 19, prop: 'text-align', value: '', type: 'remove' }, + { line: 19, column: 19, prop: 'color', value: '', type: 'remove' }, + ], + inputCssString: ` + + + + + + + + +`, + outputCssString: ` + + + + + + + + +`, + }, +]; + +export default testCases; diff --git a/src/extension/test/test-files/test-angular.component.ts b/src/extension/test/test-files/test-angular.component.ts index 460efb1..35827cc 100644 --- a/src/extension/test/test-files/test-angular.component.ts +++ b/src/extension/test/test-files/test-angular.component.ts @@ -4,8 +4,8 @@ function Component(target: any) { } @Component({ - selector: "app-root", - templateUrl: "./app.component.html", + selector: 'app-root', + templateUrl: './app.component.html', styles: [ ` .h1 { @@ -18,9 +18,9 @@ function Component(target: any) { padding: 4em; background: papayawhip; } - ` - ] + `, + ], }) export class AppComponent { - title = "fabulous-test"; + title = 'fabulous-test'; } diff --git a/src/extension/test/test-files/test-html.html b/src/extension/test/test-files/test-html.html index c06e9e5..d00f4e4 100644 --- a/src/extension/test/test-files/test-html.html +++ b/src/extension/test/test-files/test-html.html @@ -2,12 +2,14 @@ diff --git a/src/extension/test/test-files/test-react.tsx b/src/extension/test/test-files/test-react.tsx index 2b674ce..0603db8 100644 --- a/src/extension/test/test-files/test-react.tsx +++ b/src/extension/test/test-files/test-react.tsx @@ -1,6 +1,6 @@ -import React from "react"; +import React from 'react'; -import styled from "styled-components"; +import styled from 'styled-components'; // Create a react component that renders an <h1> which is // centered, palevioletred and sized at 1.5em diff --git a/src/extension/test/test-files/test-svelte.svelte b/src/extension/test/test-files/test-svelte.svelte index 1fe8625..8db5521 100644 --- a/src/extension/test/test-files/test-svelte.svelte +++ b/src/extension/test/test-files/test-svelte.svelte @@ -1,20 +1,13 @@ <style> - p { - color: purple; - font-family: "Comic Sans MS"; - font-size: 2em; - } - .button { font-size: 1.5em; text-align: center; - color: red; + color: palevioletred; } - .button-close { - font-size: 1.5em; - text-align: center; - color: blue; + .buttonClose { + padding: 4em; + background: papayawhip; } </style> diff --git a/src/extension/test/test-files/test-vue.vue b/src/extension/test/test-files/test-vue.vue index 23bb951..fe03c34 100644 --- a/src/extension/test/test-files/test-vue.vue +++ b/src/extension/test/test-files/test-vue.vue @@ -1,64 +1,20 @@ <template> <nav class="navbar navbar-light"> - <div class="container"> - <router-link class="navbar-brand" :to="{ name: 'home' }">conduit</router-link> - <ul v-if="!isAuthenticated" class="nav navbar-nav pull-xs-right"> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" exact :to="{ name: 'home' }">Home</router-link> - </li> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" exact :to="{ name: 'login' }"> - <i class="ion-compose"></i>Sign in - </router-link> - </li> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" exact :to="{ name: 'register' }"> - <i class="ion-compose"></i>Sign up - </router-link> - </li> - </ul> - <ul v-else class="nav navbar-nav pull-xs-right"> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" exact :to="{ name: 'home' }">Home</router-link> - </li> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" :to="{ name: 'article-edit' }"> - <i class="ion-compose"></i> New Article - </router-link> - </li> - <li class="nav-item"> - <router-link class="nav-link" active-class="active" exact :to="{ name: 'settings' }"> - <i class="ion-gear-a"></i> Settings - </router-link> - </li> - <li class="nav-item" v-if="currentUser.username"> - <router-link - class="nav-link" - active-class="active" - exact - :to="{ - name: 'profile', - params: { username: currentUser.username } - }" - >{{ currentUser.username }}</router-link> - </li> - </ul> - </div> + <div class="container">Foo</div> </nav> </template> <script> -import { mapGetters } from "vuex"; +import { mapGetters } from 'vuex'; export default { - name: "RwvHeader", + name: 'RwvHeader', computed: { - ...mapGetters(["currentUser", "isAuthenticated"]) - } + ...mapGetters(['currentUser', 'isAuthenticated']), + }, }; </script> -<!-- Using the `scoped` attribute --> <style scoped> .button { font-size: 1.5em; @@ -66,10 +22,9 @@ export default { color: palevioletred; } -.button-close { - font-size: 1.5em; - text-align: center; - color: palevioletred; +.buttonClose { + padding: 4em; + background: papayawhip; } </style> @@ -86,14 +41,3 @@ export default { } </style> -<style> -.c-Button { - font-size: 1.5em; - text-align: center; - color: palevioletred; -} - -.c-Button--close { - background-color: red; -} -</style> diff --git a/src/extension/test/test-types.ts b/src/extension/test/test-types.ts new file mode 100644 index 0000000..61ad640 --- /dev/null +++ b/src/extension/test/test-types.ts @@ -0,0 +1,37 @@ +import { FileHandler, SupportedFiletypes, UpdateActiveBlockType } from '../file-handlers/types'; + +export interface TestCaseSetup { + name: string; + inspector: FileHandler; + languageId: SupportedFiletypes; + testFileName: string; + parseTestCases: ParseFileTestCase[]; + updateCssTestCases: ModifyCSSTestCase[]; + addCssTestCases: ModifyCSSTestCase[]; + removeCssTestCases: ModifyCSSTestCase[]; + modificationIntegrityTestCases: ModificationIntegrityTestCase[]; +} + +export interface LineCol { + line: number; + column: number; +} + +export interface PropValType { + prop: any; + value: string; + type: UpdateActiveBlockType; +} + +export interface Expected { + expected: any; +} + +export type ParseFileTestCase = LineCol & Expected; +export type ModifyCSSTestCase = LineCol & PropValType & Expected; + +export interface ModificationIntegrityTestCase { + transformations: (LineCol & PropValType)[]; + inputCssString: string; + outputCssString: string; +} diff --git a/src/extension/test/test-utils.ts b/src/extension/test/test-utils.ts index eb14cfb..5348325 100644 --- a/src/extension/test/test-utils.ts +++ b/src/extension/test/test-utils.ts @@ -1,30 +1,18 @@ -import * as vscode from "vscode"; -import * as path from "path"; +import * as vscode from 'vscode'; +import * as path from 'path'; export function getTestFile(filename: string) { - return path.join( - __dirname, - "../../../src/extension/test/test-files", - filename - ); + return path.join(__dirname, '../../../src/extension/test/test-files', filename); } export function createMockWebviewPanel(): vscode.WebviewPanel { - return vscode.window.createWebviewPanel( - "fabulous", - "Fabulous", - vscode.ViewColumn.Two, - { - enableScripts: true, - retainContextWhenHidden: true - } - ); + return vscode.window.createWebviewPanel('fabulous', 'Fabulous', vscode.ViewColumn.Two, { + enableScripts: true, + retainContextWhenHidden: true, + }); } -export function getCursorPositionPosition( - line: number, - col: number -): vscode.Position { +export function getCursorPositionPosition(line: number, col: number): vscode.Position { return new vscode.Position(line, col); } diff --git a/yarn.lock b/yarn.lock index 3f8ebae..eed13ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -868,6 +868,11 @@ resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.7.tgz#667eb1640e8039436028055737d2b9986ee336e3" integrity sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ== +"@types/chai@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" + integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== + "@types/mocha@^2.2.42": version "2.2.48" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" @@ -1344,6 +1349,11 @@ assert@^1.1.1: dependencies: util "0.10.3" +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -1776,6 +1786,18 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1790,6 +1812,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + chokidar@^2.0.2, chokidar@^2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" @@ -2289,6 +2316,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -3205,6 +3239,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -4991,6 +5030,11 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -6420,6 +6464,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"