-
Notifications
You must be signed in to change notification settings - Fork 3
414 reg ex - Updated reg expression searching, added explicit vs non search feature, cleaned up test and main files #432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
LmCastelli
wants to merge
7
commits into
develop
Choose a base branch
from
414-reg-ex
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
60b7184
code separated out for refactor, working on parity
mitch-mitchel d704aec
fix prod build script
mitch-mitchel f6cd941
lint fixes
mitch-mitchel 4634aaf
Got first test to pass, started refactoring vcGatherUsage
LmCastelli 7bd7a21
Adding final changes to Matches trio
LmCastelli 8395792
Cleaned up comments and code, making pull request and checklist fo wh…
LmCastelli b43fba8
Merge branch 'develop' into 414-reg-ex
LmCastelli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <!doctype html> | ||
| <html> | ||
|
|
||
| <title>vcGatherUsage Tests</title> | ||
|
|
||
| <div id="mocha"></div> | ||
| <div id="test-area"></div> | ||
|
|
||
| <script type="text/javascript"> | ||
| window.less = {async: true, fileSync: true}; | ||
| </script> | ||
|
|
||
| <script src="../../../node_modules/steal/steal.js" | ||
| mocha="bdd" | ||
| main="a2jauthor/src/variables/editor/vcGatherUsage-test"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| import 'jquery' | ||
| import { assert } from 'chai' | ||
| import 'steal-mocha' | ||
| 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 | ||
|
|
||
| describe('findMacroMatches', function () { | ||
| it.only('returns matches based on A2J Macro Syntax', function () { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
| 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') | ||
| }) | ||
| }) | ||
|
|
||
| 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, [], "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") | ||
| }) | ||
| }) | ||
|
|
||
| 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`) | ||
| } | ||
| }) | ||
| }) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| import { lowerCase } from "lodash" | ||
|
|
||
| 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' } | ||
| ] | ||
|
|
||
| /* | ||
|
|
||
| Type Match = { | ||
| pageName: | ||
| location: | ||
| foundCount: | ||
| } | ||
|
|
||
| */ | ||
|
|
||
| export const findMacroMatches = (testValue, lowerCaseVarName, explicit) => { | ||
| 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*\\)` | ||
| 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) | ||
|
|
||
| return matches ? matches :[] | ||
| } | ||
|
|
||
| export const findLogicMatches = (testValue, lowerCaseVarName) => { | ||
| const logicRegexString = `${lowerCaseVarName}` | ||
| const logicRegex = new RegExp(logicRegexString, 'ig') | ||
|
|
||
| const matches = testValue.match(logicRegex) | ||
|
|
||
| return matches ? matches :[] | ||
| } | ||
|
|
||
| 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 } | ||
|
|
||
| let found = [] | ||
| let explicit | ||
|
|
||
| const testValue = searchTarget[prop].toLowerCase() | ||
| const lowerCaseVarName = varName.toLowerCase() | ||
|
|
||
| if (usageItem.type === 'regex') { // check for macro matches, `%%someVar%%` | ||
| found = findMacroMatches(testValue, lowerCaseVarName, explicit) | ||
| } else if (usageItem.type === 'logic') { | ||
| found = findLogicMatches(testValue, lowerCaseVarName) | ||
| } else { | ||
| found = findLiteralMatches(testValue, lowerCaseVarName) | ||
| } | ||
|
|
||
| return (found.length !== 0) ? 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 | ||
|
|
||
| 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 | ||
| 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) | ||
| 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] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // check all buttons | ||
| for (const button of page.buttons) { | ||
| for (const entry of buttonProps) { | ||
| buttonMatches = findMatches(button, entry, varName) | ||
| if(buttonMatches && buttonMatches.length > 1) { | ||
| where = [...where, buttonMatches] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (where.length) { // If we found anything, we'll list the page and its location. | ||
| count++ | ||
| html += ('<li>' + page.name + '</li><ul>' + '<li>' + where.join('<li>') + '</ul>') | ||
| } | ||
| } | ||
| return 'Used in ' + count + ' pages' + '<ul>' + html + '</ul>' | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see if
jqueryis required, if not, remove import