How to make 'testPattern' mandatory while updating snapshots in Jest? - jestjs

Snapshot testing comes handy for testing UI components. If your UI component changes, you are expected to update the snapshot as well to reflect the same. We can specify 'testNamePattern' to update snapshots for a specific test.
jest --updateSnapshot --testNamePattern abc.test.js
Is it possible to mandate 'testNamePattern' while updating snapshots? This will help avoid updating other failing snapshots by mistake. I understand that it is expected to be caught in code review phase. However, I want to ensure that snapshots are always updated for a specific pattern.

As of now, there isn't any CLI option for doing this per doc. I have added a small snippet to my testFrameworkScriptFile to ensure that testNamePattern is passed while updating snapshots.
import yargs from 'yargs';
const mandateTestNamePattern = () => {
const args = yargs.option('testNamePattern', {
type: 'string'
}).option('t', {
type: 'string'
}).argv;
if (args.updateSnapshot || args.u) {
if (args.testNamePattern || args.t) {
// valid case
} else {
throw new Error('TestNamePattern is mandatory while updating snapshots');
}
}
};
mandateTestNamePattern();

Related

Ambiguos "Error: NEXUS__UNKNOWN__TYPE was already defined and imported as a type" error in nexus graphql

I'm getting the following error when using nexus to define a graphql schema with apollo-server.
Error: NEXUS__UNKNOWN__TYPE was already defined and imported as a type
The stacktrace doesn't give much information as to where the issue is occurring or to what the problem is. The project has 20+ models and dozens of resolvers so it's quite hard to debug.
Error: NEXUS__UNKNOWN__TYPE was already defined and imported as a type, check the docs for extending types
at extendError (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1744:2)
at SchemaBuilder.addType (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:603:8)
at SchemaBuilder.missingType (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1212:5)
at SchemaBuilder.getOrBuildType (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1540:4)
at SchemaBuilder.getOutputType (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1471:10)
at SchemaBuilder.buildOutputField (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1349:52)
at /Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1307:7
at Array.forEach (<anonymous>)
at SchemaBuilder.buildOutputFields (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1306:7)
at fields (/Users/username/Documents/folder/folder/graphq-nexus-prisma-api/node_modules/nexus/src/builder.ts:1009:33)
Any help appreciated.
I got the same error, but it was because I removed some exports. I'm not exactly sure what caused it, but I basically have a file that exports all of my graphql modules. E.g.
// graphql/modules/index.ts
export * from './file-a';
export * from './file-b';
When I removed the second export line, I started getting the error. I'm probably using some of the types defined in file-b somewhere else, and that's somehow causing the error. Anyway, adding the line back in fixed it (I had removed it by accident anyway).
UPDATE
I also go this by referencing some arg types that didn't exist (typo). For example:
args: {
where: arg({ type: 'ConversationsWhereInput' }),
orderBy: arg({ type: 'ConversationsOrderByInput', list: true }),
},
The s in Conversations shouldn't be there. It should be:
args: {
where: arg({ type: 'ConversationWhereInput' }),
orderBy: arg({ type: 'ConversationOrderByInput', list: true }),
},
It could have been much helpful if you could elaborate what did you do before this error happened.
I just came up with this error exactly as same as what you got and for me it was because I just accidentally changed the name for objectType of typeDef.
For instance, the name for the FollowUserResult was actually FollowResult and after I changed the name, the whole mutation resolvers related to this objectType became wrong.
export const FollowUserResult = objectType({
name: "FollowUserResult", // It was originally "FollowResult"
definition(t) {
t.nonNull.boolean("ok");
t.string("error");
},
});
You may check on this again. Once you got those correct, delete the schema.graphql file and generate the new schema.graphql file.
I got this error because I was using the incorrect Node version. My project didn't have a .nvrmc file (yet) so I was using Node 10 on a project that uses Node 14. So after switching to the correct Node version this error went away
I got this error when I incorrectly specified an unknown type in the type attribute of an extension to the Query type. More specifically:
export const CoursesQuery = extendType({
type: "Query",
definition(t) {
t.field("myQuery", {
type: InvalidType, // <--- Changing InvalidType to the correct type fixed the error
async resolve(_parent, _args, ctx) {
return ...
},
});
},
});
The error disappeared after I changed InvalidType to the correct type and restarted the server.

