// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Flags: --expose-debug-as debug
// Test the mirror object for regular error objects

function MirrorRefCache(json_refs) {
  var tmp = eval('(' + json_refs + ')');
  this.refs_ = [];
  for (var i = 0; i < tmp.length; i++) {
    this.refs_[tmp[i].handle] = tmp[i];
  }
}

MirrorRefCache.prototype.lookup = function(handle) {
  return this.refs_[handle];
}

function testErrorMirror(e) {
  // Create mirror and JSON representation.
  var mirror = debug.MakeMirror(e);
  var serializer = debug.MakeMirrorSerializer();
  var json = JSON.stringify(serializer.serializeValue(mirror));
  var refs = new MirrorRefCache(
      JSON.stringify(serializer.serializeReferencedObjects()));

  // Check the mirror hierachy.
  assertTrue(mirror instanceof debug.Mirror);
  assertTrue(mirror instanceof debug.ValueMirror);
  assertTrue(mirror instanceof debug.ObjectMirror);
  assertTrue(mirror instanceof debug.ErrorMirror);

  // Check the mirror properties.
  assertTrue(mirror.isError());
  assertEquals('error', mirror.type());
  assertFalse(mirror.isPrimitive());
  assertEquals(mirror.message(), e.message, 'source');

  // Parse JSON representation and check.
  var fromJSON = eval('(' + json + ')');
  assertEquals('error', fromJSON.type);
  assertEquals('Error', fromJSON.className);
  if (e.message) {
    var found_message = false;
    for (var i in fromJSON.properties) {
      var p = fromJSON.properties[i];
      print(p.name);
      if (p.name == 'message') {
        assertEquals(e.message, refs.lookup(p.ref).value);
        found_message = true;
      }
    }
    assertTrue(found_message, 'Property message not found');
  }

  // Check the formatted text (regress 1231579).
  assertEquals(fromJSON.text, e.toString(), 'toString');
}


// Test Date values.
testErrorMirror(new Error());
testErrorMirror(new Error('This does not work'));
testErrorMirror(new Error(123+456));
testErrorMirror(new EvalError('EvalError'));
testErrorMirror(new RangeError('RangeError'));
testErrorMirror(new ReferenceError('ReferenceError'));
testErrorMirror(new SyntaxError('SyntaxError'));
testErrorMirror(new TypeError('TypeError'));
testErrorMirror(new URIError('URIError'));
