Getting error 'variant constructor can't be found' while compiling - reason

I was trying out use a sortable list component (react-sortable-hoc) on a ReasonReact project. But I ran into an error which I was trying to figure out for couple of hours.
Steps I followed:
made the #bs binds for sortableContainer() and sortableElement() for the module react-sortable-hoc
faked the reactClass returned by the both functions and put it under file SortableContainer.js and SortableElement.js
Made an another React component called Todolist which use the component SortableContainer, and SortableContainer use the component SortableElement.
Code Snippet
/* SortableContainer.re */
[#bs.val] [#bs.module "react-sortable-hoc"] external sortableContainer : 'a =>
ReasonReact.reactClass = "";
let sortableContainerReactClass: ReasonReact.reactClass = sortableContainer(() => {
(ReasonReact.createElement(SortableElement))
});
let make = (children) =>
ReasonReact.wrapJsForReason(
~reactClass=sortableContainerReactClass,
~props = { "onSortEnd": () => {} },
children
);
/* SortableElement.re */
[#bs.val] [#bs.module "react-sortable-hoc"] external sortableElement : 'a =>
ReasonReact.reactClass = "";
let sortableElementReactClass: ReasonReact.reactClass = sortableElement(() => {
(ReasonReact.stringToElement("testing is good"))
});
let make = (children) =>
ReasonReact.wrapJsForReason(
~reactClass=sortableElementReactClass,
~props = { "onSortEnd": () => {} },
children
);
/* List.re */
let component = ReasonReact.statelessComponent("List");
let make = (~items=[||], _children) => {
{
...component,
render: (_self) => {
}
}
};
When I compile this code I get this error.
# ERROR
We've found a bug for you!
/Users/jaisonjustus/code/todotabre/src/components/SortableContainer.re 5:34-48
3 │
4 │ let sortableContainerReactClass: ReasonReact.reactClass = sortableConta
iner(() => {
5 │ (ReasonReact.createElement(SortableElement))
6 │ });
7 │
The variant constructor SortableElement can't be found.
- If it's defined in another module or file, bring it into scope by:
- Annotating it with said module name: let food = MyModule.Apple
- Or specifying its type: let food: MyModule.fruit = Apple
- Constructors and modules are both capitalized. Did you want the latter?
Then instead of let foo = Bar, try module Foo = Bar.
What's wrong in this code?

Related

I am developing VS Code extension and I need to capture the call stack records and log the result

I am writing a simple VS Code extension that suppose to just log the call stack in the console at specific point while debugging a code.
I was able to write a code to retrieve the current session of debugging, the break points and things like this, but I failed to find any property or method to allow me retrieve the call stack records.
This is the code I wrote:
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "sampleextension1" is now active!');
let disposable = vscode.commands.registerCommand('sampleextension1.hello', () => {
vscode.window.showInformationMessage('Hello World from sampleextension1!');
vscode.commands.executeCommand('editor.action.addCommentLine');
vscode.debug.onDidStartDebugSession(x => {
});
vscode.debug.onDidChangeActiveDebugSession(c => {
var b = vscode.debug.breakpoints[0];
});
});
context.subscriptions.push(disposable);
}
As you see in the code, there is an event handler for onDidChangeActiveDebugSession which enables me to capture the session of the debugging but no chance to find how to capture the stack trace.
I went through the documentation but it's not helpful though.
I was able to achieve what I want by sending a CutomRequest to the debugging session to retrieve the stack frames.
More information could be found in the DAP page here
The code is as shown below:
x.customRequest('stackTrace', { threadId: 1 }).then(reply => {
const frameId = reply.stackFrames[0].id;
}, error => {
vscode.window.showInformationMessage(`error: ${error.message}`);
});
or more efficient is to register tracker as shown below:
vscode.debug.registerDebugAdapterTrackerFactory('*', {
createDebugAdapterTracker(session: vscode.DebugSession) {
return {
onWillReceiveMessage: m => console.log(`> ${JSON.stringify(m, undefined, 2)}`),
onDidSendMessage: m => console.log(`< ${JSON.stringify(m, undefined, 2)}`)
};
}
});
The full example is shown here:
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "sampleextension1" is now active!');
let disposable = vscode.commands.registerCommand('sampleextension1.hello', () => {
vscode.window.showInformationMessage('Hello World from sampleextension1!');
vscode.commands.executeCommand('editor.action.addCommentLine');
vscode.debug.onDidStartDebugSession(x => {
// x.customRequest("evaluate", {
// "expression": "Math.sqrt(10)"
// }).then(reply => {
// vscode.window.showInformationMessage(`result: ${reply.result}`);
// }, error => {
// vscode.window.showInformationMessage(`error: ${error.message}`);
// });
x.customRequest('stackTrace', { threadId: 1 }).then(reply => {
const frameId = reply.stackFrames[0].id;
}, error => {
vscode.window.showInformationMessage(`error: ${error.message}`);
});
});
vscode.debug.onDidChangeActiveDebugSession(c => {
var b = vscode.debug.breakpoints[0];
});
vscode.debug.registerDebugAdapterTrackerFactory('*', {
createDebugAdapterTracker(session: vscode.DebugSession) {
return {
onWillReceiveMessage: m => console.log(`> ${JSON.stringify(m, undefined, 2)}`),
onDidSendMessage: m => console.log(`< ${JSON.stringify(m, undefined, 2)}`)
};
}
});
});
Steps to run:
F5 to run the Extension Dev Environment.
Ctl+Shift+P then write your cmd, in my case it was Hello
Then F5 to start the debugging in the Dev Environment then you will be able to see the result.
Hope it helps

Mochawesome with Cypress - how to get aggregated charts at higher level?

I've just started using mochawesome with Cypress (9.7). Our test structure is basically a number of spec files, each following something like the following format:
describe('(A): description of this spec', () => {
describe ('(B): description of test abc', () => {
before(() => {
// do specific set up bits for this test
})
it('(C): runs test abc', () => {
// do actual test stuff
})
})
})
Where within each spec file there would be a single 'A' describe block, but there can be many 'B' level blocks (each with a single 'C') - done this way because the before block for each 'C' is always different - I couldn't use a beforeEach.
When I run my various spec files, each structured similarly to the above, the mochaewsome output is mostly correct - I get a collapsible block for each spec file at level 'A', each with multiple collapsible blocks at level B, each with test info as expected at level C.
But... The circular charts are only displayed at level B. What I was hoping, was that it might be possible to have aggregated charts at level A, and a further aggregated chart for all the level A blocks.
Not sure I've explained this brilliantly(!), but hopefully someone understands, and can offer a suggestion?!
In cypress-mochawesome-reporter there's an alternative setup using on('after:run') which can perform the aggregation.
In Cypress v9.7.0
// cypress/plugins/index.js
const { beforeRunHook, afterRunHook } = require('cypress-mochawesome-reporter/lib');
const { aggregateResults } = require('./aggregate-mochawesome-report-chart');
module.exports = (on, config) => {
on('before:run', async (details) => {
await beforeRunHook(details);
});
on('after:run', async () => {
aggregateResults(config)
await afterRunHook();
});
};
In Cypress v10+
// cypress.config.js
const { defineConfig } = require('cypress');
const { beforeRunHook, afterRunHook } = require('cypress-mochawesome-reporter/lib');
const { aggregateResults } = require('./aggregate-mochawesome-report-chart');
module.exports = defineConfig({
reporter: 'cypress-mochawesome-reporter',
video: false,
retries: 1,
reporterOptions: {
reportDir: 'test-report',
charts: true,
reportPageTitle: 'custom-title',
embeddedScreenshots: true,
inlineAssets: false,
saveAllAttempts: false,
saveJson: true
},
e2e: {
setupNodeEvents(on, config) {
on('before:run', async (details) => {
await beforeRunHook(details);
});
on('after:run', async () => {
aggregateResults(config)
await afterRunHook();
});
},
},
});
The module to do the aggregation is
// aggregate-mochawesome-reporter-chart.js
const path = require('path');
const fs = require('fs-extra')
function aggregateResults(config) {
const jsonPath = path.join(config.reporterOptions.reportDir , '/.jsons', '\mochawesome.json');
const report = fs.readJsonSync(jsonPath)
const topSuite = report.results[0].suites[0]
aggregate(topSuite)
fs.writeJsonSync(jsonPath, report)
}
function aggregate(suite, level = 0) {
const childSuites = suite.suites.map(child => aggregate(child, ++level))
suite.passes = suite.passes.concat(childSuites.map(child => child.passes)).flat()
suite.failures = suite.failures.concat(childSuites.map(child => child.failures)).flat()
suite.pending = suite.pending.concat(childSuites.map(child => child.pending)).flat()
suite.skipped = suite.skipped.concat(childSuites.map(child => child.skipped)).flat()
if (!suite.tests.length && suite.suites[0].tests.length) {
// trigger chart when to describe has no tests
suite.tests = [
{
"title": "Aggregate of tests",
"duration": 20,
"pass": true,
"context": null,
"err": {},
"uuid": "0",
"parentUUID": suite.uuid,
},
]
}
return suite
}
module.exports = {
aggregateResults
}
The function aggregate() recursively loops down through child suites and adds the test results to the parent.
json files
Note the json file is different at the point where afterRunHook runs and at the end of the test run.
If you have the option saveJson: true set, you will get a final json file in the report directory called index.json.
At the afterRunHook stage the file is mochawesome.json.
Before aggregation
After aggregation

received error message when using component

I am creating a website using ReasonReact, but I encounter this error message when using a normal component. Does anyone know what is happening?
module Component1 = {
let component = ReasonReact.statelessComponent("Component1");
let make = () => {...component, render: self => <div />};
};
module Component2 = {
let component = ReasonReact.statelessComponent("Component1");
let make = () => {
...component,
render: self => <div> <Component1 /></div>, /*error on compenent1*/
};
Here is the error message:
(
React.component('props),
'props
) => React.element
<root>/node_modules/reason-react/src/React.re
Error: This expression has type
unit =>
ReasonReact.componentSpec(ReasonReact.stateless,
ReasonReact.stateless,
ReasonReact.noRetainedProps,
ReasonReact.noRetainedProps,
ReasonReact.actionless)
but an expression was expected of type
React.component(unit) = unit => React.element
Type
ReasonReact.componentSpec(ReasonReact.stateless,
ReasonReact.stateless,
ReasonReact.noRetainedProps,
ReasonReact.noRetainedProps,
ReasonReact.actionless)
is not compatible with type React.element
The problem seems to be that you're using a project configured to use JSX version 3 with components designed for JSX version 2.
JSX version 3 was introduced in ReasonReact 0.7.0, along with a new method for defining react components that supports hooks, but still supports the method you're using as long as you configure your project to use JSX version 2. If this is a new project, which it seems to be, I would recommend using the new component style, where your code would simply look like this:
module Component1 = {
[#react.component]
let make = () =>
<div />;
};
module Component2 = {
[#react.component]
let make = () =>
<div> <Component1 /> </div>;
};
Alternatively, you can continue using the old style of components and JSX version 2 by specifying the following in bsconfig.json:
{
...
"reason": {"react-jsx": 2}
}
See the blog post on ReasonReact 0.7.0 for more details.

ionic error when trying to run with ionic serve

I've downloaded a repository from Git to make amendments to it however, I can't seem to compile it and make it run.
I was prompted to install node modules, #ionic/cli-pl
ugin-gulp and also #ionic/cli-plugin-ionic1 as this was an ionic1 based project.
I keep receiving this error:
C:\Users\User1\Desktop\belfastsalah-master\belfastsalah-master\node_modules\#ionic\cli-plugin-ionic1\dist\serve\live-reload.js:19
let contentStr = content.toString();
^
TypeError: Cannot read property 'toString' of undefined
at Object.injectLiveReloadScript (C:\Users\User1\Desktop\belfastsalah-master\belfastsalah-master\node_modules\#ionic\cli-plugin-ionic1\dist\serve\live-reload.js:19:29)
at ReadFileContext.fs.readFile [as callback] (C:\Users\User1\Desktop\belfastsalah-master\belfastsalah-master\node_modules\#ionic\cli-plugin-ionic1\dist\serve\http-server.js:59:39)
at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:366:13)
Below is the code from the JS file the error appears in however, this hasn't been modified by me. It is what I was prompted to install as stated above.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const modules_1 = require("../lib/modules");
function createLiveReloadServer(options) {
const tinylr = modules_1.load('tiny-lr');
const liveReloadServer = tinylr();
liveReloadServer.listen(options.livereloadPort, options.address);
return (changedFiles) => {
liveReloadServer.changed({
body: {
files: changedFiles.map(changedFile => ('/' + path.relative(options.wwwDir, changedFile)))
}
});
};
}
exports.createLiveReloadServer = createLiveReloadServer;
function injectLiveReloadScript(content, host, port) {
let contentStr = content.toString();
const liveReloadScript = getLiveReloadScript(host, port);
if (contentStr.indexOf('/livereload.js') > -1) {
return content;
}
let match = contentStr.match(/<\/body>(?![\s\S]*<\/body>)/i);
if (!match) {
match = contentStr.match(/<\/html>(?![\s\S]*<\/html>)/i);
}
if (match) {
contentStr = contentStr.replace(match[0], `${liveReloadScript}\n${match[0]}`);
}
else {
contentStr += liveReloadScript;
}
return contentStr;
}
exports.injectLiveReloadScript = injectLiveReloadScript;
function getLiveReloadScript(host, port) {
if (host === '0.0.0.0') {
host = 'localhost';
}
const src = `//${host}:${port}/livereload.js?snipver=1`;
return ` <!-- Ionic Dev Server: Injected LiveReload Script -->\n` + ` <script src="${src}" async="" defer=""></script>`;
}
Any help would be greatly appreciated.
Thanks
You should check if, after all bundling/generation is done, www/index.html exists
Had this problem after extensive experiments with index.html generation what resulted with it being gone ;)

jupyter-js-services - how to save notebook

I'm trying to use jupyter as a backend for my system and now I play with examples from jupyter-js-api docs.
Using IKernel and INotebookSession I managed to execute simple code and get the response form kernel.
But I can's figure out how to extract the notebook itself. there's nothing like "saveNotebook()" in API. I try to execute session.renameNotebook(), it completes successfully, but no files appear in filesystem (tried different paths like "/tmp/trynote.ipynb" "trynote.ipnb" and so on...).
Here's the code, it is slightly edited example from http://jupyter.org/jupyter-js-services/ page
#!/usr/bin/env node
var jpt = require("jupyter-js-services");
var xr = require("xmlhttprequest");
var ws = require("ws");
global.XMLHttpRequest = xr.XMLHttpRequest;
global.WebSocket = ws;
// start a new session
var options = {
baseUrl: 'http://localhost:8889',
wsUrl: 'ws://localhost:8889',
kernelName: 'python',
notebookPath: 'trynote.ipynb'
};
jpt.startNewSession(options).then((session) => {
// execute and handle replies on the kernel
var future = session.kernel.execute({ code: 'print(5 * 5);' });
future.onDone = (msg) => {
console.log('Future is fulfilled: ');
console.log(msg);
};
future.onIOPub = (msg) => {
console.log("Message in IOPub: ");
console.log(msg);
};
// rename the notebook
session.renameNotebook('trynote2.ipynb').then(() => {
console.log('Notebook renamed to', session.notebookPath);
});
// register a callback for when the session dies
session.sessionDied.connect(() => {
console.log('session died');
});
// kill the session
session.shutdown().then(() => {
console.log('session closed');
});
});
Looking and ContentManager API it seems to work with already existing files, or creating new ones, but its unclear how is it bound to sessions.
More, even simplest try to use "newUntitled" function gives 404 response...
var contents = new jpt.ContentsManager('http://localhost:8889');
// create a new python file
contents.newUntitled("foo", { type: "file", ext: "py" }).then(
(model) => {
console.log(model.path);
}
);
I feel a bit disoriented with all this and would appreciate any explanations.
Thanks..