Apply node module with object prototype methods

Good morning.
I'm trying to create a node module witch right now is published as redgem.
It consists of adding methods to base objects prototypes. For example:
const obj = { a: 'b', c: 'd' }
obj.map(do stuff)
However i haven't found a good way to apply these methods in a project. If i run the tests (they are inside the module) they all run smoothly since methods are added to base objects (arrays, strings and actual objects). But if i do the same thing in another project i get errors like Uncaught TypeError: Illegal invocation.
Could anyone please help me setup the package?
The way i'm trying to use redgem in projects right now is:
import redgem from 'redgem';
redgem():
Thanks.
So, basically this is how i export the module:
export default function apply () {
stringMethods.forEach((method) => {
String.prototype[method.name] = method.function
})
arrayMethods.forEach((method) => {
Array.prototype[method.name] = method.function
})
objectMethods.forEach((method) => {
Object.prototype[method.name] = method.function
})
}
Where every method is in the following form
{
// Tells wether the array is empty.
name: 'empty',
function: function () {
return this.length == 0
}
}

How to develop an Import/Export Functionality for my node application

I have a configuration application in Nodejs. It has a Component with name and uuid. A Component can have many Schemas. A Schema has a uuid, name, componentId, json. A Schema can have many Configurations. A Configuration has name, schemaId, json and uuid. A Schema can contain reference of many other Schemas in it. Now I want to create a functionality of exporting all the data from one instance of the application and import it in another. What should be the simplest way to do it? a few questions are
How to tell application what to export. for now i think there should be separate arrays for components, schemas and configurations. Like
{
components: ['id1', 'id2'],
schemas: ['s1', 's2'],
configuration: ['c1', 'c2'],
}
this data should be sent to application to return a file with all information that will later be used for importing in another instance
The real question is how should my export file look like keeping in mind that dependencies are also involved and dependencies can also overlap. for example a schema can have many other schemas referenced in its json field. eg schema1 has schema2 and schema4 as its dependencies. so there is another schema schema5 that also require schema2. so while importing we have to make sure that schema2 should be saved first before saving schema1 and schema5. how to represent such file that requires order as well as overlapped dependencies, making sure that schema2 is not saved twice while importing. json of schema1 is shown below as an example
{
"$schema": "http://json-schema.org/draft-04/schema#",
"p1": {
"$ref": "link-to-schema2"
},
"p2": {
"$ref": "link-to-schema4"
},
}
What should be the step wise sudo algorithm i should follow while importing.
This is a perfect occasion for a topological sort.
Taking away components, schemas and configurations terminology, what you have is objects (of various kinds) which depend on other objects existing first. A topological sort will create an order that has only forward dependencies (assuming you don't have circular ones, in which case it is impossible).
But the complication is that you have dependency information in a mix of directions. A component has to be created before its schema. A schema has to be created after the schemas that it depends on. It is not impossible that those schemas may belong to other components that have to be created as well.
The first step is to write a function that takes an object and returns a set of dependency relationships discoverable from the object itself. So we want dependencyRelations(object1 to give something like [[object1, object2], [object3, object1], [object1, object4]]. Where object1 depends on object2 existing. (Note, object1 will be in each pair but can be first or second.)
If every object has a method named uniqueName that uniquely identifies it then we can write a method that works something like this (apologies, all code was typed here and not tested, there are probably syntax errors but the idea is right):
function dependencyInfo (startingObject) {
const nameToObject = {};
const dependencyOf = {};
const todo = [startingObject];
const visited = {};
while (0 < todo.length) {
let obj = todo.pop();
let objName = obj.uniqueName();
if (! visited[ objName ]) {
visited[ objName ] = true;
nameToObject[objName] = obj;
dependencyRelations(obj).forEach((pair) => {
const [from, to] = pair;
// It is OK to put things in todo that are visited, we just don't process again.
todo.push(from);
todo.push(to);
if (! dependencyOf[from.uniqueName()]) {
dependencyOf[from.uniqueName()] = {}
}
dependencyOf[from.uniqueName()] = to.uniqueName();
});
}
}
return [nameToObject, dependencyOf];
}
This function will construct the dependency graph. But we still need to do a topological sort to get dependencies first.
function objectsInOrder (nameToObject, dependencyOf) {
const answer = [];
visited = {};
// Trick for a recursive function local to my environment.
let addObject = undefined;
addObject = function (objName) {
if (! visited[objName]) {
visited[objName] = true; // Only process once.
// Add dependencies
Object.keys(dependencyOf[objName]).forEach(addObject);
answer.push(nameToObject[objName]);
}
};
Object.keys(dependencyOf).forEach(addObject);
return answer;
}
And now we have an array of objects such that each depends on the previous ones only. Send that, and at the other end you just inflate each object in turn.

Botframework (Node) - dialogData stripping out regex

Does the BotBuilder Node SDK actively strip out anything that is stored the dialogData object?
For example, I have created a simple loop and I am storing a regex in session.dialogData.questions. When I console log this after storing it, I can see that my regex is stored as expected:
{
validation: /^[0-9]{19}$/,
}
However, when I try and log the same session.dialogData.questions object in the next step of my waterfall, then the regex seems to have been converted into an empty object:
{
validation: {}
}
I presume this a deliberate attempt to prevent XSS and other types of exploitation?
The code for this example can be found below:
const builder = require('botbuilder')
const lib = new builder.Library('FormBuilder')
lib.dialog('/', [
(session, args) => {
session.dialogData.questions = {
validation: /^[0-9]{19}$/
}
console.log(session.dialogData.questions)
builder.Prompts.confirm(session, 'Would you like to proceed?')
},
(session, results) => {
console.log(session.dialogData.questions)
}
])
module.exports.createLibrary = () => {
return lib.clone()
}
Regarding your initial question, no the SDK doesn't actively strip anything out of the dialogData object. Anything that is, except for regexp...
I'm not sure why this is, but for the time being I recommend storing your pattern as a string, '^[0-9]{19}$', and then constructing a new regexp via new RegExp(session.dialogData.questions.validation) when needed.
I tried storing a method to construct a new RegExp using this.questions.validation, but likewise this was also stripped out.
Edit:
Per Ezequiel's comment, this isn't a Bot Framework issue in the end. It is not possible to store non-serializable data inside JSON.

Changing anyMatch default for Filter.JS in ExtJS for MultiSelect search

I have a multiselect bound to a store in which I implemented use of anyMatch: true to allow for True to allow any match - no regex start/end line anchors will be added (as per the comment in Filter.js). My problem is that I need to implement this as per the answer to multiselect-search-whole-string, in particular the solution provided in this fiddle https://fiddle.sencha.com/#fiddle/jf5
What I want to do is just set anyMatch: true, regardless, so I set it in Filter.js, but this has no effect on use of it. I searched the entire codebase for other instances of anyMatch: false and the only other one is in ext-all-debug.js. Why isn't setting these values having any effect? I don't see where else this default value could be set?
EDIT 1
I tried a different override, and while it is not exhibiting the right behavior, it is actually doing something this time. I figured that since the chunk of code that does work when embedded in the search attribute within the MultiSelector control was pretty much what was found in the MultiSelectorSearch's search method, that this was what I needed to focus on for the override. Any suggestions on tweaking this would be most welcome:
Ext.define('Ext.overrides.view.MultiSelectorSearch', {
override: 'Ext.view.MultiSelectorSearch',
search: function (text, me) {
var filter = me.searchFilter,
filters = me.getSearchStore().getFilters();
if (text) {
filters.beginUpdate();
if (filter) {
filter.setValue(text);
} else {
me.searchFilter = filter = new Ext.util.Filter({
id: 'search',
property: me.field,
value: text,
anyMatch: true
});
}
filters.add(filter);
filters.endUpdate();
} else if (filter) {
filters.remove(filter);
}
}
});
EDIT 2
Got it! The key was that originally, since this code was embedded in a singleton, I could reference the method by passing me from the calling form.panel. This did not work globally as an override, and required me to define the method as
search: function (text) {
var me = this,
I hope this helps someone out there!
Changing in ext-all-debug.js is not safe, when you do a production build this file will not get included.
Best way is to override the Filter class, here is how you can do it.
Ext.define('Ext.overrides.util.Filter', {
override: 'Ext.util.Filter',
anyMatch: true
});
And import this class in Application.js
Ext.require([
'Ext.overrides.util.Filter'
]);

Resources