Skip to content

Commit

Permalink
Add testing for Default Regex
Browse files Browse the repository at this point in the history
  • Loading branch information
Trapfether committed Oct 10, 2023
1 parent 3e6fd9c commit eb07b0d
Show file tree
Hide file tree
Showing 9 changed files with 1,146 additions and 284 deletions.
2 changes: 1 addition & 1 deletion build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ let context = await esbuild.context({
target: 'node14.21.3',
external: ["vscode"],
minify: true,
entryPoints: [path.resolve(__dirname, './src/index.js')],
entryPoints: [path.resolve(__dirname, './src/index.mjs')],
outfile: path.resolve(__dirname, './dist/index.js'),
format: 'cjs',
plugins: [patchRecast()],
Expand Down
1,229 changes: 963 additions & 266 deletions package-lock.json

Large diffs are not rendered by default.

47 changes: 30 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,34 +56,47 @@
"type": "object",
"default": {
"jade": [
{
"regex": "\\.([\\._a-zA-Z0-9\\-]+)",
"separator": "\\.",
"replacement": "."
},
"\\bclass\\s*=\\s*[\\\"\\']([\\._a-zA-Z0-9\\s\\-\\:\\/]+)[\\\"\\']"
{
"regex": "\\.([\\._a-zA-Z0-9\\-]+)",
"separator": "\\.",
"replacement": "."
},
"\\bclass\\s*=\\s*[\\\"\\']([\\._a-zA-Z0-9\\s\\-\\:\\/]+)[\\\"\\']"
],
"html": "\\bclass\\s*=\\s*[\\\"\\']([\\._a-zA-Z0-9\\s\\-\\:\\/]+)[\\\"\\']",
"html": [
["class=(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2","[\"'`]([^]+)"]
],
"css": "\\B@apply\\s+([\\._a-zA-Z0-9\\s\\-\\:\\/]+);",
"javascript": [
"(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\.\\w\\d\\s_\\-:/]+[\"'`])))",
"(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])"
[
"((?:class(?:Name)?|tw)\\s*=\\s*([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>]\\2)",
"(?:class(?:Name)?|tw)\\s*=\\s*(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2",
"[\"'`]([^]+)"
]
],
"javascriptreact": [
"(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
"(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])"
[
"((?:class(?:Name)?|tw)\\s*=\\s*{?([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>]\\2)",
"(?:class(?:Name)?|tw)\\s*=\\s*{?(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2",
"[\"'`]([^]+)"
]
],
"typescript": [
"(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
"(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])"
[
"((?:class(?:Name)?|tw)\\s*=\\s*([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>]\\2)",
"(?:class(?:Name)?|tw)\\s*=\\s*(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2",
"[\"'`]([^]+)"
]
],
"typescriptreact": [
"(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
"(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])"
[
"((?:class(?:Name)?|tw)\\s*=\\s*{?([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>]\\2)",
"(?:class(?:Name)?|tw)\\s*=\\s*{?(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2",
"[\"'`]([^]+)"
]
],
"php": [
"(?:\\b(?:class(?:Name)?|tw)\\s*=\\s*(?:(?:{([\\w\\d\\s!?_\\-:/${}()[\\]\"'`,]+)})|([\"'`][\\w\\d\\s_\\-:/]+[\"'`])))",
"(?:[\"'`]([\\.\\w\\d\\s_\\-:/${}()[\\]]+)[\"'`])"
["class=(([\"'`])(?:(?:[^{}<>](?!\\2))|\\\\\\2)+[^{}<>])\\2","[\"'`]([^]+)"]
]
},
"description": "An object with language IDs as keys and their values determining the regex to search for Tailwind CSS classes.",
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions test/language_examples/example.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p class="group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]">
PHP Regex should be able to match the class property on this element
</p>
<p class=" min-h-screen flex w-full justify-center p-2 bg-[#165f67]">
This has a class property that has tripped up the regex in the past, so we're testing it here for regression.
</p>

{{-- TODO: gather more real-world examples of class uses in PHP --}}
8 changes: 8 additions & 0 deletions test/language_examples/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p class="group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]">
PHP Regex should be able to match the class property on this element
</p>
<p class=" min-h-screen flex w-full justify-center p-2 bg-[#165f67]">
This has a class property that has tripped up the regex in the past, so we're testing it here for regression.
</p>

<!-- TODO: Gather more real-world examples of HTML uses of tailwind classes -->
34 changes: 34 additions & 0 deletions test/language_examples/example.react.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// react needs to support all of the vanilla js examples

const html = `
<p class="group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]">
PHP Regex should be able to match the class property on this element
</p>
<p class=" min-h-screen flex w-full justify-center p-2 bg-[#165f67]">
This has a class property that has tripped up the regex in the past, so we're testing it here for regression.
</p>`;

{
const className = 'group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]';
const tw = 'group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px] min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
}

{
const className = 'min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
const tw = 'min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
}

// React also needs to support uses of JSX

const p1 = <p className={'group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]'}>
PHP Regex should be able to match the class property on this element
</p>;
const p2 = <p className={'min-h-screen flex w-full justify-center p-2 bg-[#165f67]'}></p>

const p3 = <p className='group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px] min-h-screen flex w-full justify-center p-2 bg-[#165f67]'></p>
const p4 = <p className='min-h-screen flex w-full justify-center p-2 bg-[#165f67]'></p>

const p5 = <p className="group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px] min-h-screen flex w-full justify-center p-2 bg-[#165f67]"></p>
const p6 = <p className="min-h-screen flex w-full justify-center p-2 bg-[#165f67]"></p>

// TODO: gather more real-world examples of classnames in react
19 changes: 19 additions & 0 deletions test/language_examples/example.vanilla.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const html = `
<p class="group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]">
PHP Regex should be able to match the class property on this element
</p>
<p class=" min-h-screen flex w-full justify-center p-2 bg-[#165f67]">
This has a class property that has tripped up the regex in the past, so we're testing it here for regression.
</p>`;

{
const className = 'group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px]';
const tw = 'group block max-w-xs mx-auto rounded-lg p-6 bg-[#424242] ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500 border-[3px] min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
}

{
const className = 'min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
const tw = 'min-h-screen flex w-full justify-center p-2 bg-[#165f67]';
}

// TODO: gather more real-world examples of class attributes in JS
83 changes: 83 additions & 0 deletions test/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import pckge from '../package.json' assert { type: "json" };
import { getTextMatch, buildMatchers } from '../src/utils.mjs';
import { readFileSync } from 'fs';
import path from 'path';

import assert from 'assert';
import { describe } from 'mocha';

const langConfig = pckge.contributes.configuration[0].properties['tailwind-raw-reorder.classRegex'].default;

describe('Basic Regex', function () {
describe('PHP', function () {
const phpFilePath = path.resolve('./test/language_examples/example.blade.php');
const phpFile = readFileSync(phpFilePath, 'utf8');
const matchesTruth = phpFile.match(/class="((?:[^"{}<>]+|\\")+)"/g).map((value)=>{
return value.match(/class="((?:[^"{}<>]+|\\")+)"/)[1];
})
const matches = [];
const matchers = buildMatchers( langConfig['php'] );
for (const matcher of matchers) {
getTextMatch(matcher.regex, phpFile, (text, startPosition) => {
matches.push(text);
});
}
it('should match all classes', function () {
assert.deepEqual(matches, matchesTruth);
});
});

describe('HTML', function () {
const htmlFilePath = path.resolve('./test/language_examples/example.html');
const htmlFile = readFileSync(htmlFilePath, 'utf8');
const matchesTruth = htmlFile.match(/class="((?:[^"{}<>]+|\\")+)"/g).map((value)=>{
return value.match(/class="((?:[^"{}<>]+|\\")+)"/)[1];
})
const matches = [];
const matchers = buildMatchers( langConfig['html'] );
for (const matcher of matchers) {
getTextMatch(matcher.regex, htmlFile, (text, startPosition) => {
matches.push(text);
});
}
it('should match all classes', function () {
assert.deepEqual(matches, matchesTruth);
});
});

