Skip to content
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
27 changes: 27 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach to Docker",
"port": 9229,
"address": "localhost",
"localRoot": "${workspaceFolder}/app",
"remoteRoot": "/opt/app"
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"envFile": "${workspaceFolder}/app/.env",
"program": "${workspaceFolder}/app/src/scripts/by_region.js"
}
]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ Run tests defined in the `/app/__tests__` directory.

### `npm run debug`

- Runs the `npm run list:region` with `--inspect` mode for debugging in containers.
- Runs the `npm run list:region` with `--inspect` flag for debugging in containers.

</details>

Expand Down
3 changes: 2 additions & 1 deletion app/__tests__/municipalities/createMunicipalityInstance.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ const createMunicipalityInstance = (excelFile) => {
logger.log(
`[INFO]: Parsed municipalities from config: ${config.countMunicipalities}\n` +
`[INFO]: Parsed municipalities from Excel file: ${excel.countMunicipalities}\n` +
`[INFO]: Total data rows from Excel file: ${excelFile.data.length}, SheetJS (Excel) header rows count: ${excelFile.options.dataRowStart}\n`, {
`[INFO]: Parsed invalid-format municipalities (excluded from ${excel.countMunicipalities}): ${excelFile.invalidRows.length}\n` +
`[INFO]: Total data rows from Excel file: ${excelFile.data.length}, ${excelFile.invalidRows.length} invalid row(s), SheetJS (Excel) header rows count: ${excelFile.options.dataRowStart}\n`, {
color: ColorLog.COLORS.TEXT.CYAN
})

Expand Down
23 changes: 18 additions & 5 deletions app/__tests__/municipalities/municipalitiesCount.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ describe('Municipalities total count match', () => {
it('municipalities from provinces config should match with original Excel municipalities count', async () => {
jest.setTimeout(20000)

// Number of invalid Excel rows (rows with malformed "municipality-province" string patterns)
const countInvalidDataRows = excelFile.invalidRows.length

// Create local/remote ExcelFile classes using the default PAGASA region settings
const {
excel,
Expand Down Expand Up @@ -64,6 +67,13 @@ describe('Municipalities total count match', () => {
})
}

if (countInvalidDataRows > 0) {
logger.log(
`[WARNING]: ${countInvalidDataRows} INVALID EXCEL DATA ROWS(S) found:\n` +
`${arrayToString(excelFile.invalidRows)}`, { color: ColorLog.COLORS.TEXT.RED }
)
}

if (hasMissingInConfig || hasMissingInExcel) {
logger.log(
'[INFO]: If you believe these RED warning(s) are incorrect, feel free to reach out\n' +
Expand All @@ -75,7 +85,7 @@ describe('Municipalities total count match', () => {
passMsg += 'PAGASA seasonal & 10-day province/municipalities naming conventions for the other regions, and they\n'
passMsg += 'may change anytime without prior notice. Take note of the INFOS/WARNINGS and to accommodate CUSTOM SETTINGS as necessary:\n'
passMsg += '- Extend/override the class methods on custom scripts or\n'
passMsg += '- Eass custom (updated) regions.json config to the class constructors'
passMsg += '- Pass custom (updated) regions.json config to the class constructors'
expect(logger.log(passMsg, { color: ColorLog.COLORS.TEXT.YELLOW })).toBe(undefined)
} else {
logger.log('[MUNICIPALITIES]: Municipalities counts match in config and Excel', {
Expand All @@ -95,11 +105,14 @@ describe('Municipalities total count match', () => {
*/

if (excelFile.options.dataRowStart > 0) {
// Parsed/loaded municipalities in the Excel file using the (manual-encoded) PAGASA seasonal config
// including provinces missing in the config should be equal to the raw loaded data count
expect(totalMunicipalitiesConfig + excelFile.options.dataRowStart).toBe(excelFile.data.length)
// Subtract the invalid Excel rows count to the original Excel data rows count
const totalValidDataCount = excelFile.data.length - countInvalidDataRows

// Parsed/loaded municipalities in the Excel file using the (manual-encoded) PAGASA seasonal config
// including provinces missing in the config should be equal to the raw loaded data count
expect(totalMunicipalitiesConfig + excelFile.options.dataRowStart).toBe(totalValidDataCount)
} else {
throw new Error('Invalid 10-day Excel file format: Missing "Project Areas" text')
throw new Error(`Invalid 10-day Excel file format: Missing "${excelFile.DATA_ROW_START_MARKER}" text`)
}
})
})
4 changes: 2 additions & 2 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ph-municipalities",
"version": "1.4.5",
"version": "1.4.6",
"description": "Lists and writes Philippine municipalities by province or region into JSON files using PAGASA 10-Day weather forecast Excel files as a data source",
"main": "index.js",
"engines": {
Expand Down
37 changes: 33 additions & 4 deletions app/src/classes/excel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ class ExcelFile {
*/
#options = {
/**
* SheetJS array index number translated from the Excel headers row count
* before elements containing "municipalityName (provinceName)" data
* SheetJS-parsed (`this.#data[]`) array index number indicating the first row containing
* "municipalityName (provinceName)" municipality data.
* - This is also the number of `this.#data[]` rows before the actual rows with uniform Excel data
* @type {number}
*/
dataRowStart: 0,
Expand Down Expand Up @@ -95,7 +96,7 @@ class ExcelFile {
#datalist = []

/**
* string[] array of malformed (garbled) text characters to watch of for in the Excel file.
* string[] array of malformed (garbled) text characters to watch for in the Excel file.
* Its value is set in the `process.env.SPECIAL_CHARACTERS` env variable.
* @type {String[]}
*/
Expand All @@ -108,6 +109,21 @@ class ExcelFile {
*/
static malformedTextCorrections = {}

/**
* Invalid data rows that do not follow the expected "municipalityName (provinceName)" uniform
* e.g., also having a **province** that's not included in the **PAGASA Rainfall Analysis Table** in
* `"City of Isabela (City of Isabela (Not a Province))"`
* @type {string[]}
*/
#invalidRows = []

/**
* A marker text found in the Excel file and the sheetjs-parsed `this.#data[]` array that indicates
* the start of actual municipality data in the next array element (i.e., the next Excel row).
* @type {string}
*/
DATA_ROW_START_MARKER = 'Municipalities'

/**
* Node event emitter for listening to custom events.
* @type {Function}
Expand Down Expand Up @@ -229,9 +245,18 @@ class ExcelFile {
} else {
// Find the SheetJS array index of rows containing data
// Note: this relies on the structure of the default Excel file in /app/data/day1.xlsx or similar
if (row[this.#options.SHEETJS_COL] === 'Municipalities') {
if (row[this.#options.SHEETJS_COL] === this.DATA_ROW_START_MARKER) {
const OFFSET_FROM_FLAG = 2
this.#options.dataRowStart = index + OFFSET_FROM_FLAG
} else {
// Check if row index corresponds to province-municipality and weather forecast data row
const isDataRow = this.#options.dataRowStart > 0 &&
index >= this.#options.dataRowStart

// Store data row to `this.#invalidRows[]` since it does not follow the "municipalityName (provinceName)" pattern
if (isDataRow) {
this.#invalidRows.push(row[this.#options.SHEETJS_COL])
}
}

if (this.#metadata.forecastDate === null) {
Expand Down Expand Up @@ -426,6 +451,10 @@ class ExcelFile {
return this.#data
}

get invalidRows () {
return this.#invalidRows
}

// Returns the region data settings object
get settings () {
return this.#settings
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const ExcelFactory = require('../classes/excelfactory')

/**
* Prompts user to download a new excel file or use the static local excel file as data source
* @returns {ExcelHandler}
* @returns {ExcelFactory}
*/
const selectDataSource = async () => {
let exit = false
Expand Down