truffle - artifacts.require is not a function - javascript

I am currently learning solidity and creating my first project. I am trying to test the deployment of my contract with truffle and i keep getting the below error
TypeError: artifacts.reqiure is not a function
Syntax looks correct and there are no errors appearing. I have also gone into the truffle console and the migration seems to have deployed ok and Color.json is now in my abis folder as well.
Any help will be appreciated, all files are below.
Color.sol
pragma solidity 0.5.0;
import "./ERC721Full.sol";
contract Color is ERC721Full {
// Initialise function
constructor () ERC721Full("Color", "COLOR") public {
}
}
Color.test.js
const Color = artifacts.reqiure('./Color.sol')
require('chai')
.use(require('chai-as-promised'))
.should()
contract('Color', (accounts) => {
let contract
before(async () => {
contract = await Color.deployed()
})
describe('deployment,', async() => {
it('deploys successfully', async() => {
contract = await Color.deployed()
const address = contract.address
console.log(address)
assert.notEqual(address,"")
assert.notEqual(address, 0x0)
assert.notEqual(address, null)
assert.notEqual(address, undefined)
})
it('has a name', async () => {
const name = await contract.name()
assert.equal(name, 'Color')
})
it('has a symbol', async () => {
const symbol = await contract.symbol()
assert.equal(symbol, 'COLOR')
})
})
})
2_deploy_contracts.js
const Color = artifacts.require("Color");
module.exports = function(deployer) {
deployer.deploy(Color);
};
1_init_migration.js
const Migrations = artifacts.require("Migrations");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};

Make sure you have
require('#nomiclabs/hardhat-truffle5');
Before you're trying to call artifacts.require

You have a typo in Color.test.js
const Color = artifacts.reqiure('./Color.sol')
should be require

I tried out this particular code and it shows out an error message and after looking into the line it is just a small spelling error in this particular line in the color code: -
const Color = artifacts.reqiure('./Color.sol')
Try replacing it with this: -
const Color = artifacts.require('./Color.sol')

Related

NodeJS: My jest spyOn function is not being called

I don't understand why my spy is not being used. I have used this code elsewhere and it has worked fine.
Here is my test:
const {DocumentEngine} = require('../documentEngine')
const fileUtils = require('../utils/fileUtils')
const request = {...}
const fieldConfig = {...}
test('If the Carbone addons file is not found, context is built with the carboneAddons property as an empty object', async () => {
const expectedResult = {
carboneAddons: {},
}
const fileExistSpy = jest
.spyOn(fileUtils, 'checkFileExists')
.mockResolvedValue(false)
const result = await docEngine.buildContext(request, fieldConfig)
expect(fileExistSpy).toHaveBeenCalledTimes(1)
})
Here is the code that it is being tested:
async function buildContextForLocalResources(request, fieldConfig) {
/* other code */
const addonFormatters = await getCarboneAddonFormatters()
const context = {
sourceJson,
addonFormatters,
documentFormat,
documentTemplateId,
documentTemplateFile,
responseType,
jsonTransformContext
}
return context
}
async function getCarboneAddonFormatters() {
const addOnPath = path.resolve(
docConfig.DOC_GEN_RESOURCE_LOCATION,
'library/addon-formatters.js'
)
if (await checkFileExists(addOnPath)) {
logger.info('Formatters found and are being used')
const {formatters} = require(addOnPath)
return formatters
}
logger.info('No formatters were found')
return {}
}
This is the code from my fileUtils file:
const fs = require('fs/promises')
async function checkFileExists(filePath) {
try {
await fs.stat(filePath)
return true
} catch (e) {
return false
}
}
My DocumentEngine class calls the buildContext function which in turn calls the its method getCarboneAddonFormatters. The fileUtils is outside of DocumentEngine class in a utilities folder. The original code I had this working on was TypeScript as opposed to this which is just NodeJS Javascript. The config files for both are the same. When I try to step through the code (VSCode debugger), as soon as I hit the line with await fs.stat(filePath) in the checkFileExists function, it kicks me out of the test and moves on to the next test - no error messages or warnings.
I've spent most of the day trying to figure this out. I don't think I need to do an instance wrapper for the documentEngine, because checkFileExists is not a class member, and that looks like a React thing...
Any help in getting this to work would be appreciated.

CoinbaseWalletSDK does not work with server side rendering

