New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(node): node 12 compatible util module and improved console #11165
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm fine with making use of Node's code when possible if the copyright/license allows for it. I had specifically been avoiding it in my re-implementations. But the reality is that our Android core has some Node code from very, very old Node versions in it already (i.e. events.js)
I think we need to revisit if we need to be retaining special copyright headers or shipping license files/etc to not be in violation of Node (and it's upstream contributors/dependencies)'s license/usage.
}, | ||
"rules": { | ||
"strict": ["error", "global"] | ||
}, | ||
"overrides": [ | ||
{ | ||
"files": [ "tests/Resources/es6.*.js" ], | ||
"files": [ "tests/Resources/es6.*.js", "tests/Resources/util.test.js" ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at this point, perhaps just bite the bullet and say all test/Resources/**
are 2017/module? Or even 2018/2019?
@@ -46,7 +46,7 @@ | |||
{ | |||
"files": [ "common/Resources/**/*.js" ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So maybe merge this and the entry above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to bump the version to 2018 for either object rest spread or async/generator support, not sure anymore.
Maybe we should even switch to axway/+babel
or manually setting the parser to babel-eslint
for stuff like this that gets transpiled?
const kColorInspectOptions = { colors: true }; | ||
const kNoColorInspectOptions = {}; | ||
|
||
console.debug = function (...args) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of the scope of this PR, but we do have an open ticket to expand our console
support. @ewanharris had added time/timeLog before, but it'd be good to start moving this all into this common area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was actually thinking to go one step ahead and adopt more of Nodes console
API but then left it as is to not blow this out of proportion.
Is there any open ticket for the extended console functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
if (otherClasses.length !== 0) { | ||
otherClasses.forEach((clazz) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to drop the wrapping parens in single-arg arrow functions...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, me too, but since this was also taken from the node source, i tried to make only the neccessary changes to make our linting pass (for example, wrap single line if-statements in brackets) and leave everything else as is.
/* eslint no-array-constructor: "off" */ | ||
/* eslint no-new-wrappers: "off" */ | ||
|
||
const should = require('./utilities/assertions'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have any hints on what actually changed here in the override test suite?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed to fix the typo in isRegexp
in the existing tests and added tests for the missing methods hanging off of types
. So all the typed array stuff at the end of this file as well as
isAnyArrayBuffer
isArrayBuffer
isArgumentsObject
isAsyncFunction
isDataView
isGeneratorFunction
isGeneratorObject
isMapIterator
isPromise
isSharedArrayBuffer
isSetIterator
isSymbolObject
isWeakMap
isWeakSet
Also some of the output generated by format
changed, so i had to adjust the existing tests there too. For example, the break length was increased and additional new lines were added when printing objects.
@sgtcoolguy so the files in lib all have a copyright header, the ones in lib/internal don't. That's why i just added a reference to the original file via Node's LICENSE file states that the copyright notice and permission notice should be included in all copies, so i'll add that to the respective files. |
} | ||
|
||
export function isSharedArrayBuffer(value) { | ||
if (!global.SharedArrayBuffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚠️ common/Resources/ti.internal/extensions/node/internal/util/types.js line 189 – The 'SharedArrayBuffer' is not supported until Node.js 8.10.0. The configured version range is '>=8'. (node/no-unsupported-features/es-builtins)
@sgtcoolguy added the license header from Node.js and updated our linting setup to ignore various node rules that don't apply to our node shims. |
I don't know why, but on Android this PR seems to finish the test suite and then sit there until it gets timed out. Not sure what could be going on that would cause that. I guess I'll have to try it locally and see? |
Ok, well after some playing around locally, it's because the wrapping code that runs our tests it getting into a state where it think it never has the full output for a test failure. Specifically we're spitting out a TEST_END with the json results and it's getting truncated somehow, so we never have the full valid JSON to parse (and it keeps appending the next line of output it sees to it to try and make it valid). The error crops up in the log: https://jenkins.appcelerator.org/blue/rest/organizations/jenkins/pipelines/titanium-sdk/pipelines/titanium_mobile/branches/PR-11165/runs/16/nodes/89/steps/154/log/?start=0 at the "util#format() with object" test. So this appears to be a bug in our actual Ti.API log implementation, that is because of a native logger limit. Android itself tries to hack around this at the Java side by splitting long messages to avoid truncation: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/Log.java#401 |
Created a TIMOB JIRA ticket for this android Ti.API limitation: https://jira.appcelerator.org/browse/TIMOB-27399 |
ok, well for now I have hacked a workaround into the test suite code. If a stringified test failure is too long, I split the JSON across multiple lines. And I handle on the other wrapping script that reads the logs and updated it to strip the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FR Passed: Can see an improvement in console debugging capabilities and apps no longer crash.
Testcase:
const a = {};
a.b = a;
console.log(a); // crashes on 8.0.1.GA, or just prints "[object Object]" on 8.1.0.GA
//Expected <ref *1> { b: [Circular *1] }
const b = {
foo: 'bar'
}
console.log(b); // prints "{ foo: 'bar' }" on 8.0.1.GA, or just "[object Object]" on 8.1.0.GA
//Expected { foo: 'bar' }
const map = new Map();
map.set('foo', 'bar');
console.log(map); // prints "{}" on 8.0.1.GA, or just "[object Map]" on 8.1.0.GA
//Expected Map { 'foo' => 'bar' }
Output:
[INFO] �� � <ref *1> { b: [Circular *1] }
[INFO] �� � { foo: 'bar' }
[INFO] �� � Map { 'foo' => 'bar' }
Test Environment
MacOS Catalina 10.15 Beta
Node.js ^8.11.1
"NPM":"4.2.15","CLI":"7.1.1"
Java Version 1.8.0_131
Xcode 11 GM seed 2
util.types.isAnyArrayBuffer(ab).should.be.true; | ||
}); | ||
|
||
it.skip('should return true for built-in SharedArrayBuffer', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚠️ tests/Resources/util.test.js line 1223 – Unexpected skipped mocha test. (mocha/no-skipped-tests)
JIRA: https://jira.appcelerator.org/browse/TIMOB-27345
Optional Description:
This refactors the util module by adding missing type checks for
util.types
and using the Node 12inspect
implementation. It is mostly a copy of internal/util/inspect.js and internal/util/types.js that i modified to work with Titanium. That way it should be easier for us to catch up with internal changes inside Node since we use the same code as they do, only with a few slight modifications to get around stuff that calls into Node's native code.Additionally this hooks up
util.inspect
withconsole.log
and the likes to get improved logging capabilities in the console, just like it is in Node. I leftTi.API.*
untouched for now, not sure if we want to sync those up too.Since iOS and Android run on different JS engines there're a few slight differences when it comes to inspecting errors or hidden object properties, but i think those can be neglected for now.
Other issues i discovered so far:
WeakMap { <items unknown> }
for example, even ifshowHidden
option is set.Our own Buffer implementation doesn't get handled properly because it is wrapped in a ProxyI added a workaround for that and also added the custom inspect implementation for Node Buffers.