Skip to content
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

Feature/test parse config rebase/679 #779

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ jobs:
npm --version
npm i

- name: Add config
- name: Add minimal config
run: |
echo "export default {};" > src/lib/data/config.js
echo "export const firebaseConfig = null;" > src/lib/data/firebase-config.js
echo "export const catalog = [];" > src/lib/data/catalog.js
echo "export default {}" > src/lib/data/contents.js

- name: Add catalog
run: echo "export const catalog = [];" > src/lib/data/catalog.js
- name: Run minimal build
run: |
npx vite build

- name: TypeScript/Svelte Check
run: |
Expand Down
22 changes: 19 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,19 @@ jobs:
for PROGRAM in sab dab; do
echo "Processing projects for $PROGRAM"
mkdir -p "$HOME/projects/$PROGRAM"
PROJECTS=$(jq -r ".${PROGRAM}.projects[]" "test_data/projects/index.json")
for PROJECT_ZIP in $PROJECTS; do

# Get all projects as JSON array
PROJECTS_JSON=$(jq -r ".${PROGRAM}.projects" "test_data/projects/index.json")

# Get number of projects
NUM_PROJECTS=$(echo "$PROJECTS_JSON" | jq '. | length')

# Iterate through projects using index
for ((i=0; i<$NUM_PROJECTS; i++)); do
# Get project path and test directories
PROJECT_ZIP=$(echo "$PROJECTS_JSON" | jq -r ".[$i].path")
TEST_DIRS=$(echo "$PROJECTS_JSON" | jq -r ".[$i].tests[]")

PROJECT_NAME=$(basename "$PROJECT_ZIP" .zip)
echo "Project: $PROJECT_NAME"
PROJECT_DIR="$HOME/projects/${PROGRAM}/$PROJECT_NAME"
Expand All @@ -60,6 +71,11 @@ jobs:
popd > /dev/null
npm run build
npm run convert
npm run test

