react-leaflet-draw edit control simulate onCreated using testing library - react-testing-library

I am trying to unit test onCreated event handler of the React-leaflet-draw's Edit control component using react testing library/jest.
I tried the following without any luck:
test('Polygon draw functionality', async () => {
const drawHandler = jest.fn();
const { getByText, getByTestId, getAllByTestId, queryAllByTestId } = render(
<Map
data={mapData}
onDraw={drawHandler}
></Map>,
{}
);
let e = document.createEvent('Event');
e.initEvent('click', true, true);
let cb = document.getElementsByClassName('leaflet-draw-draw-polygon');
cb[0].dispatchEvent(e);
expect(drawHandler).toHaveBeenCalled();
});
Map.js
...
<FeatureGroup>
<EditControl
position='topright'
onCreated={props.onDraw}
draw={{
polyline: false,
polygon: true,
rectangle: false,
circle: false,
marker: false,
circlemarker: false,
}}
/>
</FeatureGroup>
...
Is there any better way to programmatically trigger onCreated event?

Related

Vscode language server extension connection.onCompletion

I am creating a language server. Specifically, the issue is with completions. I'm returning a big list of completion items but whenever I test my language the completion provider simply will not suggest anything after I type a dot(.) when I'm expecting it to suggest, essentially, class members associated with the symbol left of said dot(.). Don't get me wrong, suggestions work until I type the dot(.) character and then it says, "No Suggestions".
Also, I'm trying to implement this server side and not client side.
EDIT:
Essentially, I'm assembling a big list and returning it.
connection.onInitialize((params: node.InitializeParams) => {
workspaceFolder = params.workspaceFolders![0].uri;
const capabilities = params.capabilities;
// Does the client support the `workspace/configuration` request?
// If not, we fall back using global settings.
hasConfigurationCapability = !!(
capabilities.workspace && !!capabilities.workspace.configuration
);
hasWorkspaceFolderCapability = !!(
capabilities.workspace && !!capabilities.workspace.workspaceFolders
);
hasDiagnosticRelatedInformationCapability = !!(
capabilities.textDocument &&
capabilities.textDocument.publishDiagnostics &&
capabilities.textDocument.publishDiagnostics.relatedInformation
);
capabilities.workspace!.workspaceEdit!.documentChanges = true;
const result: node.InitializeResult = {
capabilities: {
textDocumentSync: node.TextDocumentSyncKind.Incremental,
colorProvider: true,
hoverProvider: true,
definitionProvider: true,
typeDefinitionProvider: true,
referencesProvider: true,
documentHighlightProvider: true,
documentSymbolProvider: true,
workspaceSymbolProvider: true,
// codeActionProvider: true,
codeLensProvider: {
resolveProvider: true,
workDoneProgress: false
},
// Tell the client that this server supports code completion.
completionProvider: {
resolveProvider: true,
workDoneProgress: false,
triggerCharacters: ['.', '/'],
allCommitCharacters: ['.']
},
signatureHelpProvider: {
triggerCharacters: ['('],
retriggerCharacters: [','],
workDoneProgress: false
},
executeCommandProvider: {
commands: ["compile"],
workDoneProgress: false
},
semanticTokensProvider: {
documentSelector: [{ scheme: 'file', language: 'agc' }],
legend: {
tokenTypes: gTokenTypes,
tokenModifiers: gTokenModifiers
},
full: true,
workDoneProgress: false
}
}
};
if (hasWorkspaceFolderCapability) {
result.capabilities.workspace = {
workspaceFolders: {
supported: true
}
};
}
return result;
});
// This handler provides the initial list of the completion items.
connection.onCompletion(
async (params: node.TextDocumentPositionParams): Promise<node.CompletionItem[] | node.CompletionList | undefined> => {
console.log("completion");
let doc = documents.get(params.textDocument.uri);
let list:node.CompletionList = node.CompletionList.create([], true);
list.items = list.items.concat(comp.GetAGKKeywordCompletionItems(), comp.GetAGKCommandCompletionItems(), agkDocs.getALLCompletionItems());
list.items.push(sense.GetCommentSnippetCompletionItem(doc, params.position));
list.items.push(sense.GetCommentSnippetCompletionItem(doc, params.position, true));
console.log("END completion");
return list;
}
);

How can i prevent popup to be closed when i have fitSelectedRoutes:true options selected in the routingControl

