const chai = require('chai');
const expect = chai.expect;

const Opal = require('../src/index').Opal;

describe('Opal Node Runtime', function () {

  describe('When loaded', function() {
    it('should export Opal object', function() {
      expect(Opal).not.be.null;
    });

    it('should preserve Function methods', function() {
      const fundamentalObjects = [
        Function,
        Boolean,
        Error,
        Number,
        Date,
        String,
        RegExp,
        Array
      ];
      for (let index in fundamentalObjects) {
        const fundamentalObject = fundamentalObjects[index];
        expect(fundamentalObject.call, `${fundamentalObject.name}.call should be a Function`).to.be.an.instanceof(Function);
        expect(fundamentalObject.apply, `${fundamentalObject.name}.apply should be a Function`).to.be.an.instanceof(Function);
        expect(fundamentalObject.bind, `${fundamentalObject.name}.bind should be a Function`).to.be.an.instanceof(Function);
      }
    });
  });

  describe('When pathname module is loaded', function() {
    it('should register Pathname methods', function() {
      Opal.load('pathname');
      var Pathname = Opal.const_get_relative([], 'Pathname');
      var path1 = Pathname.$new('/foo/bar');
      var path2 = Pathname.$new('qux');
      expect(path1['$+'](path2)['$to_path']()).to.equal('/foo/bar/qux');
    });
  });

  describe('When nodejs module is loaded', function() {
    it('should register Node.js specific implementations', function() {
      Opal.load('nodejs');
      var Dir = Opal.const_get_relative([], 'Dir');
      var currentDir = Dir['$pwd']();
      expect(currentDir).to.equal(process.cwd());
    });
  });
});

@@ -52,16 +52,409 @@
 xpect;%0A%0A
+const fundamentalObjects = %5B%0A  Function,%0A  Boolean,%0A  Error,%0A  Number,%0A  Date,%0A  String,%0A  RegExp,%0A  Array%0A%5D;%0A%0A// Save the current value of toString() for each object, before the import of Opal%0Aconst fundamentalToStringValues = %5B%5D%0Afor (let index in fundamentalObjects) %7B%0A  const fundamentalObject = fundamentalObjects%5Bindex%5D;%0A  fundamentalToStringValues.push(fundamentalObject.toString());%0A%7D%0A%0A
 const Op
@@ -488,16 +488,16 @@
 ).Opal;%0A
-
 %0Adescrib
@@ -723,178 +723,9 @@
 ) %7B%0A
-      const fundamentalObjects = %5B%0A        Function,%0A        Boolean,%0A        Error,%0A        Number,%0A        Date,%0A        String,%0A        RegExp,%0A        Array%0A      %5D;
 %0A
+
     
@@ -1071,32 +1071,32 @@
 ceof(Function);%0A
-
         expect(f
@@ -1200,24 +1200,293 @@
 (Function);%0A
+        expect(fundamentalObject.toString(), %60$%7BfundamentalObject.name%7D.toString should be native function%60).to.be.equal(fundamentalToStringValues%5Bindex%5D);%0A        expect(fundamentalObject.toString()).to.equal(%60function $%7BfundamentalObject.name%7D() %7B %5Bnative code%5D %7D%60);%0A
       %7D%0A    

add tests to cover changes about toString()