Skip to content

Commit

Permalink
Merge pull request #83 from ciatph/dev
Browse files Browse the repository at this point in the history
v1.3.0
  • Loading branch information
ciatph authored Aug 26, 2024
2 parents 413a65a + d5f0442 commit f07784e
Show file tree
Hide file tree
Showing 23 changed files with 8,345 additions and 2,393 deletions.
23 changes: 0 additions & 23 deletions .github/workflows/lint.yml

This file was deleted.

45 changes: 45 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Lint Files

on:
push:
branches-ignore:
- 'master'

jobs:
lint-app:
name: Lint App
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3
- name: Use NodeJS v16.14.2
uses: actions/setup-node@v3
with:
node-version: 16.14.2
- name: Install Dependencies and lint
run: |
cd app
npm install
npm run lint
test:
name: Test App
runs-on: ubuntu-latest
needs: lint-app
env:
EXCEL_FILE_URL: ${{ secrets.EXCEL_FILE_URL }}
SHEETJS_COLUMN: ${{ secrets.SHEETJS_COLUMN }}
SORT_ALPHABETICAL: ${{ secrets.SORT_ALPHABETICAL }}
SPECIAL_CHARACTERS: ${{ secrets.SPECIAL_CHARACTERS }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3
- name: Use NodeJS v16.14.2
uses: actions/setup-node@v3
with:
node-version: 16.14.2
- name: Install Dependencies and Test
run: |
cd app
npm install
npm test
3 changes: 2 additions & 1 deletion app/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ dist/
# Ignore all Excel files except:
!data/day1.xlsx

# Exclude examples
# Exclude directories
src/examples/

# Docker
Dockerfile
.dockerignore
jest.config.js
29 changes: 29 additions & 0 deletions app/__tests__/classInitialization/checkClass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint-disable no-undef */

/**
* Checks valid `ExcelFile` or `ExcelFactory` class instances.
* @typedef {Object} params - Input parameters
* @param {Function} excelInstance - `ExcelFile` or `ExcelFactory` class instance
* @param {Bool} isRemote - Flag if the Excel data source is from a remote download. Defaults to `false`.
* @param {Function} classType - `ExcelFile` or `ExcelFactory` class
*/
const checkClass = ({ excelInstance, isRemote = false, classType = null }) => {
expect(excelInstance).toBeDefined()
expect(excelInstance instanceof classType).toBe(true)
expect(Array.isArray(excelInstance.datalist)).toBe(true)
expect(excelInstance.datalist.length).toBeGreaterThan(0)

const regions = excelInstance.listRegions()
expect(Array.isArray(regions)).toBe(true)
expect(regions.every(item => typeof item === 'string')).toBe(true)

if (isRemote) {
expect(typeof excelInstance.url).toBe('string')
expect(typeof excelInstance.url).toBe('string')
} else {
expect(excelInstance.url).toBeNull()
expect(excelInstance.url).toBeNull()
}
}

module.exports = checkClass
26 changes: 26 additions & 0 deletions app/__tests__/classInitialization/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"metadata": {
"sources": [
"https://www.pagasa.dost.gov.ph/climate/climate-prediction/seasonal-forecast"
],
"title": "List of Philippine Provinces by Regions",
"description": "This dataset is a list of provinces in the Philippines grouped by regions. Region data was manually encoded using the PAGASA source URLs as the primary source of information and Wikipedia as a secondary source. The final region data are adjusted to sync with the PAGASA 10-Day Weather Forecast Excel files (2nd source).",
"date_created": "20240826"
},
"data": [
{
"name": "Region I",
"abbrev": null,
"region_num": "1",
"region_name": "Ilocos",
"provinces": ["Ilocos Norte","Ilocos Sur","La Union","Pangasinan"]
},
{
"name": "Region II",
"abbrev": null,
"region_num": "2",
"region_name": "Cagayan Valley",
"provinces": ["Batanes","Cagayan","Isabela","Nueva Vizcaya","Quirino"]
}
]
}
122 changes: 122 additions & 0 deletions app/__tests__/classInitialization/fileLoading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
require('dotenv')
const path = require('path')

const ExcelFile = require('../../src/classes/excel')
const ExcelFactory = require('../../src/classes/excelfactory')
const ColorLog = require('../../src/classes/colorlog')
const logger = new ColorLog({ isBold: true })

const checkClass = require('./checkClass')
const config = require('./config.json')

/* eslint-disable no-undef */
describe('Class intialization using DEFAULT config', () => {
it('should load local Excel file', () => {
const excelFile = new ExcelFile({
pathToFile: path.join(__dirname, '..', '..', 'data', 'day1.xlsx')
})

const excelFactory = new ExcelFactory()

checkClass({
excelInstance: excelFactory,
classType: ExcelFactory
})

checkClass({
excelInstance: excelFile,
classType: ExcelFile
})
})

it('should load remote Excel file', async () => {
jest.setTimeout(15000)

const excelFile = new ExcelFile({
pathToFile: path.join(__dirname, 'excelfiledownload.xlsx'),
url: process.env.EXCEL_FILE_URL
})

const excelFactory = new ExcelFactory({
url: process.env.EXCEL_FILE_URL
})

// Start file download
await Promise.all([
excelFile.init(),
excelFactory.init()
])

checkClass({
excelInstance: excelFactory,
isRemote: true,
classType: ExcelFactory
})

checkClass({
excelInstance: excelFile,
isRemote: true,
classType: ExcelFile
})

logger.log('[INIT]: Success loading using "DEFAULT" config')
})
})