# Run tests for each specified directory
for TEST_DIR in $TEST_DIRS; do
echo "Running tests in directory: $TEST_DIR"
npm run test "$TEST_DIR"
done
done
done
58 changes: 29 additions & 29 deletions convert/convertConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { existsSync, PathLike, readdirSync, readFileSync } from 'fs';
import { existsSync, readdirSync, readFileSync, type PathLike } from 'fs';
import path, { basename, extname } from 'path';
import type {
AppConfig,
Expand All @@ -13,7 +13,7 @@ import type {
import jsdom from 'jsdom';
import { convertMarkdownsToHTML } from './convertMarkdown';
import { splitVersion } from './stringUtils';
import { Task, TaskOutput } from './Task';
import { Task, type TaskOutput } from './Task';

const fontFamilies: string[] = [];

Expand All @@ -26,13 +26,13 @@ function decodeFromXml(input: string): string {
.replace('&amp;', '&');
}

function parseConfigValue(value: any) {
export function parseConfigValue(value: any) {
if (!value.includes(':') && !isNaN(parseInt(value))) value = parseInt(value);
else if (['true', 'false'].includes(value)) value = value === 'true' ? true : false;
// else {} // " " split array, string, enum or time
return value;
}
function parseAdditionalNames(namesTag: Element, verbose: number) {
export function parseAdditionalNames(namesTag: Element, verbose: number) {
const additionalNames = [];
const nameTags = namesTag?.getElementsByTagName('name');
for (const tag of nameTags) {
Expand All @@ -46,7 +46,7 @@ function parseAdditionalNames(namesTag: Element, verbose: number) {
}
return additionalNames;
}
function parseStyles(stylesTag: Element, verbose: number) {
export function parseStyles(stylesTag: Element, verbose: number) {
const styles = [];
const styleTags = stylesTag?.getElementsByTagName('style');
if (!styleTags) throw new Error('Styles tag not found in xml');
Expand Down Expand Up @@ -77,7 +77,7 @@ function parseStyles(stylesTag: Element, verbose: number) {

return styles;
}
function parseStylesInfo(stylesInfoTag: Element, verbose: number): StyleConfig {
export function parseStylesInfo(stylesInfoTag: Element, verbose: number): StyleConfig {
return {
font: stylesInfoTag.getElementsByTagName('text-font')[0].attributes.getNamedItem('family')!
.value,
Expand All @@ -101,7 +101,7 @@ function parseStylesInfo(stylesInfoTag: Element, verbose: number): StyleConfig {
};
}

function parseTrait(tag: Element, name: string): string {
export function parseTrait(tag: Element, name: string): string {
const traitTags = tag.getElementsByTagName('trait');
for (const tag of traitTags) {
if (tag.attributes.getNamedItem('name')!.value === name) {
Expand Down Expand Up @@ -161,7 +161,7 @@ function changeAndroidToRem(propValue: string) {
}
}

function convertFooter(markdown: string | undefined, appdef: Document): string | undefined {
export function convertFooter(markdown: string | undefined, appdef: Document): string | undefined {
const footer = markdown?.length ? convertMarkdownsToHTML(removeCData(markdown)) : undefined;
const appName = appdef.getElementsByTagName('app-name')[0].innerHTML;
const versionName = appdef.getElementsByTagName('version')[0].getAttribute('name');
Expand All @@ -176,7 +176,7 @@ function convertFooter(markdown: string | undefined, appdef: Document): string |
?.replace(/%program-version%/g, programVersion ?? '');
}

function convertCollectionFooter(collectionTag: Element, document: Document) {
export function convertCollectionFooter(collectionTag: Element, document: Document) {
const footerTags = Array.from(collectionTag.children).filter(
(child) => child.tagName === 'footer'
);
Expand Down Expand Up @@ -360,7 +360,7 @@ function convertConfig(dataDir: string, verbose: number) {
return filterFeaturesNotReady(data);
}

function parseFeatures(document: Document, verbose: number) {
export function parseFeatures(document: Document, verbose: number) {
const mainFeatureTags = document
.querySelector('features[type=main]')
?.getElementsByTagName('e');
Expand All @@ -384,7 +384,7 @@ function parseFeatures(document: Document, verbose: number) {
return mainFeatures;
}

function parseFonts(document: Document, verbose: number) {
export function parseFonts(document: Document, verbose: number) {
const fontTags = document.getElementsByTagName('fonts')[0].getElementsByTagName('font');
const fonts = [];

Expand All @@ -407,7 +407,7 @@ function parseFonts(document: Document, verbose: number) {
return fonts;
}

function parseColorThemes(document: Document, verbose: number) {
export function parseColorThemes(document: Document, verbose: number) {
const colorThemeTags = document
.getElementsByTagName('color-themes')[0]
.getElementsByTagName('color-theme');
Expand Down Expand Up @@ -468,7 +468,7 @@ function parseColorThemes(document: Document, verbose: number) {
return { themes, defaultTheme };
}

function parseTraits(document: Document, dataDir: string, verbose: number) {
export function parseTraits(document: Document, dataDir: string, verbose: number) {
const traitTags = document.getElementsByTagName('traits')[0]?.getElementsByTagName('trait');
const traits: { [key: string]: any } = {};

Expand All @@ -488,7 +488,7 @@ function parseTraits(document: Document, dataDir: string, verbose: number) {
return traits;
}

function parseBookCollections(document: Document, verbose: number) {
export function parseBookCollections(document: Document, verbose: number) {
const booksTags = document.getElementsByTagName('books');
const bookCollections = [];

Expand Down Expand Up @@ -701,7 +701,7 @@ function parseBookCollections(document: Document, verbose: number) {
return bookCollections;
}

function parseInterfaceLanguages(document: Document, data: AppConfig, verbose: number) {
export function parseInterfaceLanguages(document: Document, data: AppConfig, verbose: number) {
const interfaceLanguagesTag = document.getElementsByTagName('interface-languages')[0];
const useSystemLanguage = parseTrait(interfaceLanguagesTag, 'use-system-language') === 'true';
const interfaceLanguages: {
Expand Down Expand Up @@ -729,7 +729,7 @@ function parseInterfaceLanguages(document: Document, data: AppConfig, verbose: n
return interfaceLanguages;
}

function parseWritingSystem(element: Element, verbose: number): WritingSystemConfig {
export function parseWritingSystem(element: Element, verbose: number): WritingSystemConfig {
const type = element.attributes.getNamedItem('type')!.value;
const fontFamily = element.getElementsByTagName('font-family')[0].innerHTML;
const textDirection = parseTrait(element, 'text-direction');
Expand All @@ -747,7 +747,7 @@ function parseWritingSystem(element: Element, verbose: number): WritingSystemCon

return writingSystem;
}
function parseDictionaryWritingSystem(
export function parseDictionaryWritingSystem(
element: Element,
verbose: number
): DictionaryWritingSystemConfig {
Expand Down Expand Up @@ -799,7 +799,7 @@ function parseDictionaryWritingSystem(
};
}

function parseMenuLocalizations(document: Document, verbose: number) {
export function parseMenuLocalizations(document: Document, verbose: number) {
const translationMappingsTags = document.getElementsByTagName('translation-mappings');
let translationMappings: {
defaultLang: string;
Expand Down Expand Up @@ -832,7 +832,7 @@ function parseMenuLocalizations(document: Document, verbose: number) {
return translationMappings;
}

function parseKeys(document: Document, verbose: number) {
export function parseKeys(document: Document, verbose: number) {
if (document.getElementsByTagName('keys').length > 0) {
const keys = Array.from(
document.getElementsByTagName('keys')[0].getElementsByTagName('key')
Expand All @@ -844,7 +844,7 @@ function parseKeys(document: Document, verbose: number) {
return [];
}

function parseAnalytics(document: Document, verbose: number) {
export function parseAnalytics(document: Document, verbose: number) {
const analyticsElements = document.getElementsByTagName('analytics');

const analytics: { enabled: boolean; providers: any[] } = {
Expand Down Expand Up @@ -893,7 +893,7 @@ function parseAnalytics(document: Document, verbose: number) {
return analytics;
}

function parseFirebase(document: Document, verbose: number) {
export function parseFirebase(document: Document, verbose: number) {
const firebaseElements = document.getElementsByTagName('firebase');
let firebase: { features: { [key: string]: any } } = { features: {} };

Expand All @@ -920,7 +920,7 @@ function parseFirebase(document: Document, verbose: number) {
return firebase;
}

function parseAudioSources(document: Document, verbose: number) {
export function parseAudioSources(document: Document, verbose: number) {
const audioSources = document
.getElementsByTagName('audio-sources')[0]
?.getElementsByTagName('audio-source');
Expand Down Expand Up @@ -987,7 +987,7 @@ function parseAudioSources(document: Document, verbose: number) {
return { sources, files };
}

function parseVideos(document: Document, verbose: number) {
export function parseVideos(document: Document, verbose: number) {
const videoTags = document.getElementsByTagName('videos')[0]?.getElementsByTagName('video');
const videos: any[] = [];
if (videoTags?.length > 0) {
Expand Down Expand Up @@ -1030,7 +1030,7 @@ function parseVideos(document: Document, verbose: number) {
return videos;
}

function parseIllustrations(document: Document, verbose: number) {
export function parseIllustrations(document: Document, verbose: number) {
const imagesTags = document.getElementsByTagName('images');
const illustrations: any[] = [];
if (imagesTags?.length > 0) {
Expand Down Expand Up @@ -1067,7 +1067,7 @@ function parseIllustrations(document: Document, verbose: number) {
return illustrations;
}

function parseLayouts(document: Document, bookCollections: any, verbose: number) {
export function parseLayouts(document: Document, bookCollections: any, verbose: number) {
const layoutRoot = document.getElementsByTagName('layouts')[0];
let defaultLayout = layoutRoot?.getAttribute('default');
const layouts = [];
Expand Down Expand Up @@ -1109,7 +1109,7 @@ function parseLayouts(document: Document, bookCollections: any, verbose: number)
return { layouts, defaultLayout };
}

function parseBackgroundImages(document: Document, verbose: number) {
export function parseBackgroundImages(document: Document, verbose: number) {
const backgroundImageTags = document
.querySelector('images[type=background]')
?.getElementsByTagName('image');
Expand All @@ -1127,7 +1127,7 @@ function parseBackgroundImages(document: Document, verbose: number) {
return backgroundImages;
}

function parseWatermarkImages(document: Document, verbose: number) {
export function parseWatermarkImages(document: Document, verbose: number) {
const watermarkImageTags = document
.querySelector('images[type=watermark]')
?.getElementsByTagName('image');
Expand All @@ -1145,7 +1145,7 @@ function parseWatermarkImages(document: Document, verbose: number) {
return watermarkImages;
}

function parseMenuItems(document: Document, type: string, verbose: number) {
export function parseMenuItems(document: Document, type: string, verbose: number) {
const firstMenuItemsByType = document.querySelector(`menu-items[type="${type}"]`);
const menuItemTags = firstMenuItemsByType?.getElementsByTagName('menu-item');
const menuItems = [];
Expand Down Expand Up @@ -1208,7 +1208,7 @@ function parseMenuItems(document: Document, type: string, verbose: number) {
return menuItems;
}

function parsePlans(document: Document, verbose: number) {
export function parsePlans(document: Document, verbose: number) {
const features: { [key: string]: string } = {};
const plans: {
id: string;
Expand Down
52 changes: 52 additions & 0 deletions convert/tests/dab/convertConfigDAB.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { readFileSync } from 'fs';
import path from 'path';
import type { DictionaryConfig, DictionaryWritingSystemConfig } from '$config';
import jsdom from 'jsdom';
import { expect, test } from 'vitest';
import { parseDictionaryWritingSystem, parseFeatures } from '../../convertConfig';

const dataDir = './data/';
const dom = new jsdom.JSDOM(readFileSync(path.join(dataDir, 'appdef.xml')).toString(), {
contentType: 'text/xml'
});
const { document } = dom.window;
const appDefinition = document.getElementsByTagName('app-definition')[0];
const programType = appDefinition.attributes.getNamedItem('type')!.value;

if (programType === 'SAB') {
test('Dummy test for DAB testing for SAB file', () => {
expect(0).toEqual(0);
});
} else if (programType === 'DAB') {
test('convertConfig: parse dictionary writing systems', () => {
const result: { [key: string]: DictionaryWritingSystemConfig } = {};
const writingSystemsTag = document.getElementsByTagName('writing-systems')[0];
const writingSystemTags = writingSystemsTag.getElementsByTagName('writing-system');
for (const tag of writingSystemTags) {
const writingSystem = parseDictionaryWritingSystem(tag, 1);
const code: string = tag.attributes.getNamedItem('code')!.value;
result[code] = writingSystem;
}

for (const lang in result.writingSystems) {
expect(result[lang].fontFamily).not.toEqual('');
expect(result[lang].textDirection).toSatisfy((r) => r === 'LTR' || r === 'RTL');
expect(Object.keys(result[lang].displayNames)).not.toHaveLength(0);

// TRAITS NOT IN SAB
expect(Object.keys(result[lang].sortMethod)).toHaveLength(2);
expect(result[lang]).toHaveProperty('alphabet');
expect(result[lang].alphabet!.length).toBeGreaterThan(0);
expect(result[lang]).toHaveProperty('inputButtons');
expect(result[lang].inputButtons!.length).toBeGreaterThan(0);
expect(Object.keys(result[lang])).not.toHaveLength(0);
}
});

test('convertConfig: parse features', () => {
const result = parseFeatures(document, 1);
expect(Object.keys(result)).not.toHaveLength(0);
});
} else {
throw new Error(`Unsupported program type parsed: ${programType}`);
}
Loading