Releases: LimeChain/matchstick
v0.6.0
What's Changed
- Bump deps and fix clippy issues. by @axiomatic-aardvark in #382
- Implement
loadInBlock
method by @arrusev in #398 - Implement
loadRelated
method by @arrusev in #399 - Add
logEntity
function by @arrusev in #405 - feat: Make possible to test and log dynamic datasources by @dimitrovmaksim in #406
- feat: Add asserts with custom messages by @dimitrovmaksim in #408
- Add ipfs data source by @arrusev in #409
- Refactor: code improvements by @arrusev in #411
- feat: Support derivedFrom with Interfaces by @dimitrovmaksim in #413
- Version 0.6.0 by @dimitrovmaksim in #407
Breaking Changes:
It seems there's an issue with the -m1
binaries, where the binary will encounter memory error when tests fail. Either use rosetta or run matchstick using docker. When using the graph-cli
, you can use the -d
flag with the graph test
command to run matchstick with docker, e.g. graph test -d
Requires matcshtick-as
0.6.0
Dropped support for MacOs 10.15 - Action runner deprecated
Dropped support for Ubuntu 18.04 - Action runner deprecated
Dropped support for Ubuntu 20.04 - Issues with building graph-node dependencies
Changed handling derived fields
Looking up derived entities will no longer be possible by directly calling the derived field of the entity , e.g. entity.derived_field
, and they will not be present when logging the store with logStore()
.
To load the derived entities in your tests, you will need to use loadRelated, e.g. entity.derived_field.load()
. To log the derived entities we have introduced a new function logEntity(entity: string, id: string, showRelated: boolean)
which will load the parent entity and optionally can be called to load the related entities, similarly how queries return the derived fields.
Added support for loadRelated
Previously it was possible to get the derived entities by accessing them as Entity fields/properties
let entity = ExampleEntity.load("id")
let derivedEntity = entity.derived_entity
This was causing a lot of issues, because we had to track and save all entity change into our store. With adding Bytes as possible type. for the entity ID, things became even more complicated. With graph-node adding loadRelated
we decided take a more graph-node
approach. Derived fields actually do not exists in the Store/Database and are dynamically collected when you perform a query or use loadRelated
. Now with the added support for loadRelated
you can get the derived entities the same way you would do in your handlers.
let entity = ExampleEntity.load("id")
let derivedEntities = entity.derived_entities.load()
logEntity
Due to the changes to how we handle the derived fields (we are trying to be as close to graph-node as possible), logStore
will no longer print the derived fields. For that reason we added another function logEntity(entity: string, id: string, showRelated: boolean)
which takes the Entity type, entity id and showRelated boolean argument to indicate if we want to print the related derived entities.
Added support for loadInBlock
By default loadInBlock
will return null
. We have introduced mockInBlockStore
that will allow users to mock entities into the block cache.
import { afterAll, beforeAll, describe, mockInBlockStore, test } from "matchstick-as"
import { Gravatar } from "../../generated/schema"
describe("loadInBlock", () => {
beforeAll(() => {
let gravatar = new Gravatar("gravatarId0")
gravatar.displayName = "Gravatar 0"
gravatar.owner = Address.fromString("0x90cBa2Bbb19ecc291A12066Fd8329D65FA1f1947")
gravatar.imageUrl = "https://example.com/gravatarId0.png"
mockInBlockStore("Gravatar", "gravatarId0", gravatar);
})
afterAll(() => {
clearInBlockStore()
})
test("Can use entity.loadInBlock() to retrieve entity from cache store in the current block", () => {
let retrievedGravatar = Gravatar.loadInBlock("gravatarId0")
assert.stringEquals("gravatarId0", retrievedGravatar!.get("id")!.toString())
})
test("Returns null when calling entity.loadInBlock() if an entity doesn't exist in the current block", () => {
let retrievedGravatar = Gravatar.loadInBlock("IDoNotExist")
assert.assertNull(retrievedGravatar)
})
})
Added support for dynamic DataSource creation testing
It is now possible to test if a new DataSource has been created from a template. It supports both ethereum/contract
and file/ipfs
templates. We added four new functions:
assert.dataSourceCount(templateName, expectedCount)
- assert the expected count of DataSources from the specified template
assert.dataSourceExists(templateName, address/ipfsHash)
- assert that a DataSource with the specified identifier (could be a contract address or IPFS file hash) from a specified template was created
logDataSources(templateName)
- Print all DataSources from the specified template to the console for debugging purposes.
readFile(path)
- Function that reads a json file that represents an IPFS file and returns the content as Bytes
Testing ethereum/contract
templates
test("ethereum/contract dataSource creation example", () => {
// Assert there are no dataSources created from GraphTokenLockWallet template
assert.dataSourceCount("GraphTokenLockWallet", 0);
// Create a new GraphTokenLockWallet datasource with address 0xA16081F360e3847006dB660bae1c6d1b2e17eC2A
GraphTokenLockWallet.create(Address.fromString("0xA16081F360e3847006dB660bae1c6d1b2e17eC2A"));
// Assert the dataSource has been created
assert.dataSourceCount("GraphTokenLockWallet", 1);
// Add a second dataSource with context
let context = new DataSourceContext()
context.set("contextVal", Value.fromI32(325))
GraphTokenLockWallet.createWithContext(Address.fromString("0xA16081F360e3847006dB660bae1c6d1b2e17eC2B"), context);
// Assert there are now 2 dataSources
assert.dataSourceCount("GraphTokenLockWallet", 2);
// Assert that a dataSource with address "0xA16081F360e3847006dB660bae1c6d1b2e17eC2B" was created
// Keep in mind that `Address` type is transformed to lower case when decoded, so you have to pass the address as all lower case when asserting if it exists
assert.dataSourceExists("GraphTokenLockWallet", "0xA16081F360e3847006dB660bae1c6d1b2e17eC2B".toLowerCase());
logDataSources("GraphTokenLockWallet");
})
logDataSource:
🛠 {
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a": {
"kind": "ethereum/contract",
"name": "GraphTokenLockWallet",
"address": "0xa16081f360e3847006db660bae1c6d1b2e17ec2a",
"context": null
},
"0xa16081f360e3847006db660bae1c6d1b2e17ec2b": {
"kind": "ethereum/contract",
"name": "GraphTokenLockWallet",
"address": "0xa16081f360e3847006db660bae1c6d1b2e17ec2b",
"context": {
"contextVal": {
"type": "Int",
"data": 325
}
}
}
}
Testing file/ipfs
templates
Similarly to contract dynamic DataSources it is now possible to test File DataSources and their handlers
subgraph.yaml
:
...
templates:
- kind: file/ipfs
name: GraphTokenLockMetadata
network: mainnet
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
file: ./src/token-lock-wallet.ts
handler: handleMetadata
entities:
- TokenLockMetadata
abis:
- name: GraphTokenLockWallet
file: ./abis/GraphTokenLockWallet.json
schema.graphql
:
"""
Token Lock Wallets which hold locked GRT
"""
type TokenLockMetadata @entity {
"The address of the token lock wallet"
id: ID!
"Start time of the release schedule"
startTime: BigInt!
"End time of the release schedule"
endTime: BigInt!
"Number of periods between start time and end time"
periods: BigInt!
"Time when the releases start"
releaseStartTime: BigInt!
}
metadata.json
{
"startTime": 1,
"endTime": 1,
"periods": 1,
"releaseStartTime": 1
}
./src/token-lock-wallet.ts
:
export function handleMetadata(content: Bytes): void {
// dataSource.stringParams() returns the File DataSource CID
// stringParam() will be mocked in the handler test
// for more info https://thegraph.com/docs/en/developing/creating-a-subgraph/#create-a-new-handler-to-process-files
let tokenMetadata = new TokenLockMetadata(dataSource.stringParam());
const value = json.fromBytes(content).toObject()
if (value) {
const startTime = value.get('startTime')
const endTime = value.get('endTime')
const periods = value.get('periods')
const releaseStartTime = value.get('releaseStartTime')
if (startTime && endTime && periods && releaseStartTime) {
tokenMetadata.startTime = startTime.toBigInt()
tokenMetadata.endTime = endTime.toBigInt()
tokenMetadata.periods = periods.toBigInt()
tokenMetadata.releaseStartTime = releaseStartTime.toBigInt()
}
tokenMetadata.save()
}
}
./tests/token-lock-wallet.test.ts
:
import { assert, test, dataSo...
v0.6.0-rc.3
What's Changed
- Bump deps and fix clippy issues. by @axiomatic-aardvark in #382
- Implement
loadInBlock
method by @arrusev in #398 - Implement
loadRelated
method by @arrusev in #399 - Add
logEntity
function by @arrusev in #405 - feat: Make possible to test and log dynamic datasources by @dimitrovmaksim in #406
- feat: Add asserts with custom messages by @dimitrovmaksim in #408
- Add ipfs data source by @arrusev in #409
- Refactor: code improvements by @arrusev in #411
- feat: Support
derivedFrom
withInterfaces
by @arrusev and @dimitrovmaksim in #413
New Contributors
Full Changelog: 0.5.4...0.6.0-rc.3
v0.6.0-rc.2
What's Changed
- Bump deps and fix clippy issues. by @axiomatic-aardvark in #382
- Implement
loadInBlock
method by @arrusev in #398 - Implement
loadRelated
method by @arrusev in #399 - Add
logEntity
function by @arrusev in #405 - feat: Make possible to test and log dynamic datasources by @dimitrovmaksim in #406
- feat: Add asserts with custom messages by @dimitrovmaksim in #408
- Add ipfs data source by @arrusev in #409
- Refactor: code improvements by @arrusev in #411
New Contributors
Full Changelog: 0.5.4...0.6.0-rc.2
v0.6.0-rc.1
What's Changed
- Bump deps and fix clippy issues. by @axiomatic-aardvark in #382
- Implement
loadInBlock
method by @arrusev in #398 - Implement
loadRelated
method by @arrusev in #399 - Add
logEntity
function by @arrusev in #405 - feat: Make possible to test and log dynamic datasources by @dimitrovmaksim in #406
- feat: Add asserts with custom messages by @dimitrovmaksim in #408
- Add ipfs data source by @arrusev in #409
New Contributors
Full Changelog: 0.5.4...0.6.0-rc.1
v0.6.0-beta5
Add ipfs data source (#409) * feat: add ipfs data source Signed-off-by: Anton Rusev <anton.rusev@limechain.tech> * chore: fix fmt and clippy Signed-off-by: Anton Rusev <anton.rusev@limechain.tech> --------- Signed-off-by: Anton Rusev <anton.rusev@limechain.tech>
v0.6.0-beta4
What's Changed
- Bump deps and fix clippy issues. by @axiomatic-aardvark in #382
- Implement
loadInBlock
method by @arrusev in #398 - Implement
loadRelated
method by @arrusev in #399 - Add
logEntity
function by @arrusev in #405 - feat: Make possible to test and log dynamic datasources by @dimitrovmaksim in #406
New Contributors
Full Changelog: 0.5.4...0.6.0-beta4
v0.6.0-beta3
Add custom messages to asserts Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
v0.6.0-beta2
Fix missing child entities when id is Bytes Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
v0.6.0-beta1
Fix derved fields with bytes IDs Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
v0.5.5-rc3
Fix missing backtrace, silence panic Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>