I am using leaflet and leaflet routing machine control libraries.
When i am creating some route path i have the folllowing code:
this.routingControl = L['Routing'].control({
router: L['Routing'].osrmv1({
serviceUrl: `http://router.project-osrm.org/route/v1/`,
language: 'en',
profile: 'car'
}),
showAlternatives: false,
lineOptions: { styles: [{ color: '#4caf50', weight: 7 }] },
fitSelectedRoutes: true,
altLineOptions: { styles: [{ color: '#ed6852', weight: 7 }] },
show: false,
routeWhileDragging: true,
addWaypoints: false,
waypoints: [
L.latLng(clickedLat, clickedLng),
L.latLng(this.selectedCityZipCodeObject.longitude, this.selectedCityZipCodeObject.latitude)
],
createMarker: function (i: number, waypoint: any, n: number) {
return null;
}
});
Note: if i have
fitSelectedRoutes:false
then when i click on some marker,which should make route path until other marker the pop up is showed.
But if i have
fitSelectedRoutes:true
then when i click on the marker it show the popup. but the map zoom is changed to fit the route path in the center between the markers and i have smaller zoom which is done automatic from the library.
And then my pop up is closed when the zoom is automatically changed . How can i prevent this from happening ?
I found that everytime this code is triggered on the map it self when there are movements
this.map.on('zoomend', function(){
thatt.lastEvent.target.unbindPopup()
.bindPopup(`
<div><b>Dispatcher:</b></div>
`).openPopup();
});
i tried to get the last marker and to open the pop up and without success.
I also tried
that.lastEvent.target
.unbindPopup()
.bindPopup(`
<div><b>Dispatcher:</b> ${truckLocationObj?.dispatcher}</div>
<div><b>Dispatcher Email:</b> ${truckLocationObj?.dispatcher_email}</div>
<div><b>Truck #:</b> ${truckLocationObj?.truck}</div>
<div><b>ZIP</b> ${truckLocationObj?.available_zip} </div>
<div><b>City:</b> ${truckLocationObj?.available_city}</div>
<div class='red'><b>Distance:</b> ${distance} km to ${that.selectedCityZipCodeObject.city}, time: ${getHm}</div>
<div><b>Available on:</b> ${truckLocationObj?.available_date}</div>
`, {closePopupOnClick: false, autoClose: false, closeOnClick:false, autopanstart:false}).openPopup();
with addiional options on the pop up itself but also without success.
So fitSelectedRoutes - true makes something like fitting bounds of the two markers.
var corner1 = L.latLng(0,0);
var corner2 = L.latLng(39.310, -84.432);
let bounds = L.latLngBounds(corner1, corner2);
map.fitBounds(bounds, { padding: [50, 50] });
with this answer here the problem will be solved.
https://stackoverflow.com/questions/51953050/leaflet-markercluster-exempt-marker-from-clustering
https://jsfiddle.net/sghL4z96/65/

How to inject mutationobserver to puppeteer

I want trace changed DOM like mutationobserver in headless chrome.
So I learning puppeteer library, but don’t know how to use do that.
It’s possible to trace DOM change in puppeteer?? thanks
Well,you can inject custom code to the browser.
One way:
await page.evaluate(() => {
const observer = new MutationObserver(
function() {
// communicate with node through console.log method
console.log('__mutation')
}
)
const config = {
attributes: true,
childList: true,
characterData: true,
subtree: true
}
observer.observe(target, config)
})
In your node script:
page.on('console', async (msg) => {
if (msg.text === '__mutation') {
// do something...
}
})

React-Leaflet-Draw: accessing a polygon's array of coordinates on save

