Javascript macOS Error: Named parameters must be passed as an object - javascript

I'm trying to implement automation for the task manager Things 3 on macOS using JXA (Javascript for macOS automation) and I'm running it to a strange error. I have spent countless hours trying to fix this myself and with the help of others. I am trying to use the following method described in the documentation:
As following:
// Set TaskApp as the app to use
var TaskApp = Application('Things3');
// Get the ToDo from toDos
var task = TaskApp.toDos["test555342343"]
// Get today as a date
var today = new Date()
// Schedule the task for Today
task.schedule(task.id(), {for: today})
This returns the error:
Error: Error: Named parameters must be passed as an object.
When using another method (like show) the specefier works as expected:
Example:
// Set TaskApp as the app to use
var TaskApp = Application('Things3');
// Get the ToDo from toDos
var task = TaskApp.toDos["test555342343"]
// Bring Things3 to the Forground
TaskApp.activate()
// Show the task
task.show(task.id())
Will show the selected todo. Creating a task with with a deadline set to the date object also produces the correct result (a task with the deadline of date).
This documentation can only be found when you have things3 installed on macOS and you reference the Script Library. I have added the documentation as PDF. The described error also apply's to the move method. Instead of parsing a date you parse a List Object to it which will resolve in the same error.
Link to documentation PDF → Link

The Things documentation is wrong: schedule is a method of Application, not of ToDo, which is why it asks for a todo specifier (it wouldn’t need that one if it was a property of a ToDo object already). The working code hence is:
// Set TaskApp as the app to use
var TaskApp = Application('Things3')
// Get the ToDo from toDos
var task = TaskApp.toDos["test555342343"]
// Get today as a date
var today = new Date()
// Schedule the task for Today
TaskApp.schedule(task, {for: today})
Note that task already is a ToDo specifier; you don’t need the detour through task.id(), which converts the ToDo specifier into an ID String before letting the schedule method cast that back to a specifier.

Related

Pass AWS SQSClient mockClient to a typescript class

I'm trying to unit test some code where the class has a constructor taking in an SQSClient object used to get messages off an sqs queue! Surprise! Very simple stuff. So I want to mock the client so I can write some unit tests around the code without actually calling the queue. I'm trying to model my code from examples here:
https://www.npmjs.com/package/aws-sdk-client-mock
In my unit test I simply create the mock client and try to pass it into my class:
const sqsMockClient = mockClient(SQSClient);
sqsMockClient.onAnyCommand().resolves({});
const blClass: BLClass = new BLClass(sqsMockClient);
This won't run, the test output says the type is not assignable to parameter of type 'SQSClient' because it's not an actual SQSClient. If I instantiate an actual SQSClient and pass that it will run but will attempt to actually hit the queue and pull messages down. I'm wanting to build out the mock above to return a static message for unit testing purposes.
Any idea what I could do differently to enable the mock to work?
This worked for me:
const sqsClient = new SQSClient({});
const sqsMockClient = mockClient(sqsClient);
sqsMockClient.onAnyCommand().resolves({});
const blClass: BLClass = new BLClass(sqsClient);

Unable to get new values from external module

I have a date module that returns current date that is set in system:
function getDateFormatAndISODate() {
const dates = require('./resources/getSystemDate').getSystemDate();
return dates;
}
module.exports.getDateFormatAndISODate = getDateFormatAndISODate;
I am requiring it in another file:
import * as isoDateModule from './datastream-get-iso-module';
The issue is the method call is not returning new date values when user changes the date manually from system and call this method again:
isoDateModule.getDateFormatAndISODate(dateVal);
I am using c node addon in my project and I am requiring it like this:
function requireUncached(module) {
delete require.cache[require.resolve(module)];
return require(module);
}
const dates = requireUncached('./resources/getSystemDate').getSystemDate();
But still I get the old date values. Not sure whats missing

Components using Date objects produce different snapshots in different timezones