describe('Class intialization using CUSTOM config', () => {
it('should load local Excel file', () => {
const excelFile = new ExcelFile({
pathToFile: path.join(__dirname, '..', '..', 'data', 'day1.xlsx'),
settings: config
})

const excelFactory = new ExcelFactory({
settings: config
})

checkClass({
excelInstance: excelFactory,
classType: ExcelFactory
})

checkClass({
excelInstance: excelFile,
classType: ExcelFile
})
})

it('should load remote Excel file', async () => {
jest.setTimeout(15000)

const excelFile = new ExcelFile({
pathToFile: path.join(__dirname, 'excelfiledownload.xlsx'),
url: process.env.EXCEL_FILE_URL,
settings: config
})

const excelFactory = new ExcelFactory({
url: process.env.EXCEL_FILE_URL,
settings: config
})

// Start file download
await Promise.all([
excelFile.init(),
excelFactory.init()
])

checkClass({
excelInstance: excelFactory,
isRemote: true,
classType: ExcelFactory
})

checkClass({
excelInstance: excelFile,
isRemote: true,
classType: ExcelFile
})

logger.log('[INIT]: Success loading using "CUSTOM" config')
})
})
67 changes: 67 additions & 0 deletions app/__tests__/municipalities/createMunicipalityInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require('dotenv')

const ColorLog = require('../../src/classes/colorlog')
const logger = new ColorLog({ color: ColorLog.COLORS.TEXT.YELLOW, isBold: true })

/**
* Builds objects containing all provinces AND municipality names for the PAGASA seasonal config and 10-Day Excel file to use for comparison checks and logs viewing purposes only.
* @param {Class} excelFile - `ExcelFile` or `ExcelFactory` instance
* @returns {Object} Object containing Arrays and Sets of province and municipality names
* - `hasMissingInExcel` {Bool} - Flag if province(s) exist in the PAGASA seasonal config but not in the 10-day Excel
* - `hasMissingInConfig` {Bool} - Flag if municipalities exist in 10-day Excel but not in the municipalities list built from the PAGASA seasonal config
* - `excel` {Object} - Contains full province/municipality names and data from the 10-day Excel file
* - `excel.provinces` {String[]} - all provinces from the 10-day Excel file
* - `excel.municipalities` {Object} - Object with province names as keys and values are String[] array of municipalities under the province
* - `excel.countMunicipalities` {Number} - Total number of all municipalities read from the 10-day Excel file
* - `config` {Object} - Contains province/municipality names and data from the PAGASA seasonal config file
* - `config.provinces` {String[]} - all provinces from the PAGASA seasonal config file
* - `config.municipalities` {Object} - Object with the config's province names as keys and values are String[] array of municipalities under the province
* - `config.countMunicipalities` {Number} - Total number of all municipalities read from the PAGASA config file
*/
const createMunicipalityInstance = (excelFile) => {
try {
// Unique provinces/municipalities from the 10-day Excel file
const excel = {}

excel.provinces = excelFile.datalist
.map(item => item.province)
.filter((x, i, a) => a.indexOf(x) === i)

excel.municipalities = excelFile
.listMunicipalities({ provinces: excel.provinces })

excel.countMunicipalities = Object.values(
excel.municipalities
).reduce(
(sum, item) => sum + item.length, 0
)

// Unique provinces/municipalities from the config file (PAGASA Seasonal)
const config = {}
config.provinces = new Set(excelFile.listRegions('provinces').flat())
config.municipalities = excelFile.listMunicipalities({ provinces: [...config.provinces] })
config.countMunicipalities = Object.values(config.municipalities).reduce((sum, item) => sum + item.length, 0)

// Municipalities exist in 10-day Excel but not in the municipalities list built from the PAGASA seasonal config
const hasMissingInConfig = (excel.countMunicipalities - config.countMunicipalities) > 0
// Province(s) exist in the PAGASA seasonal config but not in the 10-day Excel
const hasMissingInExcel = (config.provinces.size - excel.provinces.length) > 0

logger.log(
`[INFO]: Parsed municipalities from config: ${config.countMunicipalities}\n` +
`loaded municipalities from Excel file: ${excel.countMunicipalities}\n`, {
color: ColorLog.COLORS.TEXT.CYAN
})

return {
excel,
config,
hasMissingInExcel,
hasMissingInConfig
}
} catch (err) {
throw new Error(err.message)
}
}

module.exports = createMunicipalityInstance
5 changes: 5 additions & 0 deletions app/__tests__/municipalities/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const createMunicipalityInstance = require('./createMunicipalityInstance')

module.exports = {
createMunicipalityInstance
}
Loading

0 comments on commit f07784e

Please sign in to comment.