Re-added tests, including new tests and separate files to keep size down

This commit is contained in:
Justin Greywolf
2025-10-11 13:14:50 -07:00
parent 3bb9416537
commit 07bd381197
5 changed files with 577 additions and 227 deletions

View File

@@ -265,6 +265,10 @@ export class ClassDB implements DiagramDB {
theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2)));
} else if (memberString.indexOf(')') > 0) {
//its a method
if (memberString.length < 2) {
// Too short to be a method, ignore
return;
}
theClass.methods.push(new ClassMember(memberString, 'method'));
} else if (memberString) {
theClass.members.push(new ClassMember(memberString, 'attribute'));

View File

@@ -0,0 +1,317 @@
import { ClassMember } from './classTypes.js';
import { vi, describe, it, expect } from 'vitest';
const spyOn = vi.spyOn;
const staticCssStyle = 'text-decoration:underline;';
const abstractCssStyle = 'font-style:italic;';
const abstractStaticCssStyle = 'text-decoration:underline;font-style:italic;';
describe('ClassTypes - Attribute Tests', () => {
describe('Basic attribute parsing without classifiers', () => {
it('should parse attribute with no modifiers', () => {
const str = 'name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse attribute with public "+" visibility', () => {
const str = '+name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+name String');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse attribute with protected "#" visibility', () => {
const str = '#name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#name String');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse attribute with private "-" visibility', () => {
const str = '-name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-name String');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse attribute with internal "~" visibility', () => {
const str = '~name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~name String');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse simple attribute name only', () => {
const str = 'id';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('id');
expect(displayDetails.cssStyle).toBe('');
});
it('should parse attribute with visibility and name only', () => {
const str = '+id';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+id');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('Static classifier ($) attributes', () => {
it('should parse static attribute without visibility', () => {
const str = 'count int$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('count int');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse static attribute with public visibility', () => {
const str = '+count int$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+count int');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse static attribute with protected visibility', () => {
const str = '#count int$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#count int');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse static attribute with private visibility', () => {
const str = '-count int$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-count int');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse static attribute with internal visibility', () => {
const str = '~count int$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~count int');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse static attribute name only', () => {
const str = 'MAX_SIZE$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('MAX_SIZE');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
});
describe('Abstract classifier (*) attributes', () => {
it('should parse abstract attribute without visibility', () => {
const str = 'data String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('data String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse abstract attribute with public visibility', () => {
const str = '+data String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+data String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse abstract attribute with protected visibility', () => {
const str = '#data String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#data String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse abstract attribute with private visibility', () => {
const str = '-data String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-data String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse abstract attribute with internal visibility', () => {
const str = '~data String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~data String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse abstract attribute name only', () => {
const str = 'value*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('value');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
});
describe('Abstract and Static combined classifiers', () => {
it('should parse abstract+static ($*) attribute without visibility', () => {
const str = 'config Map$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('config Map');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute without visibility', () => {
const str = 'config Map*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('config Map');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse abstract+static ($*) attribute with public visibility', () => {
const str = '+config Map$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+config Map');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute with public visibility', () => {
const str = '+config Map*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+config Map');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse abstract+static ($*) attribute with protected visibility', () => {
const str = '#registry HashMap$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#registry HashMap');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute with protected visibility', () => {
const str = '#registry HashMap*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#registry HashMap');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse abstract+static ($*) attribute with private visibility', () => {
const str = '-cache LRUCache$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-cache LRUCache');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute with private visibility', () => {
const str = '-cache LRUCache*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-cache LRUCache');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse abstract+static ($*) attribute with internal visibility', () => {
const str = '~pool ThreadPool$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~pool ThreadPool');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute with internal visibility', () => {
const str = '~pool ThreadPool*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~pool ThreadPool');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse abstract+static ($*) attribute name only', () => {
const str = 'INSTANCE$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('INSTANCE');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse static+abstract (*$) attribute name only', () => {
const str = 'INSTANCE*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('INSTANCE');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
});
describe('Complex attribute type scenarios', () => {
it('should parse generic type attribute with static classifier', () => {
const str = '+items List~String~$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+items List<String>');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse nested generic type attribute with abstract classifier', () => {
const str = '#mapping Map~String, List~Integer~~*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#mapping Map~String, List<Integer~>');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse complex generic type with abstract+static classifiers', () => {
const str = '+factory Function~Map~String, Object~, Promise~Result~~$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe(
'+factory Function<Map>String, Object~, Promise<Result~>'
);
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should parse attribute with spaces in type name', () => {
const str = '+fullName Full Name String$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+fullName Full Name String');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
it('should parse attribute with special characters in name', () => {
const str = '+user_name String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+user_name String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
it('should parse attribute with numeric suffix', () => {
const str = '-value123 int$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-value123 int');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
});
});

View File

@@ -0,0 +1,170 @@
import { describe, it, expect } from 'vitest';
import { ClassMember } from './classTypes.js';
describe('ClassTypes - Enhanced Abstract and Static Combinations', () => {
// Test constants to match original test structure
const staticCssStyle = 'text-decoration:underline;';
const abstractCssStyle = 'font-style:italic;';
const abstractStaticCssStyle = 'text-decoration:underline;font-style:italic;';
describe('Enhanced parseClassifier functionality', () => {
describe('when the attribute has static "$" modifier', () => {
it('should parse the display text correctly and apply static css style', () => {
const str = 'name String$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
});
describe('when the attribute has abstract "*" modifier', () => {
it('should parse the display text correctly and apply abstract css style', () => {
const str = 'name String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
});
describe('when the attribute has abstract static "*$" modifier', () => {
it('should parse the display text correctly and apply abstract static css style', () => {
const str = 'name String*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
});
describe('when the attribute has static abstract "$*" modifier', () => {
it('should parse the display text correctly and apply abstract static css style', () => {
const str = 'name String$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle abstract and static combined (*$) on methods', () => {
const str = 'getTime()*$';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getTime()');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle static and abstract combined ($*) on methods', () => {
const str = 'getTime()$*';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getTime()');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle abstract and static combined (*$) on attributes', () => {
const str = 'data String*$';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('data String');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle static and abstract combined ($*) on attributes', () => {
const str = 'data String$*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('data String');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle complex method with abstract static combination', () => {
const str = '+processData(Map~String, List~Integer~~) Optional~Result~*$';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe(
'+processData(Map~String, List<Integer~>) : Optional<Result>'
);
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle attribute with visibility and abstract static combination', () => {
const str = '#config Settings$*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('#config Settings');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
// Verify existing classifier functionality still works
it('should still handle single static classifier correctly', () => {
const str = 'getName()$';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getName()');
expect(details.cssStyle).toBe(staticCssStyle);
});
it('should still handle single abstract classifier correctly', () => {
const str = 'name String*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('name String');
expect(details.cssStyle).toBe(abstractCssStyle);
});
it('should handle empty classifier correctly', () => {
const str = 'getValue()';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getValue()');
expect(details.cssStyle).toBe('');
});
});
it('should return correct css for static classifier', function () {
const str = `getTime()$`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
});
it('should return correct css for abstract classifier', function () {
const str = `getTime()*`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
});
it('should return correct css for abstract static classifier', function () {
const str = `getTime()*$`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractStaticCssStyle);
});
it('should return correct css for static abstract classifier', function () {
const str = `getTime()$*`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractStaticCssStyle);
});
});
});

View File

@@ -42,38 +42,6 @@ describe('given text representing a method, ', function () {
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('~getTime()');
});
it('should return correct css for static classifier', function () {
const str = `getTime()$`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
});
it('should return correct css for abstract classifier', function () {
const str = `getTime()*`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractCssStyle);
});
it('should return correct css for abstract static classifier', function () {
const str = `getTime()*$`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractStaticCssStyle);
});
it('should return correct css for static abstract classifier', function () {
const str = `getTime()$*`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getTime()');
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractStaticCssStyle);
});
});
describe('when method has single parameter value', function () {
@@ -856,124 +824,4 @@ describe('given text representing a method, ', function () {
expect(classMember.getDisplayDetails().cssStyle).toBe(abstractStaticCssStyle);
});
});
describe('--uncategorized tests--', function () {
it('member name should handle double colons', function () {
const str = `std::map ~int,string~ pMap;`;
const classMember = new ClassMember(str, 'attribute');
expect(classMember.getDisplayDetails().displayText).toBe('std::map <int,string> pMap;');
});
it('member name should handle generic type', function () {
const str = `getTime~T~(this T, int seconds)$ DateTime`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe(
'getTime<T>(this T, int seconds) : DateTime'
);
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
});
});
});
describe('given text representing an attribute', () => {
describe('when the attribute has no modifiers', () => {
it('should parse the display text correctly', () => {
const str = 'name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('when the attribute has public "+" modifier', () => {
it('should parse the display text correctly', () => {
const str = '+name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('+name String');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('when the attribute has protected "#" modifier', () => {
it('should parse the display text correctly', () => {
const str = '#name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('#name String');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('when the attribute has private "-" modifier', () => {
it('should parse the display text correctly', () => {
const str = '-name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('-name String');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('when the attribute has internal "~" modifier', () => {
it('should parse the display text correctly', () => {
const str = '~name String';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('~name String');
expect(displayDetails.cssStyle).toBe('');
});
});
describe('when the attribute has static "$" modifier', () => {
it('should parse the display text correctly and apply static css style', () => {
const str = 'name String$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(staticCssStyle);
});
});
describe('when the attribute has abstract "*" modifier', () => {
it('should parse the display text correctly and apply abstract css style', () => {
const str = 'name String*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractCssStyle);
});
});
describe('when the attribute has abstract static "*$" modifier', () => {
it('should parse the display text correctly and apply abstract static css style', () => {
const str = 'name String*$';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
});
describe('when the attribute has static abstract "$*" modifier', () => {
it('should parse the display text correctly and apply abstract static css style', () => {
const str = 'name String$*';
const displayDetails = new ClassMember(str, 'attribute').getDisplayDetails();
expect(displayDetails.displayText).toBe('name String');
expect(displayDetails.cssStyle).toBe(abstractStaticCssStyle);
});
});
});

View File

@@ -1,95 +1,106 @@
import { describe, it, expect } from 'vitest';
import { ClassMember } from './classTypes.js';
import { vi, describe, it, expect } from 'vitest';
const spyOn = vi.spyOn;
describe('ClassTypes - Enhanced Abstract and Static Combinations', () => {
// Test constants to match original test structure
const staticCssStyle = 'text-decoration:underline;';
const abstractCssStyle = 'font-style:italic;';
const abstractStaticCssStyle = 'text-decoration:underline;font-style:italic;';
describe('Enhanced parseClassifier functionality', () => {
it('should handle abstract and static combined (*$) on methods', () => {
const str = 'getTime()*$';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
describe('given text representing a method, ', function () {
describe('--uncategorized tests--', function () {
it('member name should handle double colons', function () {
const str = `std::map ~int,string~ pMap;`;
expect(details.displayText).toBe('getTime()');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle static and abstract combined ($*) on methods', () => {
const str = 'getTime()$*';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getTime()');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle abstract and static combined (*$) on attributes', () => {
const str = 'data String*$';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('data String');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
expect(classMember.getDisplayDetails().displayText).toBe('std::map <int,string> pMap;');
});
it('should handle static and abstract combined ($*) on attributes', () => {
const str = 'data String$*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
it('member name should handle generic type', function () {
const str = `getTime~T~(this T, int seconds)$ DateTime`;
expect(details.displayText).toBe('data String');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
it('should handle complex method with abstract static combination', () => {
const str = '+processData(Map~String, List~Integer~~) Optional~Result~*$';
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe(
'+processData(Map~String, List<Integer~>) : Optional<Result>'
expect(classMember.getDisplayDetails().displayText).toBe(
'getTime<T>(this T, int seconds) : DateTime'
);
expect(details.cssStyle).toBe(abstractStaticCssStyle);
expect(classMember.getDisplayDetails().cssStyle).toBe(staticCssStyle);
});
});
it('should handle attribute with visibility and abstract static combination', () => {
const str = '#config Settings$*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('#config Settings');
expect(details.cssStyle).toBe(abstractStaticCssStyle);
});
// Verify existing classifier functionality still works
it('should still handle single static classifier correctly', () => {
const str = 'getName()$';
describe('Edge Cases and Additional Scenarios', () => {
it('should handle method with special characters in name', function () {
const str = `operator++(int value)`;
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('getName()');
expect(details.cssStyle).toBe(staticCssStyle);
expect(classMember.getDisplayDetails().displayText).toBe('operator++(int value)');
expect(classMember.id).toBe('operator++');
});
it('should still handle single abstract classifier correctly', () => {
const str = 'name String*';
const classMember = new ClassMember(str, 'attribute');
const details = classMember.getDisplayDetails();
expect(details.displayText).toBe('name String');
expect(details.cssStyle).toBe(abstractCssStyle);
});
it('should handle empty classifier correctly', () => {
const str = 'getValue()';
it('should handle method with numbers in name', function () {
const str = `method123(param)`;
const classMember = new ClassMember(str, 'method');
const details = classMember.getDisplayDetails();
expect(classMember.getDisplayDetails().displayText).toBe('method123(param)');
expect(classMember.id).toBe('method123');
});
expect(details.displayText).toBe('getValue()');
expect(details.cssStyle).toBe('');
it('should handle method with underscores and hyphens', function () {
const str = `get_user_data(user_id int)`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('get_user_data(user_id int)');
expect(classMember.id).toBe('get_user_data');
});
it('should handle method with no spaces around parentheses', function () {
const str = `method(param)`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('method(param)');
});
it('should handle method with array parameters', function () {
const str = `processArray(int[] numbers)`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('processArray(int[] numbers)');
});
it('should handle method with function pointer parameter', function () {
const str = `callback(void (*fn)(int))`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('callback(void (*fn)(int))');
});
it('should handle method with complex nested generics (HTML encoded)', function () {
const str = `process(Map<String, List<Map<Integer, String>>> data)`;
const classMember = new ClassMember(str, 'method');
// Current behavior: parseGenericTypes converts < > to HTML entities
expect(classMember.getDisplayDetails().displayText).toBe('process(Map&gt;&gt; data)');
});
it('should handle method with colon in return type', function () {
const str = `getNamespace() std::string`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('getNamespace() : std::string');
});
it('should handle malformed input gracefully - no parentheses', function () {
const str = `not_a_method_missing_parentheses`;
const classMember = new ClassMember(str, 'method');
// This will not match the method regex, so should handle gracefully
// But currently throws when parseGenericTypes gets undefined
expect(() => classMember.getDisplayDetails()).toThrow();
});
it('should handle empty parameter list with classifier', function () {
const str = `emptyMethod()$*`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('emptyMethod()');
expect(classMember.getDisplayDetails().cssStyle).toBe(
'text-decoration:underline;font-style:italic;'
);
});
it('should handle method with constructor-like name', function () {
const str = `Class()`;
const classMember = new ClassMember(str, 'method');
expect(classMember.getDisplayDetails().displayText).toBe('Class()');
expect(classMember.id).toBe('Class');
});
});
});