This repository was archived by the owner on Sep 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Add caching client v3 #43
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ import { default as company } from '~/__mocks__/fixtures/v3/company.js' | |
| import { default as daily } from '~/__mocks__/fixtures/v3/daily.js' | ||
| import { default as quarter } from '~/__mocks__/fixtures/v3/quarter.js' | ||
|
|
||
| export class BuffettCodeApiClientV2 { | ||
| export class BuffettCodeApiClientV3 { | ||
|
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. これは今までの class 名がよろしくないのね |
||
| public mockCompany = jest.fn() | ||
| public mockDaily = jest.fn() | ||
| public mockQuarter = jest.fn() | ||
|
|
@@ -13,23 +13,28 @@ export class BuffettCodeApiClientV2 { | |
| this.mockQuarter.mockReturnValue(quarter) | ||
| } | ||
|
|
||
| company(ticker): object | null { | ||
| const company = this.mockCompany()[ticker] | ||
| return company ? company[0] : null | ||
| company(): object | null { | ||
| const company = this.mockCompany()['data'] | ||
| return company ? company : null | ||
| } | ||
|
|
||
| quarter(ticker): object | null { | ||
| const quarter = this.mockQuarter()[ticker] | ||
| return quarter ? quarter[0] : null | ||
| quarter(): object | null { | ||
| const quarter = this.mockQuarter()['data'] | ||
| return quarter ? quarter : null | ||
| } | ||
|
|
||
| daily(ticker): object | null { | ||
| const daily = this.mockDaily()[ticker] | ||
| return daily ? daily[0] : null | ||
| daily(): object | null { | ||
| const daily = this.mockDaily()['data'] | ||
| return daily ? daily : null | ||
| } | ||
|
|
||
| ondemandQuarter(ticker): object | null { | ||
| const quarter = this.mockQuarter()[ticker] | ||
| return quarter ? quarter[0] : null | ||
| ondemandDaily(): object | null { | ||
| const daily = this.mockDaily()['data'] | ||
| return daily ? daily : null | ||
| } | ||
|
|
||
| ondemandQuarter(): object | null { | ||
| const quarter = this.mockQuarter()['data'] | ||
| return quarter ? quarter : null | ||
| } | ||
| } | ||
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,23 @@ | ||
| import { DateParam } from '~/fiscal-periods/date-param' | ||
|
|
||
| export class DailyCache { | ||
|
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. ここ、resource 毎にcache class 分ける今みたいな実装と、 excel の方は後者の作戦だね、リソース管理がめんどくさいから。 |
||
| static readonly cache = {} | ||
|
|
||
| static get(ticker: string, date: Date | DateParam): object | null { | ||
| if (date instanceof Date) { | ||
| date = new DateParam(date) | ||
| } | ||
|
|
||
| const cached = DailyCache.cache[`${ticker}-${date}`] | ||
| return cached === undefined ? null : cached | ||
| } | ||
|
|
||
| static put(ticker: string, daily: object): void { | ||
| DailyCache.cache[`${ticker}-${daily['day']}`] = daily | ||
| } | ||
|
|
||
| // for testing | ||
| static clearAll(): void { | ||
| Object.keys(this.cache).forEach(key => delete this.cache[key]) | ||
| } | ||
| } | ||
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,182 @@ | ||
| import { CompanyCache } from '~/__mocks__/services/company-cache' | ||
| import { QuarterCache } from '~/__mocks__/services/quarter-cache' | ||
| import { CachingBuffettCodeApiClientV3 } from '~/api/v3/caching-client' | ||
| import { DateParam } from '~/fiscal-periods/date-param' | ||
| import { YearQuarter } from '~/fiscal-periods/year-quarter' | ||
| import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' | ||
| import { DailyCache } from '~/services/daily-cache' | ||
|
|
||
| jest.mock('~/api/v3/client', () => | ||
| jest.requireActual('~/__mocks__/api/v3/client') | ||
| ) | ||
| jest.mock('~/services/company-cache', () => | ||
| jest.requireActual('~/__mocks__/services/company-cache') | ||
| ) | ||
| jest.mock('~/services/daily-cache', () => | ||
| jest.requireActual('~/__mocks__/services/daily-cache') | ||
| ) | ||
| jest.mock('~/services/quarter-cache', () => | ||
| jest.requireActual('~/__mocks__/services/quarter-cache') | ||
| ) | ||
|
|
||
| describe('company', () => { | ||
| const ticker = '2371' | ||
|
|
||
| test('(uncached)', () => { | ||
| expect(CompanyCache.get(ticker)).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.company(ticker) | ||
| expect(res).not.toBeNull() | ||
|
|
||
| expect(CompanyCache.get(ticker)).toEqual(res) | ||
| }) | ||
|
|
||
| test('(cached)', () => { | ||
| const cached = CompanyCache.get(ticker) | ||
| expect(cached).not.toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.company(ticker) | ||
| expect(res).toEqual(cached) | ||
|
|
||
| expect(CompanyCache.get(ticker)).toEqual(cached) | ||
| }) | ||
| }) | ||
|
|
||
| describe('daily', () => { | ||
| const ticker = '2371' | ||
|
|
||
| test('(uncached)', () => { | ||
| const date = new DateParam(new Date('2020-09-06')) | ||
| expect(DailyCache.get(ticker, date)).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.daily(ticker, date) | ||
| expect(res).not.toBeNull() | ||
|
|
||
| expect(DailyCache.get(ticker, date)).toEqual(res) | ||
| }) | ||
|
|
||
| test('(cached)', () => { | ||
| const date = new DateParam(new Date('2020-09-06')) | ||
| const cached = DailyCache.get(ticker, date) | ||
| expect(cached).not.toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.daily(ticker, date) | ||
| expect(res).toEqual(cached) | ||
|
|
||
| expect(DailyCache.get(ticker, date)).toEqual(cached) | ||
| }) | ||
| }) | ||
|
|
||
| describe('quarter', () => { | ||
| const ticker = '2371' | ||
|
|
||
| describe('(FY, FQ)', () => { | ||
| beforeAll(() => { | ||
| QuarterCache.clearAll() | ||
| }) | ||
|
|
||
| const period = new YearQuarterParam(2018, 1) | ||
|
|
||
| test('(uncached)', () => { | ||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.quarter(ticker, period) | ||
| expect(res).not.toBeNull() | ||
| expect(res['fiscal_year']).toBe(period.year) | ||
| expect(res['fiscal_quarter']).toBe(period.quarter) | ||
|
|
||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toEqual(res) | ||
| }) | ||
|
|
||
| test('(cached)', () => { | ||
| const cached = QuarterCache.get(ticker, period.toYearQuarter()) | ||
| expect(cached).not.toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.quarter(ticker, period) | ||
| expect(res).toEqual(cached) | ||
| expect(res['fiscal_year']).toBe(period.year) | ||
| expect(res['fiscal_quarter']).toBe(period.quarter) | ||
|
|
||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toEqual(cached) | ||
| }) | ||
| }) | ||
|
|
||
| describe('(LY, LQ)', () => { | ||
| beforeAll(() => { | ||
| QuarterCache.clearAll() | ||
| }) | ||
|
|
||
| const period = new YearQuarterParam('LY', 'LQ') | ||
|
|
||
| test('(uncached)', () => { | ||
| expect(QuarterCache.get(ticker, new YearQuarter(2018, 1))).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.quarter(ticker, period) | ||
| expect(res).not.toBeNull() | ||
| expect(res['fiscal_year']).toBe(2018) | ||
| expect(res['fiscal_quarter']).toBe(1) | ||
|
|
||
| expect(QuarterCache.get(ticker, new YearQuarter(2018, 1))).toEqual(res) | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| describe('ondemandQuarter', () => { | ||
| const ticker = '2371' | ||
|
|
||
| describe('(FY, FQ)', () => { | ||
| beforeAll(() => { | ||
| QuarterCache.clearAll() | ||
| }) | ||
|
|
||
| const period = new YearQuarterParam(2018, 1) | ||
|
|
||
| test('(uncached)', () => { | ||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.ondemandQuarter(ticker, period) | ||
| expect(res).not.toBeNull() | ||
|
|
||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toEqual(res) | ||
| }) | ||
|
|
||
| test('(cached)', () => { | ||
| const cached = QuarterCache.get(ticker, period.toYearQuarter()) | ||
| expect(cached).not.toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.ondemandQuarter(ticker, period) | ||
| expect(res).toEqual(cached) | ||
|
|
||
| expect(QuarterCache.get(ticker, period.toYearQuarter())).toEqual(cached) | ||
| }) | ||
| }) | ||
|
|
||
| describe('(LY, LQ)', () => { | ||
| beforeAll(() => { | ||
| QuarterCache.clearAll() | ||
| }) | ||
|
|
||
| const period = new YearQuarterParam('LY', 'LQ') | ||
|
|
||
| test('(uncached)', () => { | ||
| expect(QuarterCache.get(ticker, new YearQuarter(2018, 1))).toBeNull() | ||
|
|
||
| const client = new CachingBuffettCodeApiClientV3('token') | ||
| const res = client.ondemandQuarter(ticker, period) | ||
| expect(res).not.toBeNull() | ||
| expect(res['fiscal_year']).toBe(2018) | ||
| expect(res['fiscal_quarter']).toBe(1) | ||
|
|
||
| expect(QuarterCache.get(ticker, new YearQuarter(2018, 1))).toEqual(res) | ||
| }) | ||
| }) | ||
| }) |
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,94 @@ | ||
| import { BuffettCodeApiClientV3 } from '~/api/v3/client' | ||
| import { DateParam } from '~/fiscal-periods/date-param' | ||
| import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' | ||
| import { CompanyCache } from '~/services/company-cache' | ||
| import { DailyCache } from '~/services/daily-cache' | ||
| import { QuarterCache } from '~/services/quarter-cache' | ||
|
|
||
| export class CachingBuffettCodeApiClientV3 extends BuffettCodeApiClientV3 { | ||
| constructor(private token: string) { | ||
| super(token) | ||
| } | ||
|
|
||
| company(ticker: string): object { | ||
| const cached = CompanyCache.get(ticker) | ||
| if (cached) { | ||
| return cached | ||
| } | ||
|
|
||
| const company = super.company(ticker) | ||
| CompanyCache.put(ticker, company) | ||
|
|
||
| return company | ||
| } | ||
|
|
||
| daily(ticker: string, date: DateParam): object | null { | ||
| const cached = DailyCache.get(ticker, date) | ||
| if (cached) { | ||
| return cached | ||
| } | ||
|
|
||
| const daily = super.daily(ticker, date) | ||
| if (!daily) { | ||
| return null | ||
| } | ||
|
|
||
| DailyCache.put(ticker, daily) | ||
|
|
||
| return daily | ||
| } | ||
|
|
||
| quarter(ticker: string, period: YearQuarterParam): object | null { | ||
| if (period.convertibleToYearQuarter()) { | ||
| const cached = QuarterCache.get(ticker, period.toYearQuarter()) | ||
| if (cached) { | ||
| return cached | ||
| } | ||
| } | ||
|
|
||
| const quarter = super.quarter(ticker, period) | ||
| if (!quarter) { | ||
| return null | ||
| } | ||
|
|
||
| QuarterCache.put(ticker, quarter) | ||
|
|
||
| return quarter | ||
| } | ||
|
|
||
| ondemandDaily(ticker: string, date: DateParam): object | null { | ||
| const cached = DailyCache.get(ticker, date) | ||
| if (cached) { | ||
| return cached | ||
| } | ||
|
|
||
| const daily = super.ondemandDaily(ticker, date) | ||
| if (!daily) { | ||
| return null | ||
| } | ||
|
|
||
| DailyCache.put(ticker, daily) | ||
|
|
||
| return daily | ||
| } | ||
|
|
||
| ondemandQuarter(ticker: string, period: YearQuarterParam): object | null { | ||
| if (period.convertibleToYearQuarter()) { | ||
| const cached = QuarterCache.get(ticker, period.toYearQuarter()) | ||
| if (cached) { | ||
| return cached | ||
| } | ||
| } | ||
|
|
||
| const quarter = super.ondemandQuarter(ticker, period) | ||
| if (!quarter) { | ||
| return null | ||
| } | ||
|
|
||
| QuarterCache.put(ticker, quarter) | ||
|
|
||
| return quarter | ||
| } | ||
|
|
||
| // TODO: Add bulkDaily and bulkQuarter support | ||
| } |
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.
ここはtypoです…