I was trying to load CoinbaseWalletSDK in my NextJS application, but it always throw an error of ReferenceError: localStorage is not defined due to it was imported before the window is loaded. I tried dynamic loading but it doesn't work. The following is what I am using at this moment.
export async function getServerSideProps({
params,
}: {
params: { project_id: string };
}) {
const project_id = params.project_id;
let project: any = fakeProjects[0];
if (project_id && typeof project_id === 'string' && !isNaN(parseInt(project_id))) {
const id = project_id;
project = fakeProjects.find(p => p.id === parseInt(id));
// Fetch project detail here
let item = await (
getNFTStatsByProjectId(
parseInt(project_id)
)
);
if (project && item && item['nftTotal'] && item['nftSold']) {
if (item.nftSold > item.nftTotal) {
item.nftSold = item.nftTotal;
}
project.nftTotal = item.nftTotal;
project.nftSold = item.nftSold;
}
}
const { coinbaseEth } = (await import('../../components/services/coinbase'));
return {
props: {
project: project,
coinbaseEth: coinbaseEth
},
};
}
And this is what I have in the coinbase service:
// TypeScript
import CoinbaseWalletSDK from '#coinbase/wallet-sdk'
import Web3 from 'web3'
const APP_NAME = 'Practice App'
const APP_LOGO_URL = process.env.WEBSITE_URL + '/logo.png'
const DEFAULT_ETH_JSONRPC_URL = 'https://mainnet.infura.io/v3/' + process.env.INFURA_PROJECT_ID
const DEFAULT_CHAIN_ID = 1
// Initialize Coinbase Wallet SDK
export const coinbaseWallet = new CoinbaseWalletSDK({
appName: APP_NAME,
appLogoUrl: APP_LOGO_URL,
darkMode: false
})
// Initialize a Web3 Provider object
export const coinbaseEth = coinbaseWallet.makeWeb3Provider(DEFAULT_ETH_JSONRPC_URL, DEFAULT_CHAIN_ID)
// Initialize a Web3 object
export const web3 = new Web3(coinbaseEth as any)
The new CoinbaseWalletSDK is where the error was thrown if that's a concern.
Based on my research, I will need to get it imported after the page is fully loaded (which is the point when "window" become available, as well as "localStorage"), which I have no clue how to achieve. Can anyone help me out on this?
I solved it by loading it later. What I did was to assign this variable with this function.
setTimeout(async () => {
coinbaseEth = (await import('../../components/services/coinbase')).coinbaseEth;
}, 1000)
I choose not to use useEffect because the value will be lost on render, which prevents the function to work properly.

How to mock fs module together with unionfs?

I have written a test case that successfully load files into virtual FS, and at the same time mounted a virtual volume as below
describe("should work", () => {
const { vol } = require("memfs");
afterEach(() => vol.reset());
beforeEach(() => {
vol.mkdirSync(process.cwd(), { recursive: true });
jest.resetModules();
jest.resetAllMocks();
});
it("should be able to mock fs that being called in actual code", async () => {
jest.mock("fs", () => {
return ufs //
.use(jest.requireActual("fs"))
.use(createFsFromVolume(vol) as any);
});
jest.mock("fs/promises", () => {
return ufs //
.use(jest.requireActual("fs/promises"))
.use(createFsFromVolume(vol) as any);
});
const { createFsFromVolume } = require("memfs");
const { ufs } = require("unionfs");
const { countFile } = require("../src/ops/fs");
vol.fromJSON(
{
"./some/README.md": "1",
"./some/index.js": "2",
"./destination": null,
},
"/app"
);
const result = ufs.readdirSync(process.cwd());
const result2 = ufs.readdirSync("/app");
const result3 = await countFile("/app");
console.log({ result, result2, result3 });
});
});
By using ufs.readdirSync, I can access to virtual FS and indeed result giving me files that loaded from disc into virtual FS, result2 representing /app which is a new volume created from vol.fromJSON.
Now my problem is I am unable to get the result for result3, which is calling countFile method as below
import fsPromises from "fs/promises";
export const countFile = async (path: string) => {
const result = await fsPromises.readdir(path);
return result.length;
};
I'm getting error
Error: ENOENT: no such file or directory, scandir '/app'
which I think it's because countFile is accessing the actual FS instead of the virtual despite I've had jest.mock('fs/promises')?
Please if anyone can provide some lead?
This is the function you want to unit test.
//CommonJS version
const fsPromises = require('fs/promises');
const countFile = async (path) => {
const result = await fsPromises.readdir(path);
return result.length;
};
module.exports = {
countFile
}
Now, how you would normally go about this, is to mock fsPromises. In this example specifically readdir() since that is the function being used in countFile.
This is what we call: a stub.
A skeletal or special-purpose implementation of a software component, used to develop or test a component that calls or is otherwise dependent on it. It replaces a called component.
const {countFile} = require('./index');
const {readdir} = require("fs/promises");
jest.mock('fs/promises');
beforeEach(() => {
readdir.mockReset();
});
it("When testing countFile, given string, then return files", async () => {
const path = "/path/to/dir";
// vvvvvvv STUB HERE
readdir.mockResolvedValueOnce(["src", "node_modules", "package-lock.json" ,"package.json"]);
const res = await countFile(path);
expect(res).toBe(4);
})
You do this because you're unit testing. You don't want to be dependent on other functions because that fails to be a unit test and more integration test. Secondly, it's a third-party library, which is maintained/tested by someone else.
Here is where your scenario applies. From my perspective, your objective isn't to test countFile() rather, to test fsPromises and maybe test functionality to read virtual file-systems: unionfs. If so then, fsPromises doesn't need to really be mocked.

