From 44072579a1b672b40fa3854d65be2c861b2cfb5d Mon Sep 17 00:00:00 2001 From: Jason Wall Date: Sun, 9 Aug 2020 17:01:05 -0400 Subject: [PATCH] remove the dict from card item, and add type safety --- app/db/src/app/common/card-operations.spec.ts | 64 +++++++++---------- app/db/src/app/common/card-operations.ts | 2 +- .../passage/passage-card.component.ts | 4 +- app/db/src/app/models/card-state.ts | 5 +- app/db/src/app/models/passage-state.ts | 4 +- app/db/src/app/models/strongs-state.ts | 1 + .../app/services/app-state-initial-state.ts | 8 +-- .../app/services/app-state-reducer.spec.ts | 19 +++--- app/db/src/app/services/app-state-reducer.ts | 6 +- app/db/src/app/services/app.service.ts | 43 +++++++------ 10 files changed, 77 insertions(+), 79 deletions(-) diff --git a/app/db/src/app/common/card-operations.spec.ts b/app/db/src/app/common/card-operations.spec.ts index bdcbdcb2..19a20ebd 100644 --- a/app/db/src/app/common/card-operations.spec.ts +++ b/app/db/src/app/common/card-operations.spec.ts @@ -1,12 +1,12 @@ import { mergeCardList } from './card-operations'; import { BibleReference, Overlap } from './bible-reference'; -import { CardType } from '../models/app-state'; +import { CardType, CardItem } from '../models/card-state'; describe('Card Merging', () => { it('Should merge two equal reference cards', () => { - const cardList = [ - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, ]; for (const strat of [Overlap.Equal, Overlap.Subset]) { const merged = mergeCardList(cardList, strat); @@ -16,9 +16,9 @@ describe('Card Merging', () => { }); it('Should merge two equal word cards', () => { - const cardList = [ - { type: CardType.Word, qry: 'sin', data: null, dict: '' }, - { type: CardType.Word, qry: 'sin', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Word, qry: 'sin', data: null }, + { type: CardType.Word, qry: 'sin', data: null }, ]; for (const strat of [Overlap.Equal]) { const merged = mergeCardList(cardList, strat); @@ -28,10 +28,10 @@ describe('Card Merging', () => { }); it('Should merge two equal word cards with one in the middle', () => { - const cardList = [ - { type: CardType.Word, qry: 'sin', data: null, dict: '' }, - { type: CardType.Word, qry: 'love', data: null, dict: '' }, - { type: CardType.Word, qry: 'sin', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Word, qry: 'sin', data: null }, + { type: CardType.Word, qry: 'love', data: null }, + { type: CardType.Word, qry: 'sin', data: null }, ]; for (const strat of [Overlap.Equal]) { const merged = mergeCardList(cardList, strat); @@ -42,9 +42,9 @@ describe('Card Merging', () => { }); it('Should merge two equal strongs cards', () => { - const cardList = [ - { type: CardType.Strongs, qry: 'G123', data: null, dict: '' }, - { type: CardType.Strongs, qry: 'G123', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Strongs, qry: 'G123', data: null }, + { type: CardType.Strongs, qry: 'G123', data: null }, ]; for (const strat of [Overlap.Equal]) { const merged = mergeCardList(cardList, strat); @@ -54,10 +54,10 @@ describe('Card Merging', () => { }); it('Should merge two equal strongs cards with one in the middle', () => { - const cardList = [ - { type: CardType.Strongs, qry: 'G123', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, - { type: CardType.Strongs, qry: 'G123', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Strongs, qry: 'G123', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, + { type: CardType.Strongs, qry: 'G123', data: null }, ]; for (const strat of [Overlap.Equal]) { const merged = mergeCardList(cardList, strat); @@ -68,10 +68,10 @@ describe('Card Merging', () => { }); it('Should merge two equal cards with one in the middle', () => { - const cardList = [ - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:2', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:2', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, ]; for (const strat of [Overlap.Equal, Overlap.Subset]) { const merged = mergeCardList(cardList, strat); @@ -82,9 +82,9 @@ describe('Card Merging', () => { }); it('Should merge two intersecting cards', () => { - const cardList = [ - { type: CardType.Passage, qry: 'Genesis 1:1-2', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Passage, qry: 'Genesis 1:1-2', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, ]; for (const strat of [Overlap.Intersect, Overlap.Subset]) { const merged = mergeCardList(cardList, strat); @@ -94,10 +94,10 @@ describe('Card Merging', () => { }); it('Should merge two intersecting cards with one in the middle', () => { - const cardList = [ - { type: CardType.Passage, qry: 'Genesis 1:1-2', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:4', data: null, dict: '' }, - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Passage, qry: 'Genesis 1:1-2', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:4', data: null }, + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, ]; for (const strat of [Overlap.Intersect, Overlap.Subset]) { const merged = mergeCardList(cardList, strat); @@ -108,9 +108,9 @@ describe('Card Merging', () => { }); it('Should not merge two cards of different card types', () => { - const cardList = [ - { type: CardType.Passage, qry: 'Genesis 1:1', data: null, dict: '' }, - { type: CardType.Word, qry: 'sin', data: null, dict: '' }, + const cardList: CardItem[] = [ + { type: CardType.Passage, qry: 'Genesis 1:1', data: null }, + { type: CardType.Word, qry: 'sin', data: null }, ]; for (const strat of [Overlap.Equal, Overlap.Subset, Overlap.Intersect, Overlap.None]) { const merged = mergeCardList(cardList, strat); diff --git a/app/db/src/app/common/card-operations.ts b/app/db/src/app/common/card-operations.ts index 85cb66ec..891ecdcb 100644 --- a/app/db/src/app/common/card-operations.ts +++ b/app/db/src/app/common/card-operations.ts @@ -1,5 +1,5 @@ import { BibleReference, Overlap } from './bible-reference'; -import { CardItem, CardType } from '../models/app-state'; +import { CardItem, CardType } from '../models/card-state'; export function maybeMergeCards(leftCard: CardItem, rightCard: CardItem, strategy: Overlap): CardItem | null { if (leftCard.type === rightCard.type) { diff --git a/app/db/src/app/components/passage/passage-card.component.ts b/app/db/src/app/components/passage/passage-card.component.ts index 9d6839a8..a8e8a608 100644 --- a/app/db/src/app/components/passage/passage-card.component.ts +++ b/app/db/src/app/components/passage/passage-card.component.ts @@ -5,7 +5,7 @@ import { NoteItem } from 'src/app/models/note-state'; import { CardComponent } from 'src/app/components/card.component'; import { BibleReference, Overlap } from 'src/app/common/bible-reference'; import { AppService } from 'src/app/services/app.service'; -import { Paragraph } from 'src/app/models/passage-state'; +import { Paragraph, BiblePassageResult } from 'src/app/models/passage-state'; @Component({ selector: 'app-passage-card', @@ -121,7 +121,7 @@ export class PassageCardComponent extends CardComponent implements OnInit { } async openStrongs(q: string, asModal = false) { - const dict = this.cardItem.dict === 'H' ? 'heb' : 'grk'; + const dict = (this.cardItem.data as BiblePassageResult).dict; const numbers = q.split(' '); for (const sn of numbers) { if (asModal) { diff --git a/app/db/src/app/models/card-state.ts b/app/db/src/app/models/card-state.ts index 74085bdc..e7052220 100644 --- a/app/db/src/app/models/card-state.ts +++ b/app/db/src/app/models/card-state.ts @@ -3,7 +3,7 @@ import { StrongsResult } from './strongs-state'; import { WordLookupResult } from './words-state'; import { NoteItem } from './note-state'; -export type Data = BiblePassageResult | StrongsResult | WordLookupResult | NoteItem; +export type CardData = BiblePassageResult | StrongsResult | WordLookupResult | NoteItem; export enum CardType { Passage, @@ -15,9 +15,8 @@ export enum CardType { export interface CardItem { readonly qry: string; - readonly data: Data; + readonly data: CardData; readonly type: CardType; - readonly dict: string; } export interface CardIcons { diff --git a/app/db/src/app/models/passage-state.ts b/app/db/src/app/models/passage-state.ts index 6fff07a8..c8b249e3 100644 --- a/app/db/src/app/models/passage-state.ts +++ b/app/db/src/app/models/passage-state.ts @@ -1,6 +1,8 @@ +import { StrongsDictionary } from './strongs-state'; + export interface BiblePassageResult { readonly cs: readonly BibleParagraphPassage[]; - readonly testament: string; + readonly dict: StrongsDictionary; readonly ref: string; } diff --git a/app/db/src/app/models/strongs-state.ts b/app/db/src/app/models/strongs-state.ts index df8170c0..a4892631 100644 --- a/app/db/src/app/models/strongs-state.ts +++ b/app/db/src/app/models/strongs-state.ts @@ -1,6 +1,7 @@ export type StrongsDictionary = 'heb' | 'grk'; export interface StrongsResult { + readonly dict: StrongsDictionary; readonly prefix: string; readonly sn: number; readonly def: StrongsDefinition; diff --git a/app/db/src/app/services/app-state-initial-state.ts b/app/db/src/app/services/app-state-initial-state.ts index ca5771fc..e019c3f1 100644 --- a/app/db/src/app/services/app-state-initial-state.ts +++ b/app/db/src/app/services/app-state-initial-state.ts @@ -3,22 +3,22 @@ import { UUID } from 'angular2-uuid'; import { AppState } from '../models/app-state'; import { PageTitles, PageIcons } from '../constants'; import { Overlap } from '../common/bible-reference'; -import { CardType } from '../models/card-state'; +import { CardType, CardItem } from '../models/card-state'; +import { NoteItem } from '../models/note-state'; export const initialState: AppState = { user: null, cards: [ { qry: 'UUIDGOESHERE', - dict: 'n/a', type: CardType.Note, data: { id: UUID.UUID(), xref: '1 pe 2:16; jn 3:16', title: 'Title Here', content: '# Content Here\nIn Markdown format.', - }, - }, + } as NoteItem, + } as CardItem, ], autocomplete: [], currentSavedPage: null, diff --git a/app/db/src/app/services/app-state-reducer.spec.ts b/app/db/src/app/services/app-state-reducer.spec.ts index 9942619f..58ee2cbe 100644 --- a/app/db/src/app/services/app-state-reducer.spec.ts +++ b/app/db/src/app/services/app-state-reducer.spec.ts @@ -2,8 +2,9 @@ import { TestBed } from '@angular/core/testing'; import { reducer } from './app-state-reducer'; import { AppAction, AppActionFactory } from './app-state-actions'; import { Overlap } from '../common/bible-reference'; -import { CardType, SavedPage } from '../models/app-state'; import { IStorable, Storable } from '../common/storable'; +import { CardType, CardIcons, CardItem } from '../models/card-state'; +import { SavedPage } from '../models/page-state'; describe('AppService Reducer', () => { const preState = { @@ -95,21 +96,20 @@ describe('AppService Reducer', () => { }); it('ADD_CARD', () => { - const card1 = { + const card1: CardItem = { qry: 'H123', data: null, type: CardType.Strongs, - dict: 'H', }; + const action1 = AppActionFactory.newAddCard(card1, null); const testState = reducer(preState, action1); expect(testState.cards[0]).toBe(card1, 'Failed to add first card to empty list'); - const card2 = { + const card2: CardItem = { qry: 'G123', data: null, type: CardType.Strongs, - dict: 'G', }; const action2 = AppActionFactory.newAddCard(card2, null); @@ -117,11 +117,10 @@ describe('AppService Reducer', () => { expect(testState2.cards.length).toBe(2, 'Failed to add second card to list with 1 item'); expect(testState2.cards[1]).toBe(card2); - const card3 = { + const card3: CardItem = { qry: 'G1234', data: null, type: CardType.Strongs, - dict: 'G', }; // append to top, insert next to card @@ -249,14 +248,12 @@ describe('AppService Reducer', () => { qry: 'H123', data: null, type: CardType.Strongs, - dict: 'H', - }, + } as CardItem, { qry: 'G123', data: null, type: CardType.Strongs, - dict: 'G', - }, + } as CardItem, ], // tslint:disable-next-line: quotemark title: "Jason's Page", diff --git a/app/db/src/app/services/app-state-reducer.ts b/app/db/src/app/services/app-state-reducer.ts index 5399e938..11ab7c23 100644 --- a/app/db/src/app/services/app-state-reducer.ts +++ b/app/db/src/app/services/app-state-reducer.ts @@ -233,10 +233,9 @@ export function reducer(state: AppState, action: AppAction): AppState { .map((o) => { return { qry: o.id, - dict: 'n/a', type: CardType.Note, data: o, - }; + } as CardItem; }); let cards = [] as CardItem[]; @@ -267,9 +266,8 @@ export function reducer(state: AppState, action: AppAction): AppState { } case 'GET_NOTE': { const note = state.notes.value.find((o) => o.id === action.noteId); - const card = { + const card: CardItem = { qry: note.id, - dict: 'n/a', type: CardType.Note, data: note, }; diff --git a/app/db/src/app/services/app.service.ts b/app/db/src/app/services/app.service.ts index 83f92e12..ff12c42f 100644 --- a/app/db/src/app/services/app.service.ts +++ b/app/db/src/app/services/app.service.ts @@ -7,13 +7,21 @@ import { StorageMap } from '@ngx-pwa/local-storage'; import { AngularFireDatabase } from '@angular/fire/database'; import { IStorable } from '../common/storable'; import { NoteItem } from '../models/note-state'; -import { Paragraph, BiblePassage, BibleVerse, BibleParagraphPassage, BibleParagraph } from '../models/passage-state'; +import { + Paragraph, + BiblePassage, + BibleVerse, + BibleParagraphPassage, + BibleParagraph, + BiblePassageResult, +} from '../models/passage-state'; import { StrongsDefinition, StrongsCrossReference, RMACCrossReference, RMACDefinition, StrongsDictionary, + StrongsResult, } from '../models/strongs-state'; import { WordToStem, IndexResult, WordLookupResult } from '../models/words-state'; import { HashTable } from '../common/hashtable'; @@ -195,16 +203,16 @@ export class AppService extends createStateService(reducer, initialState) { const result = await this.getStrongsFromApi(strongsNumber, dict); const d = dict === 'grk' ? 'G' : 'H'; - const card = { + const card: CardItem = { qry: `${d}${strongsNumber}`, - dict: d, type: CardType.Strongs, data: result, }; + return card; } - private async getStrongsFromApi(strongsNumber: string, dict: string) { + private async getStrongsFromApi(strongsNumber: string, dict: string): Promise { const sn = parseInt(strongsNumber, 10); const result = { prefix: '', @@ -266,7 +274,7 @@ export class AppService extends createStateService(reducer, initialState) { }); if (referencesForThisStrongsNumber.length === 0) { - return result; + return result as StrongsResult; } result.rmaccode = referencesForThisStrongsNumber[0].r; } catch (err) { @@ -287,7 +295,7 @@ export class AppService extends createStateService(reducer, initialState) { } } } - return result; + return result as StrongsResult; } //#endregion @@ -315,7 +323,6 @@ export class AppService extends createStateService(reducer, initialState) { const result = await this.getPassageFromApi(ref.section); return { qry: ref.toString(), - dict: ref.section.book.bookNumber > 39 ? 'G' : 'H', type: CardType.Passage, data: result, }; @@ -324,11 +331,6 @@ export class AppService extends createStateService(reducer, initialState) { private async getPassageFromApi(section: Section) { try { const chapters = []; // the verses from the chapter. - const result = { - cs: [], - testament: '', - ref: BibleReference.toString(section), - }; if (Number(section.start.chapter) > section.book.lastChapter) { this.dispatchError( @@ -351,7 +353,7 @@ export class AppService extends createStateService(reducer, initialState) { .toPromise(); chapters.push(d); } catch (err) { - this.dispatchError(`Unable to retrieve bible passage ${result.ref}.`); + this.dispatchError(`Unable to retrieve bible passage ${BibleReference.toString(section)}.`); return; } } @@ -396,13 +398,13 @@ export class AppService extends createStateService(reducer, initialState) { } // convert into paragraphs. - result.cs = await this.convertToParagraphPassages(passages, section); + const cs = await this.convertToParagraphPassages(passages, section); - if (section.book.bookNumber >= 40) { - result.testament = 'new'; - } else { - result.testament = 'old'; - } + const result = { + cs, + dict: section.book.bookNumber > 39 ? 'grk' : 'heb', + ref: BibleReference.toString(section), + } as BiblePassageResult; return result; } catch (error) { @@ -479,10 +481,9 @@ export class AppService extends createStateService(reducer, initialState) { const card = { qry, - dict: 'n/a', type: CardType.Word, data: result, - }; + } as CardItem; this.dispatch({ type: 'ADD_CARD',