opal 1.3.0.alpha1 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +3 -1
  3. data/UNRELEASED.md +29 -6
  4. data/examples/rack/Gemfile +1 -0
  5. data/examples/rack/Gemfile.lock +11 -7
  6. data/examples/rack-esm/.gitignore +1 -0
  7. data/examples/rack-esm/Gemfile +5 -0
  8. data/examples/rack-esm/app/application.rb +27 -0
  9. data/examples/rack-esm/app/user.rb +24 -0
  10. data/examples/rack-esm/config.ru +25 -0
  11. data/examples/rack-esm/index.html.erb +11 -0
  12. data/examples/sinatra/Gemfile.lock +21 -19
  13. data/lib/opal/builder.rb +39 -23
  14. data/lib/opal/builder_processors.rb +6 -1
  15. data/lib/opal/cache/file_cache.rb +7 -6
  16. data/lib/opal/cli_runners/chrome.rb +20 -15
  17. data/lib/opal/cli_runners/chrome_cdp_interface.rb +1 -1
  18. data/lib/opal/cli_runners/nodejs.rb +3 -2
  19. data/lib/opal/cli_runners/quickjs.rb +28 -0
  20. data/lib/opal/cli_runners.rb +1 -0
  21. data/lib/opal/compiler.rb +8 -2
  22. data/lib/opal/config.rb +5 -0
  23. data/lib/opal/nodes/call.rb +45 -26
  24. data/lib/opal/nodes/helpers.rb +1 -1
  25. data/lib/opal/nodes/top.rb +5 -8
  26. data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +16 -0
  27. data/lib/opal/simple_server.rb +7 -2
  28. data/lib/opal/util.rb +1 -1
  29. data/lib/opal/version.rb +1 -1
  30. data/opal/corelib/complex/base.rb +15 -0
  31. data/opal/corelib/complex.rb +3 -15
  32. data/opal/corelib/constants.rb +2 -2
  33. data/opal/corelib/error.rb +1 -1
  34. data/opal/corelib/helpers.rb +10 -0
  35. data/opal/corelib/io.rb +4 -0
  36. data/opal/corelib/kernel.rb +21 -5
  37. data/opal/corelib/main.rb +4 -0
  38. data/opal/corelib/method.rb +4 -0
  39. data/opal/corelib/module.rb +39 -16
  40. data/opal/corelib/pattern_matching/base.rb +35 -0
  41. data/opal/corelib/pattern_matching.rb +2 -36
  42. data/opal/corelib/process/base.rb +9 -0
  43. data/opal/corelib/process.rb +1 -11
  44. data/opal/corelib/random.rb +4 -0
  45. data/opal/corelib/rational/base.rb +11 -0
  46. data/opal/corelib/rational.rb +3 -10
  47. data/opal/corelib/regexp.rb +1 -1
  48. data/opal/corelib/runtime.js +38 -3
  49. data/opal/opal/full.rb +5 -4
  50. data/opal/opal.rb +12 -11
  51. data/package.json +1 -1
  52. data/spec/filters/bugs/bigdecimal.rb +0 -1
  53. data/spec/filters/bugs/enumerator.rb +5 -0
  54. data/spec/filters/bugs/float.rb +3 -0
  55. data/spec/filters/bugs/kernel.rb +2 -9
  56. data/spec/filters/bugs/language.rb +0 -1
  57. data/spec/filters/bugs/marshal.rb +3 -0
  58. data/spec/filters/bugs/method.rb +1 -2
  59. data/spec/filters/bugs/module.rb +0 -6
  60. data/spec/filters/bugs/rational.rb +1 -0
  61. data/spec/filters/bugs/regexp.rb +0 -1
  62. data/spec/lib/compiler_spec.rb +2 -2
  63. data/spec/mspec-opal/runner.rb +1 -0
  64. data/stdlib/benchmark.rb +14 -0
  65. data/stdlib/buffer.rb +4 -0
  66. data/stdlib/nashorn/file.rb +2 -0
  67. data/stdlib/native.rb +63 -58
  68. data/stdlib/nodejs/argf.rb +110 -0
  69. data/stdlib/nodejs/env.rb +12 -0
  70. data/stdlib/nodejs/file.rb +10 -0
  71. data/stdlib/nodejs/kernel.rb +56 -0
  72. data/stdlib/nodejs.rb +1 -0
  73. data/stdlib/opal/platform.rb +2 -0
  74. data/stdlib/opal-platform.rb +5 -2
  75. data/stdlib/pathname.rb +4 -0
  76. data/stdlib/quickjs/io.rb +22 -0
  77. data/stdlib/quickjs/kernel.rb +5 -0
  78. data/stdlib/quickjs.rb +2 -0
  79. data/stdlib/securerandom.rb +2 -0
  80. data/tasks/performance.rake +2 -1
  81. data/tasks/testing.rake +1 -1
  82. metadata +36 -8
  83. data/lib/opal/cli_runners/chrome_cdp_interface.js +0 -30285