I've got a component which puts an editable polygon on the map. When the user hits the "save" button, I want to access an array of the polygon's new vertices, so that I can save them. How do I do this?
My component:
<FeatureGroup>
<EditControl
position="topright"
onEdited={e => console.log(e)}
edit={{ remove: false }}
draw={{
marker: false,
circle: false,
rectangle: false,
polygon: false,
polyline: false
}}
/>
<Polygon positions={polygonCoords} />;
</FeatureGroup>
The couple of references I've got:
https://github.com/alex3165/react-leaflet-draw
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-event-draw:editstop
I understand I have to implement some sort of function dealing with the onEdited hook and the event generated thereby, but does anyone have any idea how I can get the new vertex array from this event?
For anyone else struggling with this, here's a working solution with ES6:
<FeatureGroup>
<EditControl
position="topright"
//this is the necessary function. It goes through each layer
//and runs my save function on the layer, converted to GeoJSON
//which is an organic function of leaflet layers.
onEdited={e => {
e.layers.eachLayer(a => {
this.props.updatePlot({
id: id,
feature: a.toGeoJSON()
});
});
}}
edit={{ remove: false }}
draw={{
marker: false,
circle: false,
rectangle: false,
polygon: false,
polyline: false
}}
/>
<Polygon positions={[positions(this.props)]} />;
</FeatureGroup>
);
Getting this took me some hours so it might be helpful to someone someday.
First initialise mapLayer state to hold your coordinates and implement onCreated() and onEdited() functions
const [mapLayers, setMapLayers] = useState([]);
const onCreated = e => {
console.log(e)
const {layerType, layer} = e
if (layerType === "polygon") {
const {leaflet_id} = layer
setMapLayers(layers => [...layers, {id: leaflet_id, latlngs: layer.getLatLngs()[0]}])
}
};
const onEdited = e => {
// console.log('Edited data', e);
const {layers: {_layers}} = e;
Object.values(_layers).map((
{_leaflet_id, editing}) => {
setMapLayers((layers) => layers.map((l) => l.id === _leaflet_id? {...l, latlngs: {...editing.latlngs[0]}
} : l)
)
});
};

Sencha touch 2.0 and iphone : add element to panel dynamically and setActiveItem

I am trying to add dinamically a panel item to a main panel with a card layout which has initially one panel in it.
After one event (a tap) i build dinamically a new panel and I add it to the main panel, after this i try to set the new panel item like the active one via setActiveItem
Things work ok on Android but not on iphone.
Exactly i have this app.js:
Ext.Loader.setConfig({enabled: true});
Ext.setup({
viewport: {
autoMaximize: false
},
onReady: function() {
var app = new Ext.Application({
name: 'rpc',
appFolder: 'app',
controllers: ['Home'],
autoCreateViewport: false,
launch: function () {
Ext.create('Ext.Panel',{
fullscreen: true,
layout: {
type : 'card',
animation:{
type:'slide'
,duration :3000
}
},
defaults: { /*definisce le caratteristiche di default degli elementi contenuti..??*/
flex: 1
},
items:[{
title: 'Compose',
xtype: 'griglia'
}]
});
}
});
}
});
In a controller i have
.....
.....
var grigliaPan=button.up('griglia');
var mainPan=grigliaPan.up('panel');
var html=
'<img src="img/'+segnoScelto+'_big.png" />'
+'<h1>'+segnoScelto+'</h1>'
+'<p>'+previsione+'</p>'
+'</br></br>';
if (typeof mainPan.getComponent(1) == 'undefined'){
var previsioPan = Ext.widget('previsio');
previsioPan.setHtml(html);
//here i create a button for going home panel
var backButton=new Ext.Button({
ui : 'decline',
alias: 'widget.backbutton',
text: 'Home Page',
width : 150,
height:100
})
previsioPan.add(backButton);
var it=mainPan.getItems();
alert (it['keys']); //this prints : ext-griglia-1
mainPan.add(previsioPan);
var it=mainPan.getItems();
alert (it['keys']); //this prints : ext-griglia-1,ext-previsio-1
//
}
mainPan.getLayout().setAnimation({type: 'slide', direction: 'left', duration:1000});
//mainPan.setActiveItem(1);
var pree=mainPan.getAt(1);
//pree.show();
//mainPan.setActiveItemm(pree);
mainPan.setActiveItem('ext-previsio-1');
The three form of setActiveItem() are ok for Android and falls with iPhone. Can somebody please show me what is the right way to set the new active item added dinamically on the iphone ?
The problem should not be with the add() function cause i can see the new item via the getItems() added in main panel after the add().
by following code you can understand that thisCell is added later after creation of thisRow.
var thisRow = new Ext.Panel({
layout: { type: 'hbox', align: 'stretch', pack: 'center' },
id: 'row' + (rowCount + 1),
defaults: { flex: 1 }
});
// Now we need to add the cells to the above Panel:
var thisCell = new Ext.Panel({
cls: 'dashboardButton',
layout: { type: 'vbox', align: 'center', pack: 'center' },
items: [{
xtype: 'image',
src: 'some image url',
height: '70px',
width: '100px',
}]
});
thisRow.add(thisCell);
hope this will help you to achieve your desired output...