describe('JS', function () {
const jsFilePath = path.resolve('./test/language_examples/example.vanilla.js');
const jsFile = readFileSync(jsFilePath, 'utf8');
const matchesTruth = jsFile.match(/(?:class(?:Name)?|tw)\s*=\s*(["'`])(?:(?:[^{}<>](?!\1))|\\\1)+[^{}<>]\1/g).map((value)=>{
return value.match(/(?:class(?:Name)?|tw)\s*=\s*(["'`])((?:(?:[^{}<>](?!\1))|\\\1)+[^{}<>])\1/)[2];
})
const matches = [];
const matchers = buildMatchers( langConfig['javascript'] );
for (const matcher of matchers) {
getTextMatch(matcher.regex, jsFile, (text, startPosition) => {
matches.push(text);
});
}
it('should match all classes', function () {
assert.deepEqual(matches, matchesTruth);
});
});

describe('Javascript React', function () {
const jsxFilePath = path.resolve('./test/language_examples/example.react.jsx');
const jsxFile = readFileSync(jsxFilePath, 'utf8');
const matchesTruth = jsxFile.match(/(?:class(?:Name)?|tw)\s*=\s*{?(["'`])(?:(?:[^{}<>](?!\1))|\\\1)+[^{}<>]\1/g).map((value)=>{
return value.match(/(?:class(?:Name)?|tw)\s*=\s*{?(["'`])((?:(?:[^{}<>](?!\1))|\\\1)+[^{}<>])\1/)[2];
});
const matches = [];
const matchers = buildMatchers( langConfig['javascriptreact'] );
for (const matcher of matchers) {
getTextMatch(matcher.regex, jsxFile, (text, startPosition) => {
matches.push(text);
});
}
it('should match all classes', function () {
assert.deepEqual(matches, matchesTruth);
});
});
});

0 comments on commit eb07b0d

Please sign in to comment.