@@ -1,4 +1,5 @@
1
1
  require 'corelib/numeric'
2
+ require 'corelib/rational/base'
2
3
 
3
4
  class Rational < Numeric
4
5
  def self.reduce(num, den)
@@ -350,18 +351,10 @@ class Rational < Numeric
350
351
  Rational(s.send(method), p)
351
352
  end
352
353
  end
353
- end
354
354
 
355
- module Kernel
356
- def Rational(numerator, denominator = 1)
357
- Rational.convert(numerator, denominator)
358
- end
359
- end
360
-
361
- class String
362
- def to_r
355
+ def self.from_string(string)
363
356
  %x{
364
- var str = self.trimLeft(),
357
+ var str = string.trimLeft(),
365
358
  re = /^[+-]?[\d_]+(\.[\d_]+)?/,
366
359
  match = str.match(re),
367
360
  numerator, denominator;
@@ -23,7 +23,7 @@ class Regexp < `RegExp`
23
23
  def last_match(n = nil)
24
24
  if n.nil?
25
25
  $~
26
- else
26
+ elsif $~
27
27
  $~[n]
28
28
  end
29
29
  end
@@ -234,6 +234,25 @@
234
234
  }
235
235
  }
236
236
 
237
+ function handle_autoload(cref, name) {
238
+ if (!cref.$$autoload[name].loaded) {
239
+ cref.$$autoload[name].loaded = true;
240
+ try {
241
+ Opal.Kernel.$require(cref.$$autoload[name].path);
242
+ } catch (e) {
243
+ cref.$$autoload[name].exception = e;
244
+ throw e;
245
+ }
246
+ cref.$$autoload[name].required = true;
247
+ if (cref.$$const[name]) {
248
+ cref.$$autoload[name].success = true;
249
+ return cref.$$const[name];
250
+ }
251
+ } else if (cref.$$autoload[name].loaded && !cref.$$autoload[name].required) {
252
+ if (cref.$$autoload[name].exception) { throw cref.$$autoload[name].exception; }
253
+ }
254
+ }
255
+
237
256
  // Constants
238
257
  // ---------
239
258
  //
@@ -248,7 +267,12 @@
248
267
 
249
268
  // Get the constant in the scope of the current cref
250
269
  function const_get_name(cref, name) {
251
- if (cref) return cref.$$const[name];
270
+ if (cref) {
271
+ if (cref.$$const[name]) { return cref.$$const[name]; }
272
+ if (cref.$$autoload && cref.$$autoload[name]) {
273
+ return handle_autoload(cref, name);
274
+ }
275
+ }
252
276
  }
253
277
 
254
278
  // Walk up the nesting array looking for the constant
@@ -261,7 +285,11 @@
261
285
  // and in order. The ancestors of those elements are ignored.
262
286
  for (i = 0, ii = nesting.length; i < ii; i++) {
263
287
  constant = nesting[i].$$const[name];
264
- if (constant != null) return constant;
288
+ if (constant != null) {
289
+ return constant;
290
+ } else if (nesting[i].$$autoload && nesting[i].$$autoload[name]) {
291
+ return handle_autoload(nesting[i], name);
292
+ }
265
293
  }
266
294
  }
267
295
 
@@ -276,6 +304,8 @@
276
304
  for (i = 0, ii = ancestors.length; i < ii; i++) {
277
305
  if (ancestors[i].$$const && $has_own.call(ancestors[i].$$const, name)) {
278
306
  return ancestors[i].$$const[name];
307
+ } else if (ancestors[i].$$autoload && ancestors[i].$$autoload[name]) {
308
+ return handle_autoload(ancestors[i], name);
279
309
  }
280
310
  }
281
311
  }
@@ -417,6 +447,11 @@
417
447
  for (constant in module.$$const) {
418
448
  constants[constant] = true;
419
449
  }
450
+ if (module.$$autoload) {
451
+ for (constant in module.$$autoload) {
452
+ constants[constant] = true;
453
+ }
454
+ }
420
455
  }
421
456
 
422
457
  return Object.keys(constants);
@@ -432,7 +467,7 @@
432
467
  return old;
433
468
  }
434
469
 
