"before each" hook for "is deployed": SyntaxError: Unexpected token u in JSON at position 0 - node.js

I am trying to test my contract in Mocha. and I am running into this issue where npm run test is giving the following result.
PiggyBank
1) "before each" hook for "is deployed"
0 passing (247ms)
1 failing
1) "before each" hook for "is deployed":
SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at Context.<anonymous> (test\PiggyBank.test.js:15:50)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
I tried searching on the web and making some tweaks but it didn't work.
Here is the contract PiggyBank.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract PiggyBank{
uint private pot;
//uint public input;
constructor (uint contribution){
// input = contribution;
pot = pot+contribution;
}
function peep () public view returns (uint) {
return pot;
}
function addToPot(uint contribution) public {
// input = contribution;
pot = pot + contribution;
}
}
Compile.js file given below
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const piggyBank = path.resolve(__dirname,'Contracts','PiggyBank.sol');
const source = fs.readFileSync(piggyBank,'utf8');
//console.log(solc.compile(source,1));
var input = {
language: 'Solidity',
sources: {
'PiggyBank.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
console.log(JSON.parse(solc.compile(JSON.stringify(input))));
let output = JSON.parse(solc.compile(JSON.stringify(input)));
console.log(output.contracts['PiggyBank.sol']['PiggyBank'].abi);
console.log(output.contracts['PiggyBank.sol']['PiggyBank'].evm.bytecode.object);
module.exports = solc.compile(JSON.stringify(input));
package.json given below
{
"name": "piggybank",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC",
"dependencies": {
"ganache-cli": "^6.12.2",
"mocha": "^10.0.0",
"solc": "^0.8.17",
"web3": "^1.8.0"
}
}
PiggyBank.test.js file is given below
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const {interface, bytecode} = require('../compile');
let accounts;
let piggyBank;
beforeEach(async function(){
accounts = await web3.eth.getAccounts();
piggyBank = await new web3.eth.Contract(JSON.parse(interface)).deploy({data:bytecode,arguments:[20]}).
send({from: accounts[1], gas:10000})
});
describe('PiggyBank',function(){
it('is deployed',function(){
console.log(piggyBank);
});
});
Will deeply appreciate help on this issue. Thanks in advance.
Update
I updated the code to only export the interface and bytecode
following code update in Compile.js
const interface = output.contracts['PiggyBank.sol']['PiggyBank'].abi;
const bytecode = output.contracts['PiggyBank.sol']['PiggyBank'].evm.bytecode.object;
console.log(JSON.stringify(input))
module.exports = {interface,bytecode};
But now I am getting following error
1) "before each" hook for "is deployed"
0 passing (44ms)
1 failing
1) "before each" hook for "is deployed":
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at Context.<anonymous> (test\PiggyBank.test.js:15:22)
at processImmediate (node:internal/timers:466:21)
It's having an issue parsing this part of code JSON.parse(interface)
piggyBank = await new web3.eth.Contract(JSON.parse(interface)).deploy({data:bytecode,arguments:[20]}).
send({from: accounts[1], gas:10000})
Thanks in advance

Related

Read enviroment based config properties in nodejs

I am C# guy but I am writing first time node JS lambda function.
I am trying to return JSON object the based on environment for example if query param ?env=prod
then expected response will be
{
"Aws_Client_Id": "ProdAbc",
"Aws_Secret_Key": "ProdAbc",
"FeatureStringTest": "DefaultValue"
}
config.json
{
"Aws_Client_Id": {
"Deafult": "Abc",
"Dev": "DevAbc",
"Uat": "UatAbc",
"Prod": "ProdAbc"
},
"Aws_Secret_Key": {
"Deafult": "Abc",
"Dev": "DevAbc",
"Uat": "UatAbc",
"Prod": "ProdAbc"
},
"FeatureStringTest": "DefaultValue"
}
my current lambda code
const fs = require("fs");
exports.handler = async (event) => {
const jsonString = fs.readFileSync("./config.json", 'utf8');
var config = JSON.parse(jsonString);
const response = {
statusCode: 200,
body: JSON.stringify(config),
};
return response;
};

Sinon throws on Discordjs ActionRowBuiilder stub

