Skip to content

Commit

Permalink
Fix Bugs With Option Parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
BellCubeDev committed Dec 1, 2023
1 parent 2718c4d commit f57de50
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 10 deletions.
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ const config: JestConfigWithTsJest = {
injectGlobals: true,
};

export default config;
export default config;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"type": "module",
"name": "fomod",
"description": "A library for creating, parsing, editing, and validating XML-based Fomod installers, widely popularized in the Bethesda modding scene",
"version": "0.1.9",
"version": "0.1.10",
"main": "dist/index.js",
"repository": "https://github.com/BellCubeDev/fomod-js/",
"bugs": {
Expand Down
5 changes: 2 additions & 3 deletions src/definitions/Dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,13 @@ export class FlagDependency extends Dependency {
get desiredValue() { return this.flagInstance.usedValue; }
set desiredValue(value: string|boolean) { this.flagInstance.usedValue = value; }

constructor()
constructor(flagName: string, desiredValue: string)
constructor(flagName?: string, desiredValue?: string)
constructor(flagName: Option<boolean>, desiredValue: boolean)
constructor(flagName: string|Option<boolean> = '', desiredValue: string|boolean = '') {
super();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.flagInstance = new FlagInstance(flagName as any ?? '', desiredValue as any, false);
this.flagInstance = new FlagInstance(flagName as any, desiredValue as any, false);
}

isValid() { return true; }
Expand Down
2 changes: 1 addition & 1 deletion src/definitions/FlagInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class FlagInstance<TIsOption extends boolean, TWrite extends (TIsOption e

document?: Document
) {
if (typeof name === 'string' && typeof usedValue !== 'string') throw new Error(`FlagInstance's 'usedValue' property must be a string when name is a string`);
if (typeof _name === 'string' && typeof usedValue !== 'string') throw new Error(`FlagInstance's 'usedValue' property must be a string when name is a string`);
else if (_name instanceof Option && typeof usedValue !== 'boolean') throw new Error(`FlagInstance's 'usedValue' property must be a boolean when name is an Option`);

this.usedValue = usedValue as TIsOption extends true ? boolean : string;
Expand Down
2 changes: 1 addition & 1 deletion src/definitions/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class Group<TStrict extends boolean = true> extends XmlRepresentation<TSt
const sortingOrder = optionsContainer.getAttribute('order');
if (sortingOrder !== null) group.sortingOrder = sortingOrder;

for (const optionElement of optionsContainer.querySelectorAll('option')) {
for (const optionElement of optionsContainer.querySelectorAll('plugin')) {
const option = Option.parse(optionElement);
if (option !== null) group.options.add(option);
}
Expand Down
8 changes: 5 additions & 3 deletions src/definitions/Option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export class Option<TStrict extends boolean = true> extends XmlRepresentation<TS
public description: string = '',
public image: string|null = null,
public typeDescriptor: TypeDescriptor<TStrict> = new TypeDescriptor(),
public flagsToSet: Set<FlagSetter> = new Set()
public flagsToSet: Set<FlagSetter> = new Set(),
public installsToSet: InstallPattern = new InstallPattern(),
) {
super();
}
Expand Down Expand Up @@ -113,7 +114,7 @@ export class Option<TStrict extends boolean = true> extends XmlRepresentation<TS
if (name === null) return null;

const description = element.getElementsByTagName('description')[0]?.textContent ?? '';
const image = element.getElementsByTagName('image')[0]?.textContent ?? null;
const image = element.getElementsByTagName('image')[0]?.getAttribute('path') ?? null;

const flagsToSet = new Set<FlagSetter>();
const conditionFlags = element.getElementsByTagName('conditionFlags')[0];
Expand Down Expand Up @@ -143,6 +144,7 @@ export class Option<TStrict extends boolean = true> extends XmlRepresentation<TS

const option = new Option<false>(name, description, image, typeDescriptor);
option.flagsToSet = flagsToSet;
option.installsToSet = installsToSet;

const dependencyOnThis = new FlagDependency(option, true);
installsToSet.dependencies?.dependencies.add(dependencyOnThis);
Expand Down Expand Up @@ -448,7 +450,7 @@ export class TypeNameDescriptor<TTagName extends 'type'|'defaultType', TStrict e

// Overwrite to handle the interchangeable `file` and `folder` tags
override assignElement(element: Element) {
ensureXmlDoctype(document);
ensureXmlDoctype(element.ownerDocument);

// @ts-ignore: The logic is fine but TypeScript can't figure it out
if (!this.tagNameIsReadonly && (element.tagName === 'type' || element.tagName === 'defaultType')) this.tagName = element.tagName;
Expand Down
22 changes: 22 additions & 0 deletions tests/definitions/Option.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Option, OptionType, TypeDescriptor, TypeNameDescriptor } from "../../src";
import { parseTag } from "../testUtils";

describe('Basic Option', () => {
const obj = new Option('apple', 'banana', 'someImage.png');
Expand All @@ -19,3 +20,24 @@ describe('Option With Type', () => {
test('Type is Correct', () => expect(obj.typeDescriptor.defaultTypeNameDescriptor.targetType).toBe(OptionType.Required));
test('Is Valid', () => expect(obj.isValid()).toBe(true));
});

describe('Parsing Option From Element #1', () => {
const doc = parseTag`<plugin name="lungs">
<description />
<image path="12345" />
<files />
<typeDescriptor>
<type name="CouldBeUsable" />
</typeDescriptor>
</plugin>`;

const obj = Option.parse(doc);

test('We Got An Option', () => expect(obj).toBeInstanceOf(Option));
test('Name Is Correct', () => expect(obj?.name).toBe('lungs'));
test('Description Is Correct', () => expect(obj?.description).toBe(''));
test('Image Is Correct', () => expect(obj?.image).toBe('12345'));
test('Default Type is Correct', () => expect(obj?.typeDescriptor.defaultTypeNameDescriptor.targetType).toBe(OptionType.CouldBeUsable));
test('Has No Installs', () => expect(obj?.installsToSet.filesWrapper.installs.size).toBe(0));
test('Is Valid', () => expect(obj?.isValid()).toBe(true));
});

0 comments on commit f57de50

Please sign in to comment.