435
- if (cref.$$autoload != null && cref.$$autoload[name] != null) {
470
+ if (cref.$$autoload && cref.$$autoload[name]) {
436
471
  delete cref.$$autoload[name];
437
472
  return nil;
438
473
  }
data/opal/opal/full.rb CHANGED
@@ -1,7 +1,8 @@
1
- require 'corelib/marshal'
1
+ autoload :Marshal, 'corelib/marshal'
2
2
  require 'corelib/string/unpack'
3
3
  require 'corelib/array/pack'
4
- require 'corelib/object_space'
5
- require 'corelib/pattern_matching'
6
- require 'corelib/trace_point'
4
+ autoload :ObjectSpace, 'corelib/object_space'
5
+ require 'corelib/pattern_matching/base'
6
+ autoload :PatternMatching, 'corelib/pattern_matching'
7
+ autoload :TracePoint, 'corelib/trace_point'
7
8
  require 'corelib/binding'
data/opal/opal.rb CHANGED
@@ -1,20 +1,21 @@
1
1
  require 'opal/base'
2
2
  require 'opal/mini'
3
3
 
4
+ require 'corelib/main'
4
5
  require 'corelib/kernel/format'
5
6
  require 'corelib/string/encoding'
6
- require 'corelib/math'
7
- require 'corelib/complex'
8
- require 'corelib/rational'
7
+ autoload :Math, 'corelib/math'
8
+ require 'corelib/complex/base'
9
+ autoload :Complex, 'corelib/complex'
10
+ require 'corelib/rational/base'
11
+ autoload :Rational, 'corelib/rational'
9
12
  require 'corelib/time'
10
- require 'corelib/struct'
11
- require 'corelib/io'
12
- require 'corelib/main'
13
+ autoload :Struct, 'corelib/struct'
13
14
  require 'corelib/dir'
14
- require 'corelib/file'
15
- require 'corelib/process'
16
- require 'corelib/random/formatter'
17
- require 'corelib/random'
18
- require 'corelib/random/mersenne_twister'
15
+ autoload :File, 'corelib/file'
16
+
17
+ require 'corelib/process/base'
18
+ autoload :Process, 'corelib/process'
19
+ autoload :Random, 'corelib/random'
19
20
 
20
21
  require 'corelib/unsupported'
data/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "benchmark": "^2.1.4",
6
6
  "browserify": "^17.0.0",
7
7
  "source-map-support": "0.5.19",
8
- "uglify-js": "^3.7.2"
8
+ "terser": "^5.9.0"
9
9
  },
