From 60b7184f5874677c32e8e1037f39e617041a3739 Mon Sep 17 00:00:00 2001 From: mitch Date: Wed, 5 Mar 2025 09:41:21 -0500 Subject: [PATCH 1/6] code separated out for refactor, working on parity --- index.dev.html | 42 ----------- index.html | 2 +- src/variables/editor/editor.js | 3 +- src/variables/editor/vcGatherUsage-test.js | 77 +++++++++++++++++++ src/variables/editor/vcGatherUsage.js | 86 ++++++++++++++++++++++ 5 files changed, 166 insertions(+), 44 deletions(-) delete mode 100644 index.dev.html create mode 100644 src/variables/editor/vcGatherUsage-test.js create mode 100644 src/variables/editor/vcGatherUsage.js diff --git a/index.dev.html b/index.dev.html deleted file mode 100644 index 65564f13..00000000 --- a/index.dev.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - A2J Author 7 - - - - - - -
- - - - - - \ No newline at end of file diff --git a/index.html b/index.html index 9cc3a43f..dc8b1592 100644 --- a/index.html +++ b/index.html @@ -37,6 +37,6 @@ window.less = {async: true, fileSync: true}; - + \ No newline at end of file diff --git a/src/variables/editor/editor.js b/src/variables/editor/editor.js index 85de8256..261e310b 100644 --- a/src/variables/editor/editor.js +++ b/src/variables/editor/editor.js @@ -2,6 +2,7 @@ import DefineMap from 'can-define/map/map' import Component from 'can-component' import template from './editor.stache' import constants from '~/src/models/constants' +import { vcGatherUsage } from './vcGatherUsage' export const VariableEditorVM = DefineMap.extend('VariableEditorVM', { /* @@ -150,7 +151,7 @@ export const VariableEditorVM = DefineMap.extend('VariableEditorVM', { onFindUsage () { // use the initially loaded name in case they've edited it in the form before checking usage const variableName = this.initialVarName - const html = window.vcGatherUsage(variableName) + const html = vcGatherUsage(variableName) this.variableUsageHtml = html } }) diff --git a/src/variables/editor/vcGatherUsage-test.js b/src/variables/editor/vcGatherUsage-test.js new file mode 100644 index 00000000..dc636105 --- /dev/null +++ b/src/variables/editor/vcGatherUsage-test.js @@ -0,0 +1,77 @@ +import './viewer/A2J_Types' +// import './viewer/A2J_Prefs' +// import './viewer/A2J_SharedSus' +// import './viewer/A2J_Logic' +import 'jquery' +import './A2J_Tabs' + +import { assert } from 'chai' +import 'steal-mocha' +describe('vcGatherUsage', function () { + it('gathers usage on Page, Field, and Button level property values using variables', function () { + const usageTestPage = new window.TPage() + usageTestPage.fields = [new window.TField()] + usageTestPage.buttons = [new window.TButton()] + + window.gGuide.pages = { usageTestPage: usageTestPage } + + const testProps = { + page: [ + { key: 'name', type: 'regex', display: 'Page Name' }, + { key: 'text', type: 'regex', display: 'Question Text' }, + { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, + { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, + { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, + { key: 'help', type: 'regex', display: 'LearnMore Response' }, + { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, + { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, + { key: 'codeAfter', type: 'logic', display: 'After Logic' } + ], + fields: [ + { key: 'label', type: 'regex', display: 'Field Label' }, + { key: 'name', type: 'string', display: 'Field Variable' }, + { key: 'value', type: 'regex', display: 'Field Default Value' }, + { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, + { key: 'sample', type: 'regex', display: 'Field Sample Value' } + ], + buttons: [ + { key: 'label', type: 'regex', display: 'Button Label' }, + { key: 'name', type: 'string', display: 'Button Variable Name' }, + { key: 'value', type: 'regex', display: 'Button Default Value' }, + { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, + { key: 'url', type: 'regex', display: 'Button URL' } + ] + } + + const setTestProps = (targetMap, propsToSet) => { + for (const entry of propsToSet) { + const prop = entry.key + if (entry.type === 'regex') { + targetMap[prop] = 'macro style %%[Number NU]%%' + } else if (entry.type === 'logic') { + targetMap[prop] = 'SET [Number NU] TO 1' + } else { // direct var set + targetMap[prop] = 'Number NU' + } + } + } + setTestProps(usageTestPage, testProps.page) + setTestProps(usageTestPage.fields[0], testProps.fields) + setTestProps(usageTestPage.buttons[0], testProps.buttons) + + const foundMessage = window.vcGatherUsage('Number NU') + // if found, `display value` will be in foundMessage for each entry + for (const entry of testProps.page) { + const usedInPage = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.fields) { + const usedInField = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.buttons) { + const usedInButton = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + }) +}) diff --git a/src/variables/editor/vcGatherUsage.js b/src/variables/editor/vcGatherUsage.js new file mode 100644 index 00000000..ea490317 --- /dev/null +++ b/src/variables/editor/vcGatherUsage.js @@ -0,0 +1,86 @@ +export function vcGatherUsage (varName) { // 2015-03-27 Search for variable or constant + let html = '' + let count = 0 + let pageName + let lowerCaseVarName = varName.toLowerCase() + let regexString = `\\(\\s*${lowerCaseVarName}\\s*\\)|\\%\\s*${lowerCaseVarName}\\s*\\%|\\[\\s*${lowerCaseVarName}\\s*\\]` + let macroRegex = new RegExp(regexString, 'i') + for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. + /** @type TPage */ + var where = [] // list where it's on this page + let page = window.gGuide.pages[pageName] + + const findMatches = (searchTarget, usageItem) => { + // skip check if not string value to check + const prop = usageItem.key + if (!searchTarget[prop]) { return } + const testValue = searchTarget[prop].toLowerCase() + + if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` + const matches = testValue.match(macroRegex) + if (matches && matches.length) { + where.push(usageItem.display) + } + } else if (usageItem.type === 'logic') { + if (testValue.indexOf(lowerCaseVarName) !== -1) { // check for logic usage (no macro syntax, `set someVar to "foo"`) + where.push(usageItem.display) + } + } else { + if (testValue === lowerCaseVarName) { // check for varName itself, `someVar` + where.push(usageItem.display) + } + } + } + + // check top level page properties + const pageProps = [ + { key: 'name', type: 'regex', display: 'Page Name' }, + { key: 'text', type: 'regex', display: 'Question Text' }, + { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, + { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, + { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, + { key: 'help', type: 'regex', display: 'LearnMore Response' }, + { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, + { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, + { key: 'codeAfter', type: 'logic', display: 'After Logic' } + ] + for (const entry of pageProps) { + findMatches(page, entry) + } + + // check all page fields + const fieldProps = [ + { key: 'label', type: 'regex', display: 'Field Label' }, + { key: 'name', type: 'string', display: 'Field Variable' }, + { key: 'value', type: 'regex', display: 'Field Default Value' }, + { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, + { key: 'sample', type: 'regex', display: 'Field Sample Value' } + ] + for (const field of page.fields) { + for (const entry of fieldProps) { + findMatches(field, entry) + } + } + + // check all buttons + const buttonProps = [ + { key: 'label', type: 'regex', display: 'Button Label' }, + { key: 'name', type: 'string', display: 'Button Variable Name' }, + { key: 'value', type: 'regex', display: 'Button Default Value' }, + { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, + { key: 'url', type: 'regex', display: 'Button URL' } + ] + for (const button of page.buttons) { + for (const entry of buttonProps) { + findMatches(button, entry) + } + } + + if (where.length > 0) { // If we found anything, we'll list the page and its location. + count++ + html += ('
  • ' + page.name + '
  • ') + } + } + + return 'Used in ' + count + ' pages' + '' +} From d704aec54ae4b0a0fbfc2356194add34e9771a74 Mon Sep 17 00:00:00 2001 From: mitch Date: Fri, 7 Mar 2025 09:55:00 -0500 Subject: [PATCH 2/6] fix prod build script --- build.production.html.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.production.html.js b/build.production.html.js index eabc99f4..117c8d99 100644 --- a/build.production.html.js +++ b/build.production.html.js @@ -44,7 +44,7 @@ function template (version) { window.less = {async: true, fileSync: true}; - + ` } From f6cd9416fd0fdc61ebf6bd8aea7975b5c60cb11f Mon Sep 17 00:00:00 2001 From: mitch Date: Fri, 7 Mar 2025 10:01:18 -0500 Subject: [PATCH 3/6] lint fixes --- src/variables/editor/vcGatherUsage-test.js | 2 +- src/variables/editor/vcGatherUsage.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/variables/editor/vcGatherUsage-test.js b/src/variables/editor/vcGatherUsage-test.js index dc636105..14486499 100644 --- a/src/variables/editor/vcGatherUsage-test.js +++ b/src/variables/editor/vcGatherUsage-test.js @@ -13,7 +13,7 @@ describe('vcGatherUsage', function () { usageTestPage.fields = [new window.TField()] usageTestPage.buttons = [new window.TButton()] - window.gGuide.pages = { usageTestPage: usageTestPage } + window.gGuide.pages = { usageTestPage } const testProps = { page: [ diff --git a/src/variables/editor/vcGatherUsage.js b/src/variables/editor/vcGatherUsage.js index ea490317..bf49a762 100644 --- a/src/variables/editor/vcGatherUsage.js +++ b/src/variables/editor/vcGatherUsage.js @@ -2,13 +2,13 @@ export function vcGatherUsage (varName) { // 2015-03-27 Search for variable or c let html = '' let count = 0 let pageName - let lowerCaseVarName = varName.toLowerCase() - let regexString = `\\(\\s*${lowerCaseVarName}\\s*\\)|\\%\\s*${lowerCaseVarName}\\s*\\%|\\[\\s*${lowerCaseVarName}\\s*\\]` - let macroRegex = new RegExp(regexString, 'i') - for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. + const lowerCaseVarName = varName.toLowerCase() + const regexString = `\\(\\s*${lowerCaseVarName}\\s*\\)|\\%\\s*${lowerCaseVarName}\\s*\\%|\\[\\s*${lowerCaseVarName}\\s*\\]` + const macroRegex = new RegExp(regexString, 'i') + for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. /** @type TPage */ - var where = [] // list where it's on this page - let page = window.gGuide.pages[pageName] + const where = [] // list where it's on this page + const page = window.gGuide.pages[pageName] const findMatches = (searchTarget, usageItem) => { // skip check if not string value to check From 4634aaf60bf5bb459442934a20fc65954a457812 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 18 Mar 2025 11:01:57 -0500 Subject: [PATCH 4/6] Got first test to pass, started refactoring vcGatherUsage --- src/variables/editor/vcGatherUsage-test.html | 15 ++ src/variables/editor/vcGatherUsage-test.js | 190 ++++++++++++------- src/variables/editor/vcGatherUsage.js | 140 +++++++++----- test/test.js | 1 + 4 files changed, 225 insertions(+), 121 deletions(-) create mode 100644 src/variables/editor/vcGatherUsage-test.html diff --git a/src/variables/editor/vcGatherUsage-test.html b/src/variables/editor/vcGatherUsage-test.html new file mode 100644 index 00000000..07a2a262 --- /dev/null +++ b/src/variables/editor/vcGatherUsage-test.html @@ -0,0 +1,15 @@ + + + +vcGatherUsage Tests + +
    +
    + + + + diff --git a/src/variables/editor/vcGatherUsage-test.js b/src/variables/editor/vcGatherUsage-test.js index 14486499..8e6207bf 100644 --- a/src/variables/editor/vcGatherUsage-test.js +++ b/src/variables/editor/vcGatherUsage-test.js @@ -1,77 +1,127 @@ -import './viewer/A2J_Types' -// import './viewer/A2J_Prefs' -// import './viewer/A2J_SharedSus' -// import './viewer/A2J_Logic' import 'jquery' -import './A2J_Tabs' - import { assert } from 'chai' import 'steal-mocha' -describe('vcGatherUsage', function () { - it('gathers usage on Page, Field, and Button level property values using variables', function () { - const usageTestPage = new window.TPage() - usageTestPage.fields = [new window.TField()] - usageTestPage.buttons = [new window.TButton()] +import { vcGatherUsage, findMacroMatches } from './vcGatherUsage' + +describe('findMacroMatches', function () { + it.only('returns matches based on A2J Macro Syntax', function () { + const matches = findMacroMatches('Hello %%[Client First Name TE]%%, welcome to the interview!', 'Client First Name TE') + const expectedResult = [ '[Client First Name TE]' ] + console.log(matches) + assert.deepEqual(matches, expectedResult, 'should find one match') + }) +}) - window.gGuide.pages = { usageTestPage } +//Copy above function for other two branches in findMatches, make fail, go from there - const testProps = { - page: [ - { key: 'name', type: 'regex', display: 'Page Name' }, - { key: 'text', type: 'regex', display: 'Question Text' }, - { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, - { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, - { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, - { key: 'help', type: 'regex', display: 'LearnMore Response' }, - { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, - { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, - { key: 'codeAfter', type: 'logic', display: 'After Logic' } - ], - fields: [ - { key: 'label', type: 'regex', display: 'Field Label' }, - { key: 'name', type: 'string', display: 'Field Variable' }, - { key: 'value', type: 'regex', display: 'Field Default Value' }, - { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, - { key: 'sample', type: 'regex', display: 'Field Sample Value' } - ], - buttons: [ - { key: 'label', type: 'regex', display: 'Button Label' }, - { key: 'name', type: 'string', display: 'Button Variable Name' }, - { key: 'value', type: 'regex', display: 'Button Default Value' }, - { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, - { key: 'url', type: 'regex', display: 'Button URL' } - ] - } - const setTestProps = (targetMap, propsToSet) => { - for (const entry of propsToSet) { - const prop = entry.key - if (entry.type === 'regex') { - targetMap[prop] = 'macro style %%[Number NU]%%' - } else if (entry.type === 'logic') { - targetMap[prop] = 'SET [Number NU] TO 1' - } else { // direct var set - targetMap[prop] = 'Number NU' - } - } - } - setTestProps(usageTestPage, testProps.page) - setTestProps(usageTestPage.fields[0], testProps.fields) - setTestProps(usageTestPage.buttons[0], testProps.buttons) +// describe('vcGatherUsage', function () { +// let usageTestPage +// const testProps = { +// page: [ +// { key: 'name', type: 'regex', display: 'Page Name' }, +// { key: 'text', type: 'regex', display: 'Question Text' }, +// { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, +// { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, +// { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, +// { key: 'help', type: 'regex', display: 'LearnMore Response' }, +// { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, +// { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, +// { key: 'codeAfter', type: 'logic', display: 'After Logic' } +// ], +// fields: [ +// { key: 'label', type: 'regex', display: 'Field Label' }, +// { key: 'name', type: 'string', display: 'Field Variable' }, +// { key: 'value', type: 'regex', display: 'Field Default Value' }, +// { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, +// { key: 'sample', type: 'regex', display: 'Field Sample Value' } +// ], +// buttons: [ +// { key: 'label', type: 'regex', display: 'Button Label' }, +// { key: 'name', type: 'string', display: 'Button Variable Name' }, +// { key: 'value', type: 'regex', display: 'Button Default Value' }, +// { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, +// { key: 'url', type: 'regex', display: 'Button URL' } +// ] +// } - const foundMessage = window.vcGatherUsage('Number NU') - // if found, `display value` will be in foundMessage for each entry - for (const entry of testProps.page) { - const usedInPage = foundMessage.indexOf(entry.display) !== -1 - assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) - } - for (const entry of testProps.fields) { - const usedInField = foundMessage.indexOf(entry.display) !== -1 - assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) - } - for (const entry of testProps.buttons) { - const usedInButton = foundMessage.indexOf(entry.display) !== -1 - assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) - } - }) -}) +// beforeEach(() => { +// usageTestPage = new window.TPage() +// usageTestPage.fields = [new window.TField()] +// usageTestPage.buttons = [new window.TButton()] + +// const gGuide = new window.TGuide() +// window.gGuide = gGuide +// window.gGuide.pages = { usageTestPage } +// }) + +// afterEach(() => { +// window.gGuide = null +// }) + +// it('gathers usage on Page, Field, and Button level property values using variables', function () { +// const setTestProps = (targetMap, propsToSet) => { +// for (const entry of propsToSet) { +// const prop = entry.key +// if (entry.type === 'regex') { +// targetMap[prop] = 'macro style %%[Number NU]%%' +// } else if (entry.type === 'logic') { +// targetMap[prop] = 'SET [Number NU] TO 1' +// } else { // direct var set +// targetMap[prop] = 'Number NU' +// } +// } +// } +// setTestProps(usageTestPage, testProps.page) +// setTestProps(usageTestPage.fields[0], testProps.fields) +// setTestProps(usageTestPage.buttons[0], testProps.buttons) + +// const foundMessage = vcGatherUsage('Number NU') +// // if found, `display value` will be in foundMessage for each entry +// for (const entry of testProps.page) { +// const usedInPage = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// for (const entry of testProps.fields) { +// const usedInField = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// for (const entry of testProps.buttons) { +// const usedInButton = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// }) + +// it('gathers explicit usage on Page, Field, and Button level property values using variables', function () { +// const setTestProps = (targetMap, propsToSet) => { +// for (const entry of propsToSet) { +// const prop = entry.key +// if (entry.type === 'regex') { +// targetMap[prop] = 'macro style %%[Number NU]%%' +// } else if (entry.type === 'logic') { +// targetMap[prop] = 'SET [Number123 NU] TO 1' +// } else { // direct var set +// targetMap[prop] = 'Number foo NU' +// } +// } +// } +// setTestProps(usageTestPage, testProps.page) +// setTestProps(usageTestPage.fields[0], testProps.fields) +// setTestProps(usageTestPage.buttons[0], testProps.buttons) + +// const foundMessage = vcGatherUsage('Number NU') +// // if found, `display value` will be in foundMessage for each entry +// for (const entry of testProps.page) { +// const usedInPage = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// for (const entry of testProps.fields) { +// const usedInField = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// for (const entry of testProps.buttons) { +// const usedInButton = foundMessage.indexOf(entry.display) !== -1 +// assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) +// } +// }) +// }) diff --git a/src/variables/editor/vcGatherUsage.js b/src/variables/editor/vcGatherUsage.js index bf49a762..7e0ff711 100644 --- a/src/variables/editor/vcGatherUsage.js +++ b/src/variables/editor/vcGatherUsage.js @@ -1,61 +1,106 @@ -export function vcGatherUsage (varName) { // 2015-03-27 Search for variable or constant +const pageProps = [ + { key: 'name', type: 'regex', display: 'Page Name' }, + { key: 'text', type: 'regex', display: 'Question Text' }, + { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, + { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, + { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, + { key: 'help', type: 'regex', display: 'LearnMore Response' }, + { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, + { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, + { key: 'codeAfter', type: 'logic', display: 'After Logic' } +] +const fieldProps = [ + { key: 'label', type: 'regex', display: 'Field Label' }, + { key: 'name', type: 'string', display: 'Field Variable' }, + { key: 'value', type: 'regex', display: 'Field Default Value' }, + { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, + { key: 'sample', type: 'regex', display: 'Field Sample Value' } +] +const buttonProps = [ + { key: 'label', type: 'regex', display: 'Button Label' }, + { key: 'name', type: 'string', display: 'Button Variable Name' }, + { key: 'value', type: 'regex', display: 'Button Default Value' }, + { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, + { key: 'url', type: 'regex', display: 'Button URL' } +] + +/* +All three tests greedy if explicitSearch = notTrue +Test 3 currently is explicit (testValue === lowerCaseVarName) +Make test 3 greedy + +-i believe this can be solved with .includes, maybe a + if(testValue.includes(lowerCaseVarName)){ + where.push(usageItem.display) + } + +Rename three regex consts + +-could simply be + parenRegexString `^\\(\\s*${lowerCaseVarName}\\s*\\)$` + percentRegexString `^\\%\\s*${lowerCaseVarName}\\s*\\%$` + bracketRegexString `^\\[\\s*${lowerCaseVarName}\\s*\\]$` + if explicitSearch === true, use search Regex with ^/$ + +*After above is done* +If explicit, find explicit matches +Either if/else or find Explicit function + +*/ + +export const findMacroMatches = (testValue, varName) => { + const lowerCaseVarName = varName.toLowerCase() + const parenRegexString = `\\(\\s*${lowerCaseVarName}\\s*\\)` + const percentRegexString = `\\%\\s*${lowerCaseVarName}\\s*\\%` + const bracketRegexString = `\\[\\s*${lowerCaseVarName}\\s*\\]` + const regexString = `${parenRegexString} | ${percentRegexString} | ${bracketRegexString}` + const macroRegex = new RegExp(regexString, 'i') + + const matches = testValue.match(macroRegex) + + return matches +} + +export const findMatches = (searchTarget, usageItem) => { + // skip check if not string value to check + const prop = usageItem.key + if (!searchTarget[prop]) { return } + const testValue = searchTarget[prop].toLowerCase() + + if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` + const matches = testValue.match(macroRegex) + if (matches && matches.length) { + where.push(usageItem.display) + } + } else if (usageItem.type === 'logic') { + if (testValue.indexOf(lowerCaseVarName) !== -1) { // check for logic usage (no macro syntax, `set someVar to "foo"`) + where.push(usageItem.display) + } + } else { + if (testValue === lowerCaseVarName) { // check for varName itself, `someVar` + where.push(usageItem.display) + } + } +} + +export function vcGatherUsage (varName, explicitSearch) { // 2015-03-27 Search for variable or constant + // alter below line to test two search methods + explicitSearch = true let html = '' let count = 0 let pageName - const lowerCaseVarName = varName.toLowerCase() - const regexString = `\\(\\s*${lowerCaseVarName}\\s*\\)|\\%\\s*${lowerCaseVarName}\\s*\\%|\\[\\s*${lowerCaseVarName}\\s*\\]` - const macroRegex = new RegExp(regexString, 'i') + for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. /** @type TPage */ const where = [] // list where it's on this page const page = window.gGuide.pages[pageName] - const findMatches = (searchTarget, usageItem) => { - // skip check if not string value to check - const prop = usageItem.key - if (!searchTarget[prop]) { return } - const testValue = searchTarget[prop].toLowerCase() - - if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` - const matches = testValue.match(macroRegex) - if (matches && matches.length) { - where.push(usageItem.display) - } - } else if (usageItem.type === 'logic') { - if (testValue.indexOf(lowerCaseVarName) !== -1) { // check for logic usage (no macro syntax, `set someVar to "foo"`) - where.push(usageItem.display) - } - } else { - if (testValue === lowerCaseVarName) { // check for varName itself, `someVar` - where.push(usageItem.display) - } - } - } - // check top level page properties - const pageProps = [ - { key: 'name', type: 'regex', display: 'Page Name' }, - { key: 'text', type: 'regex', display: 'Question Text' }, - { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, - { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, - { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, - { key: 'help', type: 'regex', display: 'LearnMore Response' }, - { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, - { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, - { key: 'codeAfter', type: 'logic', display: 'After Logic' } - ] for (const entry of pageProps) { findMatches(page, entry) } // check all page fields - const fieldProps = [ - { key: 'label', type: 'regex', display: 'Field Label' }, - { key: 'name', type: 'string', display: 'Field Variable' }, - { key: 'value', type: 'regex', display: 'Field Default Value' }, - { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, - { key: 'sample', type: 'regex', display: 'Field Sample Value' } - ] for (const field of page.fields) { for (const entry of fieldProps) { findMatches(field, entry) @@ -63,13 +108,6 @@ export function vcGatherUsage (varName) { // 2015-03-27 Search for variable or c } // check all buttons - const buttonProps = [ - { key: 'label', type: 'regex', display: 'Button Label' }, - { key: 'name', type: 'string', display: 'Button Variable Name' }, - { key: 'value', type: 'regex', display: 'Button Default Value' }, - { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, - { key: 'url', type: 'regex', display: 'Button URL' } - ] for (const button of page.buttons) { for (const entry of buttonProps) { findMatches(button, entry) diff --git a/test/test.js b/test/test.js index 6195ceaf..32f913a4 100644 --- a/test/test.js +++ b/test/test.js @@ -23,3 +23,4 @@ import 'a2jauthor/src/pages-tab/components/var-picker/field/var-picker-field-tes // import 'a2jauthor/src/templates/edit/toolbar/toolbar-test' // import 'a2jauthor/src/templates/list/item/item-test' // import 'a2jauthor/src/templates/list/sortbar/sortbar-test' +import 'a2jauthor/src/variables/editor/vcGatherUsage-test.js' From 7bd7a21f60a02108a403aac547ea2f0c7b1ef33c Mon Sep 17 00:00:00 2001 From: lucas Date: Mon, 28 Apr 2025 13:01:20 -0500 Subject: [PATCH 5/6] Adding final changes to Matches trio --- src/variables/editor/vcGatherUsage-test.js | 46 +++++++++-- src/variables/editor/vcGatherUsage.js | 89 ++++++++++++++++------ 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/src/variables/editor/vcGatherUsage-test.js b/src/variables/editor/vcGatherUsage-test.js index 8e6207bf..2fea1db5 100644 --- a/src/variables/editor/vcGatherUsage-test.js +++ b/src/variables/editor/vcGatherUsage-test.js @@ -1,18 +1,52 @@ import 'jquery' import { assert } from 'chai' import 'steal-mocha' -import { vcGatherUsage, findMacroMatches } from './vcGatherUsage' +import { vcGatherUsage, findMacroMatches, findLogicMatches, findLiteralMatches} from './vcGatherUsage' + +// Tests for these functions reflect that varname and testValue will be lowercase by the point they reach these functions describe('findMacroMatches', function () { it.only('returns matches based on A2J Macro Syntax', function () { - const matches = findMacroMatches('Hello %%[Client First Name TE]%%, welcome to the interview!', 'Client First Name TE') - const expectedResult = [ '[Client First Name TE]' ] - console.log(matches) - assert.deepEqual(matches, expectedResult, 'should find one match') + const matches = findMacroMatches('Enter your mailing address, %%[Client First Name TE ]%%', 'Client First Name TE') + const matches2 = findMacroMatches('Enter your mailing address, %%[Client First Name TE D]%%', 'Client First Name TE') + const matches3 = findMacroMatches('Enter your mailing address, %%[ Client First Name TE ]%%', 'Client First Name TE') + + //explicit = true should pass, fail, pass + //explicit = false should pass all + assert.deepEqual(matches, ['[Client First Name TE ]'], 'Should find one match') + assert.deepEqual(matches2, ['[Client First Name TE D]'], 'Should find one match') + assert.deepEqual(matches3, [ '[ Client First Name TE ]' ], 'Should find one match') }) }) -//Copy above function for other two branches in findMatches, make fail, go from there + +// describe('findLogicMatches', function () { +// it.only('Returns true search target is matched', function () { +// const matches = findLogicMatches('set client first name te to "matt"','client first name te') +// const matches2 = findLogicMatches("set [client last name te] to 'matt'",'client first name te') + +// assert.deepEqual(matches, true, "should return true if match is found") +// assert.deepEqual(matches2, null, "should return null if no match is found") +// }) +// }) + +describe('findLiteralMatches', function () { + it.only('Returns true if target matches exactly', function () { + const matches = findLiteralMatches('client age', 'clientage') + const matches2 = findLiteralMatches('client age', 'CLIENT AGE') + + assert.deepEqual(matches, null, "should return null if no match found") + assert.deepEqual(matches2, true, "Returns true if exact match") + }) +}) + +// saving just in case +// const matches = findLiteralMatches('client age', 'client age') +// const matches2 = findLiteralMatches('age', 'client age') + +// assert.deepEqual(matches, true, "should return true if exact match") +// assert.deepEqual(matches2, false, "should return false if not exact match") + // describe('vcGatherUsage', function () { diff --git a/src/variables/editor/vcGatherUsage.js b/src/variables/editor/vcGatherUsage.js index 7e0ff711..00f6fa3e 100644 --- a/src/variables/editor/vcGatherUsage.js +++ b/src/variables/editor/vcGatherUsage.js @@ -1,3 +1,5 @@ +import { lowerCase } from "lodash" + const pageProps = [ { key: 'name', type: 'regex', display: 'Page Name' }, { key: 'text', type: 'regex', display: 'Question Text' }, @@ -29,11 +31,6 @@ All three tests greedy if explicitSearch = notTrue Test 3 currently is explicit (testValue === lowerCaseVarName) Make test 3 greedy --i believe this can be solved with .includes, maybe a - if(testValue.includes(lowerCaseVarName)){ - where.push(usageItem.display) - } - Rename three regex consts -could simply be @@ -46,38 +43,81 @@ Rename three regex consts If explicit, find explicit matches Either if/else or find Explicit function +const match = findMatches() +if (match) { add to where[] } + +Type Match = { +pageName: +location: +foundCount: +} + */ -export const findMacroMatches = (testValue, varName) => { - const lowerCaseVarName = varName.toLowerCase() - const parenRegexString = `\\(\\s*${lowerCaseVarName}\\s*\\)` - const percentRegexString = `\\%\\s*${lowerCaseVarName}\\s*\\%` - const bracketRegexString = `\\[\\s*${lowerCaseVarName}\\s*\\]` - const regexString = `${parenRegexString} | ${percentRegexString} | ${bracketRegexString}` - const macroRegex = new RegExp(regexString, 'i') +export const findMacroMatches = (testValue, lowerCaseVarName, explicit) => { + explicit = false; + + //For greedy search, Regex looks for lowerCaseVarName followed by any character 0+ times, then white space 0+ times, then the closing half of bracket, paren, percent + const parenRegexString = `\\(\\s*${lowerCaseVarName}.*\\s*\\)` + const percentRegexString = `\\%\\s*${lowerCaseVarName}.*\\s*\\%` + const bracketRegexString = `\\[\\s*${lowerCaseVarName}.*\\s*\\]` + + //For explicit search, Regex ends with '$', meaning nothing can follow + const parenRegexStringX = `\\(\\s*${lowerCaseVarName}\\s*\\)` + const percentRegexStringX = `\\%\\s*${lowerCaseVarName}\\s*\\%` + const bracketRegexStringX = `\\[\\s*${lowerCaseVarName}\\s*\\]` + + const regexString = `${parenRegexString}|${percentRegexString}|${bracketRegexString}` + const regexStringX = `${parenRegexStringX}|${percentRegexStringX}|${bracketRegexStringX}` + + //Checks explicit and uses the appropriate regexString to make macroRegex + const macroRegex = (explicit === false) ? new RegExp(regexString, 'ig'): new RegExp(regexStringX, 'ig') const matches = testValue.match(macroRegex) + console.log(matches) + return matches ? matches :[] +} + +export const findLogicMatches = (testValue, lowerCaseVarName) => { + const logicRegexString = `${lowerCaseVarName}` + const logicRegex = new RegExp(logicRegexString, 'ig') - return matches + const matches = testValue.match(logicRegex) + + return matches ? matches :[] } -export const findMatches = (searchTarget, usageItem) => { +export const findLiteralMatches =(testValue, lowerCaseVarName) => { + // finds variables assigned explicitly to buttons, fields, and counting variables + const literalRegexString = `${lowerCaseVarName}` + const literalRegex = new RegExp(literalRegexString, 'ig') + + const matches = testValue.match(literalRegex) + + return matches ? matches :[] +} + +export const findMatches = (searchTarget, usageItem, varName) => { // skip check if not string value to check const prop = usageItem.key if (!searchTarget[prop]) { return } const testValue = searchTarget[prop].toLowerCase() + const lowerCaseVarName = varName.toLowerCase() if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` - const matches = testValue.match(macroRegex) - if (matches && matches.length) { + const found = findMacroMatches(testValue, lowerCaseVarName) + if (found) { where.push(usageItem.display) + console.log(where) } } else if (usageItem.type === 'logic') { - if (testValue.indexOf(lowerCaseVarName) !== -1) { // check for logic usage (no macro syntax, `set someVar to "foo"`) + const found = findLogicMatches(testValue, lowerCaseVarName) + if (found) { // check for logic usage (no macro syntax, `set someVar to "foo"`) where.push(usageItem.display) } } else { - if (testValue === lowerCaseVarName) { // check for varName itself, `someVar` + const found = findLiteralMatches(testValue, lowerCaseVarName) + if (found) { // check for varName itself, `someVar` where.push(usageItem.display) } } @@ -92,29 +132,32 @@ export function vcGatherUsage (varName, explicitSearch) { // 2015-03-27 Search f for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. /** @type TPage */ - const where = [] // list where it's on this page + let where = [] // list where it's on this page const page = window.gGuide.pages[pageName] + let pageMatches, fieldMatches, buttonMatches // check top level page properties for (const entry of pageProps) { - findMatches(page, entry) + pageMatches = findMatches(page, entry, varName) + // populate where array here! } // check all page fields for (const field of page.fields) { for (const entry of fieldProps) { - findMatches(field, entry) + fieldMatches = findMatches(field, entry, varName) } } // check all buttons for (const button of page.buttons) { for (const entry of buttonProps) { - findMatches(button, entry) + buttonMatches = findMatches(button, entry, varName) } } + where = [...where, ...pageMatches, ...fieldMatches, ...buttonMatches] - if (where.length > 0) { // If we found anything, we'll list the page and its location. + if (where.length) { // If we found anything, we'll list the page and its location. count++ html += ('
  • ' + page.name + '
    • ' + '
    • ' + where.join('
    • ') + '
    ') } From 839579248c4ca09c6481c477d83c63dd3af3917d Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 3 Jun 2025 20:02:24 -0500 Subject: [PATCH 6/6] Cleaned up comments and code, making pull request and checklist fo what is left --- src/variables/editor/vcGatherUsage-test.js | 267 +++++++++++---------- src/variables/editor/vcGatherUsage.js | 61 ++--- 2 files changed, 159 insertions(+), 169 deletions(-) diff --git a/src/variables/editor/vcGatherUsage-test.js b/src/variables/editor/vcGatherUsage-test.js index 2fea1db5..b6c4aab3 100644 --- a/src/variables/editor/vcGatherUsage-test.js +++ b/src/variables/editor/vcGatherUsage-test.js @@ -1,7 +1,7 @@ import 'jquery' import { assert } from 'chai' import 'steal-mocha' -import { vcGatherUsage, findMacroMatches, findLogicMatches, findLiteralMatches} from './vcGatherUsage' +import { vcGatherUsage, findMacroMatches, findLogicMatches, findLiteralMatches, findMatches} from './vcGatherUsage' // Tests for these functions reflect that varname and testValue will be lowercase by the point they reach these functions @@ -13,149 +13,154 @@ describe('findMacroMatches', function () { //explicit = true should pass, fail, pass //explicit = false should pass all + assert.deepEqual(matches, ['[Client First Name TE ]'], 'Should find one match') assert.deepEqual(matches2, ['[Client First Name TE D]'], 'Should find one match') assert.deepEqual(matches3, [ '[ Client First Name TE ]' ], 'Should find one match') }) }) +describe('findLogicMatches', function () { + it.only('Returns true search target is matched', function () { + const matches = findLogicMatches('set client first name te to "matt"','client first name te') + const matches2 = findLogicMatches("set [client last name te] to 'matt'",'client first name te') -// describe('findLogicMatches', function () { -// it.only('Returns true search target is matched', function () { -// const matches = findLogicMatches('set client first name te to "matt"','client first name te') -// const matches2 = findLogicMatches("set [client last name te] to 'matt'",'client first name te') - -// assert.deepEqual(matches, true, "should return true if match is found") -// assert.deepEqual(matches2, null, "should return null if no match is found") -// }) -// }) + assert.deepEqual(matches, true, "should return true if match is found") + assert.deepEqual(matches2, null, "should return null if no match is found") + }) +}) describe('findLiteralMatches', function () { it.only('Returns true if target matches exactly', function () { const matches = findLiteralMatches('client age', 'clientage') const matches2 = findLiteralMatches('client age', 'CLIENT AGE') - assert.deepEqual(matches, null, "should return null if no match found") - assert.deepEqual(matches2, true, "Returns true if exact match") + assert.deepEqual(matches, [], "should return null if no match found") + assert.deepEqual(matches2, [ 'client age'], "Returns true if exact match") + }) +}) + +//Find Matches currently needs regex type things to have bracket, paren, percent, logic and literal +describe('findMatches', function () { + it.only('Returns found if it finds a match', function() { + const testButton = {name:'', label:'', value:'', repeatVar:' [CLIENT FIRST NAME TE] ', url:''} + const testEntry = {key: 'repeatVar', type: 'regex', display: 'Button Counting Variable' } + const testVarName = 'Client First Name TE' + + const found = findMatches(testButton, testEntry, testVarName) + + assert.deepEqual(found, [ '[client first name te]' ], "testing") }) }) -// saving just in case -// const matches = findLiteralMatches('client age', 'client age') -// const matches2 = findLiteralMatches('age', 'client age') - -// assert.deepEqual(matches, true, "should return true if exact match") -// assert.deepEqual(matches2, false, "should return false if not exact match") - - - -// describe('vcGatherUsage', function () { -// let usageTestPage -// const testProps = { -// page: [ -// { key: 'name', type: 'regex', display: 'Page Name' }, -// { key: 'text', type: 'regex', display: 'Question Text' }, -// { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, -// { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, -// { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, -// { key: 'help', type: 'regex', display: 'LearnMore Response' }, -// { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, -// { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, -// { key: 'codeAfter', type: 'logic', display: 'After Logic' } -// ], -// fields: [ -// { key: 'label', type: 'regex', display: 'Field Label' }, -// { key: 'name', type: 'string', display: 'Field Variable' }, -// { key: 'value', type: 'regex', display: 'Field Default Value' }, -// { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, -// { key: 'sample', type: 'regex', display: 'Field Sample Value' } -// ], -// buttons: [ -// { key: 'label', type: 'regex', display: 'Button Label' }, -// { key: 'name', type: 'string', display: 'Button Variable Name' }, -// { key: 'value', type: 'regex', display: 'Button Default Value' }, -// { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, -// { key: 'url', type: 'regex', display: 'Button URL' } -// ] -// } - -// beforeEach(() => { -// usageTestPage = new window.TPage() -// usageTestPage.fields = [new window.TField()] -// usageTestPage.buttons = [new window.TButton()] - -// const gGuide = new window.TGuide() -// window.gGuide = gGuide -// window.gGuide.pages = { usageTestPage } -// }) - -// afterEach(() => { -// window.gGuide = null -// }) - -// it('gathers usage on Page, Field, and Button level property values using variables', function () { -// const setTestProps = (targetMap, propsToSet) => { -// for (const entry of propsToSet) { -// const prop = entry.key -// if (entry.type === 'regex') { -// targetMap[prop] = 'macro style %%[Number NU]%%' -// } else if (entry.type === 'logic') { -// targetMap[prop] = 'SET [Number NU] TO 1' -// } else { // direct var set -// targetMap[prop] = 'Number NU' -// } -// } -// } -// setTestProps(usageTestPage, testProps.page) -// setTestProps(usageTestPage.fields[0], testProps.fields) -// setTestProps(usageTestPage.buttons[0], testProps.buttons) - -// const foundMessage = vcGatherUsage('Number NU') -// // if found, `display value` will be in foundMessage for each entry -// for (const entry of testProps.page) { -// const usedInPage = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// for (const entry of testProps.fields) { -// const usedInField = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// for (const entry of testProps.buttons) { -// const usedInButton = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// }) - -// it('gathers explicit usage on Page, Field, and Button level property values using variables', function () { -// const setTestProps = (targetMap, propsToSet) => { -// for (const entry of propsToSet) { -// const prop = entry.key -// if (entry.type === 'regex') { -// targetMap[prop] = 'macro style %%[Number NU]%%' -// } else if (entry.type === 'logic') { -// targetMap[prop] = 'SET [Number123 NU] TO 1' -// } else { // direct var set -// targetMap[prop] = 'Number foo NU' -// } -// } -// } -// setTestProps(usageTestPage, testProps.page) -// setTestProps(usageTestPage.fields[0], testProps.fields) -// setTestProps(usageTestPage.buttons[0], testProps.buttons) - -// const foundMessage = vcGatherUsage('Number NU') -// // if found, `display value` will be in foundMessage for each entry -// for (const entry of testProps.page) { -// const usedInPage = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// for (const entry of testProps.fields) { -// const usedInField = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// for (const entry of testProps.buttons) { -// const usedInButton = foundMessage.indexOf(entry.display) !== -1 -// assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) -// } -// }) -// }) +describe('vcGatherUsage', function () { + let usageTestPage + const testProps = { + page: [ + { key: 'name', type: 'regex', display: 'Page Name' }, + { key: 'text', type: 'regex', display: 'Question Text' }, + { key: 'repeatVar', type: 'string', display: 'Counting Variable' }, + { key: 'outerLoopVar', type: 'string', display: 'Outer Loop Variable' }, + { key: 'learn', type: 'regex', display: 'LearnMore Prompt' }, + { key: 'help', type: 'regex', display: 'LearnMore Response' }, + { key: 'helpReader', type: 'regex', display: 'Video Transcript' }, + { key: 'codeBefore', type: 'logic', display: 'Before Logic' }, + { key: 'codeAfter', type: 'logic', display: 'After Logic' } + ], + fields: [ + { key: 'label', type: 'regex', display: 'Field Label' }, + { key: 'name', type: 'string', display: 'Field Variable' }, + { key: 'value', type: 'regex', display: 'Field Default Value' }, + { key: 'invalidPrompt', type: 'regex', display: 'Field Custom Invalid Prompt' }, + { key: 'sample', type: 'regex', display: 'Field Sample Value' } + ], + buttons: [ + { key: 'label', type: 'regex', display: 'Button Label' }, + { key: 'name', type: 'string', display: 'Button Variable Name' }, + { key: 'value', type: 'regex', display: 'Button Default Value' }, + { key: 'repeatVar', type: 'string', display: 'Button Counting Variable' }, + { key: 'url', type: 'regex', display: 'Button URL' } + ] + } + + beforeEach(() => { + usageTestPage = new window.TPage() + usageTestPage.fields = [new window.TField()] + usageTestPage.buttons = [new window.TButton()] + + const gGuide = new window.TGuide() + window.gGuide = gGuide + window.gGuide.pages = { usageTestPage } + }) + + afterEach(() => { + window.gGuide = null + }) + + it('gathers usage on Page, Field, and Button level property values using variables', function () { + const setTestProps = (targetMap, propsToSet) => { + for (const entry of propsToSet) { + const prop = entry.key + if (entry.type === 'regex') { + targetMap[prop] = 'macro style %%[Number NU]%%' + } else if (entry.type === 'logic') { + targetMap[prop] = 'SET [Number NU] TO 1' + } else { // direct var set + targetMap[prop] = 'Number NU' + } + } + } + setTestProps(usageTestPage, testProps.page) + setTestProps(usageTestPage.fields[0], testProps.fields) + setTestProps(usageTestPage.buttons[0], testProps.buttons) + + const foundMessage = vcGatherUsage('Number NU') + // if found, `display value` will be in foundMessage for each entry + for (const entry of testProps.page) { + const usedInPage = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.fields) { + const usedInField = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.buttons) { + const usedInButton = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + }) + + it('gathers explicit usage on Page, Field, and Button level property values using variables', function () { + const setTestProps = (targetMap, propsToSet) => { + for (const entry of propsToSet) { + const prop = entry.key + if (entry.type === 'regex') { + targetMap[prop] = 'macro style %%[Number NU]%%' + } else if (entry.type === 'logic') { + targetMap[prop] = 'SET [Number123 NU] TO 1' + } else { // direct var set + targetMap[prop] = 'Number foo NU' + } + } + } + + setTestProps(usageTestPage, testProps.page) + setTestProps(usageTestPage.fields[0], testProps.fields) + setTestProps(usageTestPage.buttons[0], testProps.buttons) + + const foundMessage = vcGatherUsage('Number NU') + // if found, `display value` will be in foundMessage for each entry + for (const entry of testProps.page) { + const usedInPage = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInPage, `should find Number NU usage in page.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.fields) { + const usedInField = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInField, `should find Number NU usage in field.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + for (const entry of testProps.buttons) { + const usedInButton = foundMessage.indexOf(entry.display) !== -1 + assert.isTrue(usedInButton, `should find Number NU usage in button.${entry.key} by displaying ${entry.display} in returned foundMessage html`) + } + }) +}) diff --git a/src/variables/editor/vcGatherUsage.js b/src/variables/editor/vcGatherUsage.js index 00f6fa3e..52f7c47f 100644 --- a/src/variables/editor/vcGatherUsage.js +++ b/src/variables/editor/vcGatherUsage.js @@ -27,24 +27,6 @@ const buttonProps = [ ] /* -All three tests greedy if explicitSearch = notTrue -Test 3 currently is explicit (testValue === lowerCaseVarName) -Make test 3 greedy - -Rename three regex consts - --could simply be - parenRegexString `^\\(\\s*${lowerCaseVarName}\\s*\\)$` - percentRegexString `^\\%\\s*${lowerCaseVarName}\\s*\\%$` - bracketRegexString `^\\[\\s*${lowerCaseVarName}\\s*\\]$` - if explicitSearch === true, use search Regex with ^/$ - -*After above is done* -If explicit, find explicit matches -Either if/else or find Explicit function - -const match = findMatches() -if (match) { add to where[] } Type Match = { pageName: @@ -55,7 +37,7 @@ foundCount: */ export const findMacroMatches = (testValue, lowerCaseVarName, explicit) => { - explicit = false; + explicit = true; //For greedy search, Regex looks for lowerCaseVarName followed by any character 0+ times, then white space 0+ times, then the closing half of bracket, paren, percent const parenRegexString = `\\(\\s*${lowerCaseVarName}.*\\s*\\)` @@ -74,7 +56,7 @@ export const findMacroMatches = (testValue, lowerCaseVarName, explicit) => { const macroRegex = (explicit === false) ? new RegExp(regexString, 'ig'): new RegExp(regexStringX, 'ig') const matches = testValue.match(macroRegex) - console.log(matches) + return matches ? matches :[] } @@ -101,26 +83,22 @@ export const findMatches = (searchTarget, usageItem, varName) => { // skip check if not string value to check const prop = usageItem.key if (!searchTarget[prop]) { return } + + let found = [] + let explicit + const testValue = searchTarget[prop].toLowerCase() const lowerCaseVarName = varName.toLowerCase() if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` - const found = findMacroMatches(testValue, lowerCaseVarName) - if (found) { - where.push(usageItem.display) - console.log(where) - } + found = findMacroMatches(testValue, lowerCaseVarName, explicit) } else if (usageItem.type === 'logic') { - const found = findLogicMatches(testValue, lowerCaseVarName) - if (found) { // check for logic usage (no macro syntax, `set someVar to "foo"`) - where.push(usageItem.display) - } + found = findLogicMatches(testValue, lowerCaseVarName) } else { - const found = findLiteralMatches(testValue, lowerCaseVarName) - if (found) { // check for varName itself, `someVar` - where.push(usageItem.display) - } + found = findLiteralMatches(testValue, lowerCaseVarName) } + + return (found.length !== 0) ? usageItem.display : [] } export function vcGatherUsage (varName, explicitSearch) { // 2015-03-27 Search for variable or constant @@ -133,19 +111,25 @@ export function vcGatherUsage (varName, explicitSearch) { // 2015-03-27 Search f for (pageName in window.gGuide.pages) { // Search text, buttons, help, fields and logic for variable name. /** @type TPage */ let where = [] // list where it's on this page - const page = window.gGuide.pages[pageName] let pageMatches, fieldMatches, buttonMatches + + const page = window.gGuide.pages[pageName] // check top level page properties for (const entry of pageProps) { pageMatches = findMatches(page, entry, varName) - // populate where array here! + if(pageMatches && pageMatches.length > 1) { + where = [...where, pageMatches] + } } - + // check all page fields for (const field of page.fields) { for (const entry of fieldProps) { fieldMatches = findMatches(field, entry, varName) + if(fieldMatches && fieldMatches.length > 1) { + where = [...where, fieldMatches] + } } } @@ -153,15 +137,16 @@ export function vcGatherUsage (varName, explicitSearch) { // 2015-03-27 Search f for (const button of page.buttons) { for (const entry of buttonProps) { buttonMatches = findMatches(button, entry, varName) + if(buttonMatches && buttonMatches.length > 1) { + where = [...where, buttonMatches] + } } } - where = [...where, ...pageMatches, ...fieldMatches, ...buttonMatches] if (where.length) { // If we found anything, we'll list the page and its location. count++ html += ('
  • ' + page.name + '
    • ' + '
    • ' + where.join('
    • ') + '
    ') } } - return 'Used in ' + count + ' pages' + '
      ' + html + '
    ' }