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 aStyled!
+`, + 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