Test firestore trigger locally

I am writing a test which tests a firebase trigger. The problem, however, is that I cannot make it work.
I want to use the local firestore emulator and Jest in order to simulate a change in the firestore and see if the trigger does what it needs to do.
I require the cloud function in my test and I initialize my app
Setup.js:
const firebase = require('#firebase/testing');
const PROJECT_ID = 'project';
let admin;
let db;
const setupAdmin = async () => {
admin = firebase.initializeAdminApp({
projectId: PROJECT_ID
});
db = admin.firestore();
};
const getAdmin = () => {
return admin;
};
const getDb = () => {
return db;
};
module.exports.setupAdmin = setupAdmin;
module.exports.getAdmin = getAdmin;
module.exports.getDb = getDb;
Test.js
describe('Billing', () => {
let dbRef;
beforeAll(async () => {
const {db, admin} = require('../../../functions/helpers/setup');
dbRef = db;
});
afterAll(async () => {
await Promise.all(firebase.apps().map(app => app.delete()));
console.log(`View rule coverage information at ${COVERAGE_URL}\n`);
});
it('test', async () => {
const mockData = {
'Users/user1': {
uid: 'user1'
},
['Users/user1/Taxes/' + new Date().getFullYear().toString()]: {
totalExpenseEuro: 0
}
};
for (const key in mockData) {
const ref = dbRef.doc(key);
await ref.set(mockData[key]);
}
// Create mockup data
await dbRef.collection('Users').doc('user1').collection('Expenses').doc('expense1').set({
amountEuroInclVAT: 100
});
// Make snapshot for state of database beforehand
const beforeSnap = test.firestore.makeDocumentSnapshot({amountEuroInclVAT: 0}, 'Users/user1/Expenses/expense1');
// Make snapshot for state of database after the change
const afterSnap = test.firestore.makeDocumentSnapshot(
{amountEuroInclVAT: 100},
'Users/user1/Expenses/expense1'
);
const change = test.makeChange(beforeSnap, afterSnap);
// Call wrapped function with the Change object
const wrapped = test.wrap(calculateTaxesOnExpenseUpdate);
wrapped(change, {
params: {
uid: 'test1'
}
});
});
});
Now the main problem comes when I try to access this db object in my trigger
const calculateTaxesOnExpenseUpdate = functions.firestore
.document('Users/{uid}/Expenses/{expenseId}')
.onWrite(async (change, context) => {
const {getDb} = require('../helpers/setup'); // This setup is the same as above
let db = getDb();
...
For some reason when I perform an action like (await db.collection('Users').get()).get('totalExpenseEuro'), Jest stops executing my code. When I set a debugger right after that line, it never gets printed. That piece of code crashes, and I have no idea why. I think the DB instance if not properly configured in my cloud trigger function.
Question: What is a good way of sharing the DB instance (admin.firestore()) between the test and the cloud trigger functions?

Cloud Function to export new documents from Firestore to GCP bucket

I am trying to write a cloud function to export only the new documents getting added to my 'reviews' sub-collection. The trigger for this cloud function is: Cloud Firestore. However, my cloud function deployment fails through the console. Could someone please help me understand what's wrong with my cloud function?
Error message:
Deployment failure:
Build failed: /workspace/index.js:26
}
^
SyntaxError: missing ) after argument list
at new Script (vm.js:83:7)
at checkScriptSyntax (internal/bootstrap/node.js:620:5)
at startup (internal/bootstrap/node.js:280:11)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3); Error ID: d984e68f
Cloud function code:
const firestore = require('#google-cloud/firestore');
const client = new firestore.v1.FirestoreAdminClient();
const bucket = 'gs://bucket_name'
exports.scheduledFirestoreBackup = (event, context) => {
const databaseName = client.databasePath(
// process.env.GCLOUD_PROJECT,
"fs124",
'(default)'
);
return client
.exportDocuments({
name: databaseName,
outputUriPrefix: bucket,
collectionIds: ['reviews'],
})
.onSnapshot()
.then(snap => {
snap.forEach(doc => {
const response = doc.data();
console.log(doc.data());
return response;
}
});
Console snippet:
The message you are getting, SyntaxError: missing ) after argument list is pretty clear. You are missing the closing curly bracket} and parenthesis) of then(). It should look something like this:
const firestore = require('#google-cloud/firestore');
const client = new firestore.v1.FirestoreAdminClient();
const bucket = 'gs://bucket_name'
exports.scheduledFirestoreBackup = (event, context) => {
const databaseName = client.databasePath(
// process.env.GCLOUD_PROJECT,
"fs124",
'(default)'
);
return client
.exportDocuments({
name: databaseName,
outputUriPrefix: bucket,
collectionIds: ['reviews'],
})
.onSnapshot()
.then(snap => {
snap.forEach(doc => {
const response = doc.data();
console.log(doc.data());
return response;
});
});
};

Categories

Resources