10
10
  "devDependencies": {
11
11
  "eslint": "^7.32.0"
@@ -170,7 +170,6 @@ opal_filter "BigDecimal" do
170
170
  fails "BigDecimal#sub with Object tries to coerce the other operand to self" # Mock 'Object' expected to receive coerce(123450000000000) exactly 1 times but received it 0 times
171
171
  fails "BigDecimal#sub with Rational produces a BigDecimal" # Exception: lhs.$- is not a function
172
172
  fails "BigDecimal#to_f properly handles special values"
173
- fails "BigDecimal#to_f remembers negative zero when converted to float"
174
173
  fails "BigDecimal#to_i raises FloatDomainError if BigDecimal is infinity or NaN"
175
174
  fails "BigDecimal#to_i returns Integer or Bignum otherwise"
176
175
  fails "BigDecimal#to_i returns Integer otherwise" # NoMethodError: undefined method `to_i' for 3e-20001
@@ -164,6 +164,11 @@ opal_filter "Enumerator" do
164
164
  fails "Enumerator::Lazy#uniq without block returns a lazy enumerator" # Expected [0, 1] (Array) to be an instance of Enumerator::Lazy
165
165
  fails "Enumerator::Lazy#uniq without block sets the size to nil" # Expected 2 == nil to be truthy but was false
166
166
  fails "Enumerator::Lazy#uniq works with an infinite enumerable" # TypeError: can't iterate from Float
167
+ fails "Enumerator::Lazy#with_index enumerates with a given block" # Expected [] == [[0, 0], [2, 1], [4, 2]] to be truthy but was false
168
+ fails "Enumerator::Lazy#with_index enumerates with an index starting at 0 when offset is nil" # Expected [] == [[0, 0], [1, 1], [2, 2]] to be truthy but was false
169
+ fails "Enumerator::Lazy#with_index enumerates with an index starting at a given offset" # Expected [] == [[0, 3], [1, 4], [2, 5]] to be truthy but was false
170
+ fails "Enumerator::Lazy#with_index enumerates with an index" # Expected [] == [[0, 0], [1, 1], [2, 2]] to be truthy but was false
171
+ fails "Enumerator::Lazy#with_index raises TypeError when offset does not convert to Integer" # Expected TypeError but no exception was raised ([] was returned)
167
172
  fails "Enumerator::Lazy#zip calls the block with a gathered array when yield with multiple arguments" # NoMethodError: undefined method `force' for [[[], []], [0, 0], [[0, 1], [0, 1]], [[0, 1, 2], [0, 1, 2]], [[0, 1, 2], [0, 1, 2]], [nil, nil], ["default_arg", "default_arg"], [[], []], [[], []], [[0], [0]], [[0, 1], [0, 1]], [[0, 1, 2], [0, 1, 2]]]
168
173
  fails "Enumerator::Lazy#zip keeps size" # Expected 0 == 100 to be truthy but was false
169
174
  fails "Enumerator::Lazy#zip on a nested Lazy keeps size" # Expected 0 == 100 to be truthy but was false
@@ -3,6 +3,9 @@ opal_filter "Float" do
3
3
  fails "Float constant MAX is 1.7976931348623157e+308"
4
4
  fails "Float constant MIN is 2.2250738585072014e-308"
5
5
  fails "Float#<=> raises TypeError when #coerce misbehaves" # Expected TypeError (coerce must return [x, y]) but no exception was raised (nil was returned)
6
+ fails "Float#<=> returns 0 when self is Infinity and other other is infinite?=1" # Expected nil == 0 to be truthy but was false
7
+ fails "Float#<=> returns 1 when self is Infinity and other is infinite?=-1" # Expected nil == 1 to be truthy but was false
8
+ fails "Float#<=> returns 1 when self is Infinity and other is infinite?=nil (which means finite)" # Expected nil == 1 to be truthy but was false
6
9
  fails "Float#divmod returns an [quotient, modulus] from dividing self by other" # precision errors caused by Math.frexp and Math.ldexp
7
10
  fails "Float#inspect emits a trailing '.0' for a whole number" # Expected "50" == "50.0" to be truthy but was false
8
11
  fails "Float#inspect emits a trailing '.0' for the mantissa in e format" # Expected "100000000000000000000" == "1.0e+20" to be truthy but was false
@@ -43,10 +43,9 @@ opal_filter "Kernel" do
43
43
  fails "Kernel#__dir__ when used in eval with top level binding returns the real name of the directory containing the currently-executing file"
44
44
  fails "Kernel#autoload calls main.require(path) to load the file" # NameError: uninitialized constant TOPLEVEL_BINDING
45
45
  fails "Kernel#autoload can autoload in instance_eval" # NameError: uninitialized constant KSAutoloadD
46
+ fails "Kernel#autoload inside a Class.new method body should define on the new anonymous class" # NoMethodError: undefined method `autoload?' for #<#<Class:0x61d4a>:0x61d48>
46
47
  fails "Kernel#autoload is a private method" # Expected Kernel to have private instance method 'autoload' but it does not
47
- fails "Kernel#autoload loads the file when the constant is accessed" # NameError: uninitialized constant KSAutoloadB
48
- fails "Kernel#autoload registers a file to load the first time the named constant is accessed" # NoMethodError: undefined method `autoload?' for #<MSpecEnv:0x7849c>
49
- fails "Kernel#autoload sets the autoload constant in Object's constant table" # Expected Object to have constant 'KSAutoloadA' but it does not
48
+ fails "Kernel#autoload registers a file to load the first time the named constant is accessed" # NoMethodError: undefined method `autoload?' for #<MSpecEnv:0x5b168>
50
49
  fails "Kernel#autoload when Object is frozen raises a FrozenError before defining the constant" # NoMethodError: undefined method `tmp' for #<MSpecEnv:0x7849c>
51
50
  fails "Kernel#autoload when called from included module's method setups the autoload on the included module" # NoMethodError: undefined method `autoload?' for KernelSpecs::AutoloadMethod
52
51
  fails "Kernel#autoload when called from included module's method the autoload is reachable from the class too" # NoMethodError: undefined method `autoload?' for KernelSpecs::AutoloadMethodIncluder
@@ -102,7 +101,6 @@ opal_filter "Kernel" do
102
101
  fails "Kernel#initialize_copy does nothing if the argument is the same as the receiver" # Expected nil.equal? #<Object:0x590> to be truthy but was false
103
102
  fails "Kernel#initialize_copy raises FrozenError if the receiver is frozen" # Expected FrozenError but no exception was raised (nil was returned)
104
103
  fails "Kernel#initialize_copy raises TypeError if the objects are of different class" # Expected TypeError (initialize_copy should take same class object) but no exception was raised (nil was returned)
105
- fails "Kernel#inspect does not call #to_s if it is defined"
106
104
  fails "Kernel#inspect returns a String for an object without #class method" # Exception: Maximum call stack size exceeded
107
105
  fails "Kernel#instance_variables immediate values returns the correct array if an instance variable is added"
108
106
  fails "Kernel#is_a? does not take into account `class` method overriding" # TypeError: can't define singleton
@@ -340,13 +338,8 @@ opal_filter "Kernel" do
340
338
  fails "Kernel.__method__ returns the caller from blocks too"
341
339
  fails "Kernel.__method__ returns the caller from define_method too"
342
340
  fails "Kernel.autoload calls #to_path on non-String filenames" # Mock 'path' expected to receive to_path("any_args") exactly 1 times but received it 0 times
343
- fails "Kernel.autoload registers a file to load the first time the toplevel constant is accessed" # NoMethodError: undefined method `autoload?' for Kernel
344
- fails "Kernel.autoload sets the autoload constant in Object's constant table" # Expected Object to have constant 'KSAutoloadBB' but it does not
345
341
  fails "Kernel.autoload when called from included module's method setups the autoload on the included module" # NoMethodError: undefined method `autoload?' for KernelSpecs::AutoloadMethod2
346
- fails "Kernel.autoload when called from included module's method the autoload is reachable from the class too" # NoMethodError: undefined method `autoload?' for KernelSpecs::AutoloadMethodIncluder2
347
342
  fails "Kernel.autoload when called from included module's method the autoload relative to the included module works" # NameError: uninitialized constant KernelSpecs::AutoloadMethod2::AutoloadFromIncludedModule2
348
- fails "Kernel.autoload? returns nil if no file has been registered for a constant" # NoMethodError: undefined method `autoload?' for Kernel
349
- fails "Kernel.autoload? returns the name of the file that will be autoloaded" # NoMethodError: undefined method `autoload?' for Kernel
350
343
  fails "Kernel.global_variables finds subset starting with std"
351
344
  fails "Kernel.lambda does not create lambda-style Procs when captured with #method" # Expected true to be false
352
345
  fails "Kernel.lambda raises an ArgumentError when no block is given"
@@ -239,7 +239,6 @@ opal_filter "language" do
239
239
  fails "Predefined global $/ raises a TypeError if assigned an Integer" # Expected TypeError but no exception was raised (#<Number>(#pretty_inspect raised #<TypeError: no implicit conversion of Number into String>) was returned)
240
240
  fails "Predefined global $_ is Thread-local"
241
241
  fails "Predefined global $_ is set at the method-scoped level rather than block-scoped"
242
- fails "Predefined global $_ is set to the last line read by e.g. StringIO#gets"
243
242
  fails "Predefined global $stdout raises TypeError error if assigned to nil"
244
243
  fails "Predefined global $stdout raises TypeError error if assigned to object that doesn't respond to #write"
245
244
  fails "Predefined global $~ is set at the method-scoped level rather than block-scoped"
@@ -6,6 +6,8 @@ opal_filter "Marshal" do
6
6
  fails "Marshal.dump with a Range dumps a Range with extra instance variables" # Expected nil to equal 42
7
7
  fails "Marshal.dump with a Regexp dumps a Regexp subclass" # requires Class.new(Regexp).new("").class != Regexp
8
8
  fails "Marshal.dump with a Regexp dumps a Regexp with instance variables" # //.source.should == ''
9
+ fails "Marshal.dump with a Struct dumps an extended Struct" # Expected "\x04\be: MethsS:\x15Struct::Extended\a:\x06a[\a\"\x06a\"\ahi:\x06b[\a\" Meths@\b" == "\x04\be: MethsS:\x15Struct::Extended\a:\x06a[\a;\a\"\ahi:\x06b[\a;\x00@\a" to be truthy but was false
10
+ fails "Marshal.dump with a Symbol dumps multiple Symbols sharing the same encoding" # Expected "\x04\b[\a\"\tâ\x82¬a\"\tâ\x82¬b" == "\u0004\b[\aI:\tâ\u0082¬a\u0006:\u0006ETI:\tâ\u0082¬b\u0006;\u0006T" to be truthy but was false
9
11
  fails "Marshal.dump with a Time dumps the zone and the offset"
10
12
  fails "Marshal.dump with a Time dumps the zone, but not the offset if zone is UTC" # NoMethodError: undefined method `default_internal' for Encoding
11
13
  fails "Marshal.dump with an Exception contains the filename in the backtrace"
@@ -37,6 +39,7 @@ opal_filter "Marshal" do
37
39
  fails "Marshal.load for an Exception loads an marshalled exception with ivars" # Expected "Exception" == "foo" to be truthy but was false
38
40
  fails "Marshal.load for an Object loads an Object with a non-US-ASCII instance variable" # NameError: '@é' is not allowed as an instance variable name
39
41
  fails "Marshal.load for an Object raises ArgumentError if the object from an 'o' stream is not dumpable as 'o' type user class" # Expected ArgumentError but no exception was raised (#<File:0x3b160> was returned)
42
+ fails "Marshal.load for an object responding to #marshal_dump and #marshal_load loads a user-marshaled object" # Expected "\x04\b[\aU:\x10UserMarshal\"\tdata@\x06" == "\x04\b[\aU:\x10UserMarshal:\tdata;\x06" to be truthy but was false
40
43
  fails "Marshal.load loads a Regexp" # anchors difference
41
44
  fails "Marshal.load loads an array containing objects having _dump method, and with proc"
42
45
  fails "Marshal.load loads an array containing objects having marshal_dump method, and with proc"
@@ -24,11 +24,10 @@ opal_filter "Method" do
24
24
  fails "Method#call for a Method generated by respond_to_missing? invokes method_missing with the method name and the specified arguments"
25
25
  fails "Method#call for a Method generated by respond_to_missing? invokes method_missing with the specified arguments and returns the result"
26
26
  fails "Method#clone returns a copy of the method"
27
- fails "Method#curry returns a curried proc"
28
27
  fails "Method#curry with optional arity argument raises ArgumentError when the method requires less arguments than the given arity"
29
28
  fails "Method#curry with optional arity argument raises ArgumentError when the method requires more arguments than the given arity"
30
- fails "Method#curry with optional arity argument returns a curried proc when given correct arity"
31
29
  fails "Method#define_method when passed a Proc object and a method is defined inside defines the nested method in the default definee where the Proc was created" # Expected #<#<Class:0x3753c>:0x37538> NOT to have method 'nested_method_in_proc_for_define_method' but it does
30
+ fails "Method#define_method when passed a block behaves exactly like a lambda for break" # Exception: unexpected break
32
31
  fails "Method#define_method when passed an UnboundMethod object defines a method with the same #arity as the original"
33
32
  fails "Method#define_method when passed an UnboundMethod object defines a method with the same #parameters as the original"
34
33
  fails "Method#eql? missing methods returns true for the same method missing"
@@ -86,10 +86,6 @@ opal_filter "Module" do
86
86
  fails "Module#const_defined? returns true when passed a scoped constant name for a constant in the inheritance hierarchy and the inherited flag is true"
87
87
  fails "Module#const_defined? returns true when passed a scoped constant name"
88
88
  fails "Module#const_get coerces the inherit flag to a boolean" # Expected NameError but no exception was raised ("const1" was returned)
89
- fails "Module#const_get does autoload a constant with a toplevel scope qualifier" # NameError: uninitialized constant CSAutoloadB
90
- fails "Module#const_get does autoload a constant" # NameError: uninitialized constant CSAutoloadA
91
- fails "Module#const_get does autoload a module and resolve a constant within" # NameError: uninitialized constant CSAutoloadC
92
- fails "Module#const_get does autoload a non-toplevel module" # LoadError: cannot load such file -- ruby/core/module/fixtures/constants_autoload_d
93
89
  fails "Module#const_set sets the name of a module scoped by an anonymous module" # NoMethodError: undefined method `end_with?' for nil
94
90
  fails "Module#const_set when overwriting an existing constant does not warn if the previous value was undefined" # Expected #<Module:0x48fd0> to have constant 'Foo' but it does not
95
91
  fails "Module#const_set when overwriting an existing constant warns if the previous value was a normal value" # Expected warning to match: /already initialized constant/ but got: ""
@@ -177,7 +173,6 @@ opal_filter "Module" do
177
173
  fails "Module#name is not nil for a nested module created with the module keyword"
178
174
  fails "Module#name is not nil when assigned to a constant in an anonymous module" # NoMethodError: undefined method `end_with?' for nil
179
175
  fails "Module#name is set after it is removed from a constant under an anonymous module" # Expected nil to match /^#<Module:0x\h+>::Child$/
180
- fails "Module#name preserves the encoding in which the class was defined"
181
176
  fails "Module#prepend keeps the module in the chain when dupping an intermediate module"
182
177
  fails "Module#prepend keeps the module in the chain when dupping the class"
183
178
  fails "Module#prepend uses only new module when dupping the module" # Expected [#<Module:0x6c37a>] == [#<Module:0x6c38c>, #<Module:0x6c37a>] to be truthy but was false
@@ -223,7 +218,6 @@ opal_filter "Module" do
223
218
  fails "Module#refine when super is called in a refinement looks in the lexical scope refinements before other active refinements" # Expected ["A", "C"] == ["A", "LOCAL", "C"] to be truthy but was false
224
219
  fails "Module#remove_const calls #to_str to convert the given name to a String"
225
220
  fails "Module#remove_const raises a TypeError if conversion to a String by calling #to_str fails"
226
- fails "Module#remove_const returns nil when removing autoloaded constant"
227
221
  fails "Module#ruby2_keywords acceps String as well" # NoMethodError: undefined method `ruby2_keywords' for #<Class:#<Object:0x40040>>
228
222
  fails "Module#ruby2_keywords marks the final hash argument as keyword hash" # NoMethodError: undefined method `ruby2_keywords' for #<Class:#<Object:0x40036>>
229
223
  fails "Module#ruby2_keywords prints warning when a method accepts keyword splat" # NoMethodError: undefined method `ruby2_keywords' for #<Class:#<Object:0x4001e>>
@@ -1,5 +1,6 @@
1
1
  # NOTE: run bin/format-filters after changing this file
2
2
  opal_filter "Rational" do
3
+ fails "Rational does not respond to new" # Expected NoMethodError but got: ArgumentError ([Rational#initialize] wrong number of arguments(1 for 2))
3
4
  fails "Rational#coerce coerces to Rational, when given a Complex" # Expected nil == [(5/1), (3/4)] to be truthy but was false
4
5
  fails "Rational#coerce raises an error when passed a BigDecimal" # Expected TypeError (/BigDecimal can't be coerced into Rational/) but no exception was raised (nil was returned)
5
6
  fails "Rational#marshal_dump dumps numerator and denominator"
@@ -62,7 +62,6 @@ opal_filter "regular_expressions" do
62
62
  fails "Regexp.compile given a String with escaped characters returns a Regexp with the input String's encoding" # NameError: uninitialized constant Encoding::Shift_JIS
63
63
  fails "Regexp.compile works by default for subclasses with overridden #initialize" # Expected /hi/ (Regexp) to be kind of RegexpSpecsSubclass
64
64
  fails "Regexp.escape sets the encoding of the result to BINARY if any non-US-ASCII characters are present in an input String with invalid encoding" # Expected true to be false
65
- fails "Regexp.last_match returns nil when there is no match" # NoMethodError: undefined method `[]' for nil
66
65
  fails "Regexp.new given a String accepts an Integer of two or more options ORed together as the second argument" # Expected 0 == 0 to be falsy but was true
67
66
  fails "Regexp.new given a String raises a RegexpError when passed an incorrect regexp"
68
67
  fails "Regexp.new given a String with escaped characters raises a RegexpError if \\x is not followed by any hexadecimal digits"
@@ -170,9 +170,9 @@ RSpec.describe Opal::Compiler do
170
170
  end
171
171
 
172
172
  describe '#autoload' do
173
- it 'ignores autoload outside of context class' do
173
+ it 'parses and resolve second #autoload arguments in top scope' do
174
174
  compiler = compiler_for(%Q{autoload :Whatever, "#{__FILE__}"})
175
- expect(compiler.requires).to eq([])
175
+ expect(compiler.requires).to eq([__FILE__])
176
176
  end
177
177
 
178
178
  it 'parses and resolve second #autoload arguments' do
@@ -82,6 +82,7 @@ class OSpecFormatter
82
82
  'node' => NodeJSFormatter,
83
83
  'nodejs' => NodeJSFormatter,
84
84
  'gjs' => ColoredDottedFormatter,
85
+ 'quickjs' => ColoredDottedFormatter,
85
86
  'nodedoc' => NodeJSDocFormatter,
86
87
  'nodejsdoc' => NodeJSDocFormatter,
87
88
  'dotted' => DottedFormatter
data/stdlib/benchmark.rb CHANGED
@@ -519,6 +519,20 @@ module Benchmark
519
519
  [@label, @utime, @stime, @cutime, @cstime, @real]
520
520
  end
521
521
 
522
+ #
523
+ # Returns a hash containing the same data as `to_a`.
524
+ #
525
+ def to_h
526
+ {
527
+ label: @label,
528
+ utime: @utime,
529
+ stime: @stime,
530
+ cutime: @cutime,
531
+ cstime: @cstime,
532
+ real: @real
533
+ }
534
+ end
535
+
522
536
  protected
523
537
 
524
538
  #
data/stdlib/buffer.rb CHANGED
@@ -39,4 +39,8 @@ class Buffer
39
39
  def view(offset = nil, length = nil)
40
40
  View.new(self, offset, length)
41
41
  end
42
+
43
+ def to_s
44
+ to_a.to_a.pack('c*')
45
+ end
42
46
  end
@@ -1,5 +1,7 @@
1
1
  `/* global Java */`
2
2
 
3
+ require 'corelib/file'
4
+
3
5
  class File
4
6
  def self.read(path)
5
7
  %x(
data/stdlib/native.rb CHANGED
@@ -529,74 +529,79 @@ class NilClass
529
529
  end
530
530
  end
531
531
 
532
- class Hash
533
- alias _initialize initialize
534
-
535
- def initialize(defaults = undefined, &block)
536
- %x{
537
- if (defaults != null &&
538
- (defaults.constructor === undefined ||
539
- defaults.constructor === Object)) {
540
- var smap = self.$$smap,
541
- keys = self.$$keys,
542
- key, value;
543
-
544
- for (key in defaults) {
545
- value = defaults[key];
546
-
547
- if (value &&
548
- (value.constructor === undefined ||
549
- value.constructor === Object)) {
550
- smap[key] = #{Hash.new(`value`)};
551
- } else if (value && value.$$is_array) {
552
- value = value.map(function(item) {
553
- if (item &&
554
- (item.constructor === undefined ||
555
- item.constructor === Object)) {
556
- return #{Hash.new(`item`)};
557
- }
558
-
559
- return #{Native(`item`)};
560
- });
561
- smap[key] = value
562
- } else {
563
- smap[key] = #{Native(`value`)};
532
+ # Running this code twice results in an infinite loop. While it's true
533
+ # that we shouldn't run this file twice, there are certain cases, like
534
+ # for example live reload, when this may happen.
535
+ unless Hash.method_defined? :_initialize
536
+ class Hash
537
+ alias _initialize initialize
538
+
539
+ def initialize(defaults = undefined, &block)
540
+ %x{
541
+ if (defaults != null &&
542
+ (defaults.constructor === undefined ||
543
+ defaults.constructor === Object)) {
544
+ var smap = self.$$smap,
545
+ keys = self.$$keys,
546
+ key, value;
547
+
548
+ for (key in defaults) {
549
+ value = defaults[key];
550
+
551
+ if (value &&
552
+ (value.constructor === undefined ||
553
+ value.constructor === Object)) {
554
+ smap[key] = #{Hash.new(`value`)};
555
+ } else if (value && value.$$is_array) {
556
+ value = value.map(function(item) {
557
+ if (item &&
558
+ (item.constructor === undefined ||
559
+ item.constructor === Object)) {
560
+ return #{Hash.new(`item`)};
561
+ }
562
+
563
+ return #{Native(`item`)};
564
+ });
565
+ smap[key] = value
566
+ } else {
567
+ smap[key] = #{Native(`value`)};
568
+ }
569
+
570
+ keys.push(key);
564
571
  }
565
572
 
566
- keys.push(key);
573
+ return self;
567
574
  }
568
575
 
569
- return self;
576
+ return #{_initialize(defaults, &block)};
570
577
  }
578
+ end
571
579
 
572
- return #{_initialize(defaults, &block)};
573
- }
574
- end
580
+ # @return a JavaScript object with the same keys but calling #to_n on
581
+ # all values.
582
+ def to_n
583
+ %x{
584
+ var result = {},
585
+ keys = self.$$keys,
586
+ smap = self.$$smap,
587
+ key, value;
575
588
 
576
- # @return a JavaScript object with the same keys but calling #to_n on
577
- # all values.
578
- def to_n
579
- %x{
580
- var result = {},
581
- keys = self.$$keys,
582
- smap = self.$$smap,
583
- key, value;
584
-
585
- for (var i = 0, length = keys.length; i < length; i++) {
586
- key = keys[i];
587
-
588
- if (key.$$is_string) {
589
- value = smap[key];
590
- } else {
591
- key = key.key;
592
- value = key.value;
589
+ for (var i = 0, length = keys.length; i < length; i++) {
590
+ key = keys[i];
591
+
592
+ if (key.$$is_string) {
593
+ value = smap[key];
594
+ } else {
595
+ key = key.key;
596
+ value = key.value;
597
+ }
598
+
599
+ result[key] = #{Native.try_convert(`value`, `value`)};
593
600
  }
594
601
 
595
- result[key] = #{Native.try_convert(`value`, `value`)};
602
+ return result;
596
603
  }
597
-
598
- return result;
599
- }
604
+ end
600
605
  end
601
606
  end
602
607
 
@@ -0,0 +1,110 @@
1
+ ARGF = Object.new
2
+
3
+ class << ARGF
4
+ include Enumerable
5
+
6
+ def inspect
7
+ 'ARGF'
8
+ end
9
+
10
+ def argv
11
+ ARGV
12
+ end
13
+
14
+ def file
15
+ fn = filename
16
+ if fn == '-'
17
+ $stdin
18
+ else
19
+ @file ||= File.open(fn, 'r')
20
+ end
21
+ end
22
+
23
+ def filename
24
+ return @filename if @filename
25
+ if argv == ['-']
26
+ '-'
27
+ elsif argv == []
28
+ @last_filename || '-'
29
+ else
30
+ @file = nil
31
+ @filename = @last_filename = argv.shift
32
+ end
33
+ end
34
+
35
+ def close
36
+ file.close
37
+ @filename = nil
38
+ self
39
+ end
40
+
41
+ def closed?
42
+ file.closed?
43
+ end
44
+
45
+ def each(*args, &block)
46
+ return enum_for(:each) unless block_given?
47
+
48
+ while (l = gets(*args))
49
+ yield(l)
50
+ end
51
+ end
52
+
53
+ def gets(*args)
54
+ s = file.gets(*args)
55
+ if s.nil?
56
+ close
57
+ s = file.gets(*args)
58
+ end
59
+ @lineno += 1 if s
60
+ s
61
+ end
62
+
63
+ def read(len = nil)
64
+ buf = ''
65
+ loop do
66
+ r = file.read(len)
67
+ if r
68
+ buf += r
69
+ len -= r.length
70
+ end
71
+ file.close
72
+ break if len && len > 0 && @filename
73
+ end
74
+ end
75
+
76
+ def readlines(*args)
77
+ each(*args).to_a
78
+ end
79
+
80
+ attr_accessor :lineno
81
+
82
+ def rewind
83
+ @lineno = 1
84
+ f = file
85
+ begin
86
+ f.rewind
87
+ rescue
88
+ nil
89
+ end
90
+ 0
91
+ end
92
+
93
+ def fileno
94
+ return 0 if !@filename && @last_filename
95
+ file.fileno
96
+ end
97
+
98
+ def eof?
99
+ file.eof?
100
+ end
101
+
102
+ alias to_io file
103
+ alias to_i fileno
104
+ alias skip close
105
+ alias path filename
106
+ alias each_line each
107
+ alias eof eof?
108
+ end
109
+
110
+ ARGF.lineno = 1