I am struggling with stubbing third party elements with Sinon. Anybody seeing an issue here?
The funny thing is I am running pretty much the exact same test for a different module and it works.
I do admit I am not great on instantiation but really not seeing it.
Code to test
'use strict'
const { ActionRowBuilder, SelectMenuBuilder } = require('discord.js')
class Action {
static async selectHook (interaction, client, deleteId) {
const row = new ActionRowBuilder()
.addComponents(
new SelectMenuBuilder()
.setCustomId('confirmselect')
.setPlaceholder('Please confirm')
.addOptions(
{
label: 'I confirm',
description: `Confirm hook #${deleteId}`,
value: deleteId
}
)
)
await interaction.update({
content: 'Hook was selected! Please confirm ' +
'by using the select menu again.',
components: [row],
ephemeral: true
})
}
}
Test file
'use strict'
const sinon = require('sinon')
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const sinonChai = require('sinon-chai')
chai.use(chaiAsPromised)
chai.use(sinonChai)
const expect = chai.expect
const { ActionRowBuilder, SelectMenuBuilder } = require('discord.js')
const client = {
once () {},
on () {},
},
const interaction = {
reply () {},
followUp () {},
update () {},
},
describe('app/Action', function () {
afterEach( function () {
sinon.restore()
})
describe('Action.selectHook', function () {
it(' should run interaction.update', async function () {
const updateStub = sinon.stub(interaction, 'update')
.resolves()
sinon.spy(function () {
return sinon.createStubInstance(ActionRowBuilder)
})
sinon.spy(function () {
return sinon.createStubInstance(SelectMenuBuilder)
})
await Action.selectHook(interaction, client, 1)
sinon.assert.calledOnceWithMatch(
updateStub,
{
content: 'Hook was selected! Please confirm ' +
'by using the select menu again.'
}
)
})
})
})
I have also tried with
sinon.createStubInstance(SelectMenuBuilder)
sinon.createStubInstance(ActionRowBuilder)
Anyways I get
1) should run interaction.update
0 passing (199ms)
1 failing
1) app/Action
Action.selectHook
should run interaction.update:
Error: Received one or more errors
at UnionValidator.handle (node_modules/#sapphire/shapeshift/dist/index.js:1085:23)
at UnionValidator.parse (node_modules/#sapphire/shapeshift/dist/index.js:142:88)
at /home/axel/Dropbox/0_Programming/discordjs-captain-hook/node_modules/#discordjs/builders/dist/index.js:557:147
at Array.map (<anonymous>)
at SelectMenuBuilder.addOptions (node_modules/#discordjs/builders/dist/index.js:557:34)
at SelectMenuBuilder.addOptions (node_modules/discord.js/src/structures/SelectMenuBuilder.js:48:18)
at Function.selectHook (app/Action.js:108:22)
at Context.<anonymous> (tests/mocha/Action.js:265:26)
at processImmediate (node:internal/timers:464:21)
Running on
Nodejs: v16.13.2
"discord-api-types": "^0.37.2",
"discord.js": "^14.2.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"sinon": "^14.0.0",
"sinon-chai": "^3.7.0"

Error while deploying a smart contract to Mumbai testnet through Hardhat

I've been having this problem while trying to deploy a smart contract to the Mumbai testnet using Hardhat, and I keep getting the following error:
Error HH9: Error while loading Hardhat's configuration.
You probably tried to import the "hardhat" module from your config or a file imported from it.
This is not possible, as Hardhat can't be initialized while its config is being defined.
To learn more about how to access the Hardhat Runtime Environment from different contexts go to https://hardhat.org/hre
Here's my smart contract code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
// implements the ERC721 standard
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
// keeps track of the number of tokens issued
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
// Here we need to get the contract object sent from the frontend React app and replace the properties of the contract hereunder
// Accessing the Ownable method ensures that only the creator of the smart contract can interact with it
contract myContract is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter private currentTokenId;
/// #dev Base token URI used as a prefix by tokenURI().
string public baseTokenURI;
constructor() ERC721("MyToken", "MTK") {
baseTokenURI = "";
}
function mintTo(address recipient) public returns (uint256) {
currentTokenId.increment();
uint256 newItemId = currentTokenId.current();
_safeMint(recipient, newItemId);
return newItemId;
}
/// #dev Returns an URI for a given token ID
function _baseURI() internal view virtual override returns (string memory) {
return baseTokenURI;
}
/// #dev Sets the base token URI prefix.
function setBaseTokenURI(string memory _baseTokenURI) public {
baseTokenURI = _baseTokenURI;
}
}
Here's the deploy script:
const { ethers } = require("hardhat");
async function main() {
// Fetching the compiled contract using ethers.js
const contract = await ethers.getContractFactory("myContract");
// calling deploy() will return an async Promise that we can await on
const CustomSC = await contract.deploy();
console.log(`Contract deployed to address: ${CustomSC.address}`);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
And here's my hardhat.config file:
/**
* #type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("#nomiclabs/hardhat-ethers");
require("#nomiclabs/hardhat-waffle");
require("./scripts/deploy.js");
require("#nomiclabs/hardhat-etherscan");
const { MORALIS_POLYGON_KEY, POLYGONSCAN_API_KEY, ACCOUNT_PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.1",
defaultNetwork: "mumbai",
networks: {
hardhat: {},
mumbai: {
url: `${MORALIS_POLYGON_KEY}`,
accounts: [`0x${ACCOUNT_PRIVATE_KEY}`],
},
},
etherscan: {
apiKey: POLYGONSCAN_API_KEY,
},
};
And here's my package.json file:
{
"name": "backend",
"version": "1.0.0",
"description": "backend for the NFT Marketplace dApp",
"main": "src/server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon src/server.js",
"build": "node src/server.js"
},
"author": "Ayed Oukhay",
"license": "ISC",
"dependencies": {
"#openzeppelin/contracts": "^4.0.0",
"body-parser": "^1.20.0",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.18.1",
"helmet": "^5.0.2",
"mongodb": "^4.5.0",
"mongoose": "^6.3.2",
"nodemon": "^2.0.16",
"web3": "^1.7.3"
},
"devDependencies": {
"#nomiclabs/hardhat-ethers": "^2.0.6",
"#nomiclabs/hardhat-etherscan": "^3.0.3",
"#nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.6",
"hardhat": "^2.9.5"
}
}
When I tried fixing it by replacing the following line:
const { ethers } = require("hardhat");
with: const { ethers } = require("hardhat/config");
I get the following error:
TypeError: Cannot read property 'getContractFactory' of undefined
And even when I replaced the deploy.js code with one that's based on tasks and helpers, it compiles successfully but the npx hardhat run scripts/deploy.js --network mumbai it doesn't return anything.
here's the code that I replaced it with:
deploy.js
const { task } = require("hardhat/config");
const { getAccount } = require("./helpers.js");
task("deploy", "Deploys the smart contract ...").setAction(async function (taskArguments, hre) {
const myContractFactory = await hre.ethers.getContractFactory("myContract", getAccount());
console.log('Deploying myContract...');
const contract = await myContractFactory.deploy();
await contract.deployed();
console.log(`Contract deployed to address: ${contract.address}`);
});
and helpers.js
const { ethers } = require("ethers");
const { getContractAt } = require("#nomiclabs/hardhat-ethers/internal/helpers");
// Helper method for fetching environment variables from .env
function getEnvVariable(key, defaultValue) {
if (process.env[key]) {
return process.env[key];
}
if (!defaultValue) {
throw `${key} is not defined and no default value was provided`;
}
return defaultValue;
}
// Helper method for fetching a connection provider to the Ethereum network
function getProvider() {
return ethers.getDefaultProvider(getEnvVariable("NETWORK", "mumbai"), {
moralis: getEnvVariable("MORALIS_POLYGON_KEY"),
});
}
// RQ:: The getProvider() helper also lets us use other EVM networks (like Ethereum mainnet or Polygon) by optionally setting a NETWORK environment variable in .env.
// Helper method for fetching a wallet account using an environment variable for the PK
function getAccount() {
return new ethers.Wallet(getEnvVariable("ACCOUNT_PRIVATE_KEY"), getProvider());
}
// Helper method for fetching a contract instance at a given address
function getContract(contractName, hre) {
const account = getAccount();
return getContractAt(hre, contractName, getEnvVariable("NFT_CONTRACT_ADDRESS"), account);
}
module.exports = {
getEnvVariable,
getProvider,
getAccount,
getContract,
}
Any help would be really appreciated, I've been stuck on this for almost a week now.
Ironically, I found the solution just as I posted this. well, here it is for anyone who's facing the same problem: in the hardhat.config file, remove the '${}' from both network url and accounts. that solved it for me. Can't believe it took me so long to figure out lol
so your config file should look like this:
/**
* #type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("#nomiclabs/hardhat-ethers");
require("#nomiclabs/hardhat-waffle");
// require("./scripts/deploy.js");
require("#nomiclabs/hardhat-etherscan");
const { MORALIS_POLYGON_KEY, POLYGONSCAN_API_KEY, ACCOUNT_PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.1",
defaultNetwork: "mumbai",
networks: {
hardhat: {},
mumbai: {
url: MORALIS_POLYGON_KEY,
accounts: [ACCOUNT_PRIVATE_KEY],
},
},
etherscan: {
apiKey: POLYGONSCAN_API_KEY,
},
};

TypeError: Slackbot is not a constructor

I need your help because it's the first time that I develop a Slack bot and I don't understand why this message appear:
const botSlack = new Slackbot ({
^
TypeError: Slackbot is not a constructor
Here my code : slack.js
const {Slackbot} = require('#slack/bolt');
const botSlack = new Slackbot({
token : process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
(async () => {
await botSlack.start(process.env.PORT || 3000);
})();
Part of my package.json:
"scripts": {
"dev": "nodemon slack.js",
},
"dependencies": {
"#slack/bolt": "^3.11.0",
},
In the bolt documentation (https://api.slack.com/tutorials/hello-world-bolt) and others, it's the same and it's run.
Please someone can explain to me why ?
The documentation has this code - App instead of Slackbot. You can rename the local variable if you want, but the import statement requires the exact name:
const { App } = require('#slack/bolt');
const botSlack = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
(async () => {
await botSlack.start(process.env.PORT || 3000);
})();
if you do want to rename the value, you can use
const { App: Slackbot } = require('#slack/bolt');
It is more common to use import statements for this, you can still alias it using import { App as Stackbot} from '#slack/bolt', see MDN - import

Testing NodeJS with Mocha: 'Require is not defined'

EDIT:
As per the comment on the answer below: removing "type": "module" from package.json, which as I understand it is what makes Node understand 'import' and 'export' statements, and reverting everything to 'require' and 'module.exports' solved the issue.
Is there a way to keep 'import' and 'export' and still make Mocha work?
I have a very simple Node file that I'm trying to test with Mocha/Chai. The actual code is trivial, this is just to learn a bit about Mocha and how to use it. But when I run the Mocha test, I get the error ERROR: ReferenceError: require is not defined
`
I did some googling for people experiencing the same problem but the examples that I came up with were when they were running the test in the browser (see, for example, Mocha, "require is not defined" when test in browser).
The file I want to test, index.js
const argv = require('minimist')(process.argv.slice(2));
const digitTester = /\d/g;
const capTester = /[A-Z]/g;
const dict = {
length:10,
must_have_numbers: true,
must_have_caps: true
}
export default function passwordCheck(password) {
if (!password) return false;
if (typeof password !== "string") return false;
if (password.length < dict.length) return false; // assumes that 10 is a MINIMUM length
if (dict.must_have_numbers && !digitTester.test(password)) return false;
return !(dict.must_have_caps && !capTester.test(password));
}
if (argv._.length) {
console.log(passwordCheck(argv._[0]))
}
/**
* alternate version to check a lot of passwords:
*
* if (argv._.length) {
* for (const pwd of argv_) console.log(passwordCheck(pwd)
*}
*
*/
the mocha file, test/index.test.js
const chai = require('chai')
const expect = chai.expect
const passwordCheck = require('../index.js')
const tooShort = "A2a"
const noCaps = "a2abcdefghijklmnop"
const noNumber = "Aabcdefghijklmnop"
const good = "A2abcdefghijklmnop"
describe('password checking', () => {
it('should return false for passwords less than length 10', () => {
expect(passwordCheck(tooShort)).to.be.false;
});
it('should return false for passwords without a capital letter', () => {
expect(passwordCheck(noCaps)).to.be.false;
});
it('should return false for passwords without a number', () => {
expect(passwordCheck(noNumber)).to.be.false;
});
it('should return true for passwords that match criteria', () => {
expect(passwordCheck(good)).to.be.true;
});
});
and package.json
{
"name": "codetest",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "mocha"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"#types/minimist": "^1.2.1",
"#types/node": "^14.14.20",
"chai": "^4.2.0",
"minimist": "^1.2.5",
"mocha": "^8.2.1"
}
}
and the error message is
✖ ERROR: ReferenceError: require is not defined
at file:///Users/r/Documents/Projects/sandbox/pwd_checker/index.js:2:14
at ModuleJob.run (node:internal/modules/esm/module_job:152:23)
at async Loader.import (node:internal/modules/esm/loader:166:24)
at async exports.handleRequires (/Users/r/Documents/Projects/sandbox/pwd_checker/node_modules/mocha/lib/cli/run-helpers.js:94:28)
at async /Users/r/Documents/Projects/sandbox/pwd_checker/node_modules/mocha/lib/cli/run.js:341:25
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Node 15.
Remove this line - "type": "module" from package.json and check whether it’s working or not.
Prepend your tests with the following:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
This is because you cannot require from an ESM module; for more info please see this comment on a nodejs issue.
Documentation: https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs

Resources