I'm using Enzyme with enzyme-to-json to do Jest snapshot testing of my React components. I'm testing shallow snapshots of a DateRange component that renders a display field with the current range (e.g. 5/20/2016 - 7/18/2016) and two DateInput components that allow selecting a Date value. This means that my snapshot contains the Dates I pass to the component both in the DateInput props and in a text representation it resolves itself. In my test I'm creating some fixed dates using new Date(1995, 4, 23).
When I run my test in different timezones, this produces different snapshots, because the Date(year, month, ...) constructor creates the date in the local timezone. E.g. use of new Date() produces this difference in snapshot between runs in my local timezone and on our CI server.
- value={1995-05-22T22:00:00.000Z}
+ value={1995-05-23T00:00:00.000Z}
I tried removing the timezone offset from the dates, but then the snapshot differed in the display field value, where the local timezone-dependent representation is used.
- value={5/20/2016 - 7/18/2016}
+ value={5/19/2016 - 7/17/2016}
How can I make my tests produce the same Dates in snapshots regardless of the timezone they're run in?
I struggled with this for hours/days and only this worked for me:
1) In your test:
Date.now = jest.fn(() => new Date(Date.UTC(2017, 7, 9, 8)).valueOf())
2) Then change the TZ env var before running your tests.
So the script in my package.json:
(Mac & Linux only)
"test": "TZ=America/New_York react-scripts test --env=jsdom",
(Windows)
"test": "set TZ=America/New_York && react-scripts test --env=jsdom",
I ended up with a solution comprised of two parts.
Never create Date objects in tests in timezone-dependent manner. If you don't want to use timestamps directly to have readable test code, use Date.UTC, e.g.
new Date(Date.UTC(1995, 4, 23))
Mock the date formatter used to turn Dates into display values, so that it returns a timezone-independent representation, e.g. use Date::toISOString(). Fortunately this was easy in my case, as I just needed to mock the formatDate function in my localization module. It might be harder if the component is somehow turning Dates into strings on its own.
Before I arrived at the above solution, I tried to somehow change how the snapshots are created. It was ugly, because enzyme-to-json saves a local copy of toISOString(), so I had to use _.cloneDeepWith and modify all the Dates. It didn't work out for me anyway, because my tests also contained cases of Date creation from timestamps (the component is quite a bit more complicated than I described above) and interactions between those and the dates I was creating in the tests explicitly. So I first had to make sure all my date definitions were referring to the same timezone and the rest followed.
Update (11/3/2017): When I checked enzyme-to-json recently, I haven't been able to find the local saving of toISOString(), so maybe that's no longer an issue and it could be mocked. I haven't been able to find it in history either though, so maybe I just incorrectly noted which library did it. Test at your own peril :)
I did this by using timezone-mock, it internally replaces the global Date object and it's the easiest solution I could find.
The package supports a few test timezones.
import timezoneMock from 'timezone-mock';
describe('when in PT timezone', () => {
beforeAll(() => {
timezoneMock.register('US/Pacific');
});
afterAll(() => {
timezoneMock.unregister();
});
// ...
https://www.npmjs.com/package/timezone-mock
I ended up getting around this by mocking the toLocaleString (or whatever toString method you are using) prototype. Using sinon I did:
var toLocaleString;
beforeAll(() => {
toLocaleString = sinon.stub(Date.prototype, 'toLocaleString', () => 'fake time')
})
afterAll(() => {
toLocaleString.restore()
})
This way if you are generating strings straight from a Date object, you're still OK.
2020 solution that works for me
beforeEach(() => {
jest.useFakeTimers('modern');
jest.setSystemTime(Date.parse(FIXED_SYSTEM_TIME));
});
afterEach(() => {
jest.useRealTimers();
});
If you're using new Date() constructor instead of Date.now you can do like below:
const RealDate = Date;
beforeEach(() => {
// #ts-ignore
global.Date = class extends RealDate {
constructor() {
super();
return new RealDate("2016");
}
};
})
afterEach(() => {
global.Date = RealDate;
});
This issue is a must visit if you're here.
Adding TZ=UTC to my .env file solved the issue for me.
A simple fact can make it easy.
Just use :
new Date('some string').
This will always give an invalid date and no matter which machine, it will always be invalid date.
cheers.
Try passing a random date like new Date(1466424490000), wherever you call new Date()

how does the ReadableMap interface in React-native convert JS to JAVA?

I'm trying to understand how to properly pass options from the js side of react-native to the java side.
The react-native bridge uses ReadableMap to convert but as a Java noob I'm failing to understand how this works.
More specifically I don't understand:
how the actual conversion works?
how to tell what type/format the downstream Java code wants?
how to properly use ReadableMap to do this?
Generally I would like to know how this works but I'll give the specific example I'm looking at to give some context.
A react-native package exposes a datetime picker.
The JS side has a showTimePicker method:
showTimePicker(date, callback) {
date = date || new Date();
console.log(this.props);
debugger
var options = {
...this.props,
hour:date.getHours(),
minute:date.getMinutes()
};
RCTDateTimePicker.showTimePicker(options, function (hour, minute) {
date.setHours(hour);
date.setMinutes(minute);
callback(date);
});
}
RCTDateTimePicker.showTimePicker is bridged to a Java method on the native side:
#ReactMethod
public void showTimePicker(ReadableMap options, Callback callback) {
DialogFragment timePicker = new TimePicker(options, callback);
timePicker.show(activity.getFragmentManager(), "timePicker");
}
which calls
public TimePicker(ReadableMap options, Callback callback) {
final Calendar c = Calendar.getInstance();
this.callback = callback;
hour = options.hasKey("hour") ? options.getInt("hour") : c.get(Calendar.HOUR_OF_DAY);
minute = options.hasKey("minute") ? options.getInt("minute") : c.get(Calendar.MINUTE);
}
which creates and instance of an Android TimePicker. My goal is to change the style of the Timepicker from watch to spinner.
There is a settable XML attribute android:timePickerMode="spinner" but I don't think I can pass an XML attribute through react-native can I?
I also found a suggestion in comments to pass defStyleAttr to do this, but I don't understand how.
First, see the list of Argument Types from the React Native document for Android Native Modules.
Argument Types
The following argument types are supported for methods
annotated with #ReactMethod and they directly map to their JavaScript
equivalents
Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array
So, you can pass the extra field for timePickerMode as a String by updating the options that the JS side passes to include it.
var options = {
...this.props,
hour:date.getHours(),
minute:date.getMinutes(),
timePickerMode:"spinner"
};
And then get that value from the ReadableMap in your custom TimePicker constructor.
String timePickerMode = options.hasKey("timePickerMode") ?
options.getString("timePickerMode") : defaultTimePickerMode;
Now you have the value you wish to set. Unfortunately it does not appear that timePickerMode can be set programmatically. This SO question asks how to do it and #alanv (whose profile indicates they are a Software Engineer at Google) indicates that it is not possible at runtime.

node.js log module bunyan change timezone

I'm using this logging module bunyan.js which is included in the framwork restify.js. The module does outprint a time in the log file/console, however, I want to change the time to UTC/GMT, not sure if it's possible wihtout modifying the module code?
If you don't want to use local time anywhere else in your process, one way to achieve what you want is to change the timezone for the process. Either by writing this statement at the startup of you application:
process.env.TZ = 'UTC'
Or by starting it with a environment variable from the command line, like this:
TZ=UTC node main.js
I was also facing the same issue and resolved it by adding a custom attribute, localtime, while creating the logger using bunyan.createLogger method like this:
var init = function () {
log = bunyan.createLogger({
name: 'myLogs',
src: true,
localtime: new Date().toString();
});
};
By doing this, I get an extra field in my log called localtime with the appropriate time as per my timezone.
Hope this helps.

Categories

Resources