Search code examples
javascriptcodeceptjs

Create new json from source json file in test project


UPDATE I have continued to work through this and have the following code - st

  async generatejobs() {
    const fs = require("fs");
    const path = require("path");
    const directoryPath = path.join(__dirname, "../data/pjo/in");

    fs.readdir(directoryPath, function (err, files) {
      if (err) {
        console.log("Error getting directory information." + err);
      } else {
        files.forEach(function (file) {
          console.log(file);
          fs.readFile(file, (err, data) => {
            console.log(file); // this works, if I stop here
            // if (err) throw err;
            // let newJson = fs.readFileSync(data);
            // console.log(newJson);
          })
          // let data = fs.readFileSync(file);
          // let obj = JSON.parse(data);
          // let isoUtc = new Date();
          // let isoLocal = toISOLocal(isoUtc);
          // obj.printingStart = isoLocal;
          // obj.printingEnd = isoLocal;
          // let updatedFile = JSON.stringify(obj);
          // let write = fs.createWriteStream(
          //   path.join(__dirname, "../data/pjo/out", updatedFile)
          // );
          // read.pipe(write);
        });
      }
    });

As soon as I try uncomment the line shown below, it fails.

let newJson = fs.readFileSync(data);

The error I am getting is this.

Uncaught ENOENT: no such file or directory, open 'C:\projects\codeceptJs\ipt\80-012345.json'

This is a true statement as the path should be as follows.

'C:\projects\codeceptJs\ipt\src\data\pjo\in\80-012345.json'

I do not understand why it is looking for the file here given that earlier in the code the path is set and seems to work correctly for finding the file via this.

const directoryPath = path.join(__dirname, "../data/pjo/in");

The remainder of the code which is currently commented out is where I am attempting to do the following.

  • Grab each file from source dir
  • put into json object
  • Update the json object to change two date entries
  • Save to a new json file / new location in my project

Original Post I have a codeceptjs test project and would like to include a set of existing json files in my project (src/data/jsondata/in) and then update the date attribute within each and write them to an output location in my project (src/data/jsondata/out). I need to change the date and then get it back into a very specific string format, which I have done and then insert this back into the new json being created. I got this about 80% of the way there and then ran into issues when trying to get the files from one folder within my project to another.

I broke this up in to two parts.

  1. function to take a date and convert it to the date string I need

  2. function to grab the source json, update the date, and make a new json at a new folder location

Number 1 is working as it should. Number 2 is not.

If there is a better way to accomplish this, I am very much open to that.

Here is the code where I'm trying to update the json. The main issue here is I'm not understanding and / or handling correctly the join path stuff.

generatePressJobs() {
    //requiring path and fs modules
    const path = require('path');
    const fs = require('fs');
    //joining path of directory
    const directoryPath = path.join(__dirname, '../', 'data/pjo/in/');
    //passsing directoryPath and callback function
    fs.readdir(directoryPath, function (err, files) {
      //handling error
      if (err) {
        I.say('unable to scan directory: ' + err);
        return console.log('Unable to scan directory: ' + err);
      }
      //listing all files using forEach
      files.forEach(function (file) {
        // Update each file with new print dates
        let data = fs.readFileSync(file);
        let obj = JSON.parse(data);
        let isoUtc = new Date();
        let isoLocal = toISOLocal(isoUtc);
        obj.printingStart = isoLocal;
        obj.printingEnd = isoLocal;
        let updatedFile = JSON.stringify(obj);
        fs.writeFile(`C:\\projects\\csPptr\\ipt\\src\\data\\pjo\\out\\${file}`, updatedFile, (err) => {
          if (err) {
            throw err;
          }
        });
      });
    });
  },

Error received

Uncaught ENOENT: no such file or directory, open '80-003599.json'
      at Object.openSync (fs.js:462:3)
      at Object.readFileSync (fs.js:364:35)
      at C:\projects\codeceptJs\ipt\src\pages\Base.js:86:23
      at Array.forEach (<anonymous>)
      at C:\projects\codeceptJs\ipt\src\pages\Base.js:84:13
      at FSReqCallback.oncomplete (fs.js:156:23)

The function to generate the json is located in src/pages/basePage.js

The folder structure I've built for the json file is located in src/data/jsondata/in --> for original source files src/data/jsondata/out --> for resulting json after change

Any insight or suggestions would be hugely appreciated.

Thank you, Bob


Solution

  • My approach / resolution Passing along the final approach I took in the event this is helpful to anyone else. The data in the middle was specific to my requirements, but left in to show the process I took to do what I needed to do.

    async generatePressjobs(count) {
        const fs = require("fs");
        const path = require("path");
        const sourceDirectoryPath = path.join(__dirname, "../data/pjo/in/");
        const destDirectoryPath = path.join(__dirname, "../data/pjo/out/");
    
        for (i = 0; i < count; i++) {
          // read file and make object
          let content = JSON.parse(
            fs.readFileSync(sourceDirectoryPath + "source.json")
          );
    
          // Get current date and convert to required format for json file
          let isoUtc = new Date();
          let isoLocal = await this.toISOLocal(isoUtc);
          let fileNameTimeStamp = await this.getFileNameDate(isoUtc);
    
          // Get current hour and minute for DPI time stamp
          let dpiDate = new Date;
          let hour = dpiDate.getHours();
          let minute = dpiDate.getMinutes();
          dpiStamp = hour + '' + minute;
    
          // update attributes in the json obj
          content.batchid = `80-0000${i}`;
          content.id = `80-0000${i}-10035-tcard-${dpiStamp}-0101010000_.pdf`
          content.name = `80-0000${i}-8.5x11CALJEF-CalBody-${dpiStamp}-01010100${i}_.pdf`;
          content.printingStart = isoLocal;
          content.printingEnd = isoLocal;
    
          // write the file
          fs.writeFileSync(
            destDirectoryPath + `80-0000${i}-SOME-JOB-NAME-${dpiStamp}.pdf_Press Job printing end_${fileNameTimeStamp}.json`,
            JSON.stringify(content)
          );
        }
      },