/*
 * Copyright (C) 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.gson.functional;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import junit.framework.TestCase;

public class MapAsArrayTypeAdapterTest extends TestCase {

  public void testSerializeComplexMapWithTypeAdapter() {
    Type type = new TypeToken<Map<Point, String>>() {}.getType();
    Gson gson = new GsonBuilder()
        .enableComplexMapKeySerialization()
        .create();

    Map<Point, String> original = new LinkedHashMap<Point, String>();
    original.put(new Point(5, 5), "a");
    original.put(new Point(8, 8), "b");
    String json = gson.toJson(original, type);
    assertEquals("[[{\"x\":5,\"y\":5},\"a\"],[{\"x\":8,\"y\":8},\"b\"]]", json);
    assertEquals(original, gson.<Map<Point, String>>fromJson(json, type));

    // test that registering a type adapter for one map doesn't interfere with others
    Map<String, Boolean> otherMap = new LinkedHashMap<String, Boolean>();
    otherMap.put("t", true);
    otherMap.put("f", false);
    assertEquals("{\"t\":true,\"f\":false}",
        gson.toJson(otherMap, Map.class));
    assertEquals("{\"t\":true,\"f\":false}",
        gson.toJson(otherMap, new TypeToken<Map<String, Boolean>>() {}.getType()));
    assertEquals(otherMap, gson.<Object>fromJson("{\"t\":true,\"f\":false}",
        new TypeToken<Map<String, Boolean>>() {}.getType()));
  }

  public void testTwoTypesCollapseToOneSerialize() {
    Gson gson = new GsonBuilder()
        .enableComplexMapKeySerialization()
        .create();

    Map<Number, String> original = new LinkedHashMap<Number, String>();
    original.put(new Double(1.0), "a");
    original.put(new Float(1.0), "b");
    try {
      gson.toJson(original, new TypeToken<Map<Number, String>>() {}.getType());
      fail();
    } catch (JsonSyntaxException expected) {
    }
  }

  public void testTwoTypesCollapseToOneDeserialize() {
    Gson gson = new GsonBuilder()
        .enableComplexMapKeySerialization()
        .create();

    String s = "[[\"1.00\",\"a\"],[\"1.0\",\"b\"]]";
    try {
      gson.fromJson(s, new TypeToken<Map<Double, String>>() {}.getType());
      fail();
    } catch (JsonSyntaxException expected) {
    }
  }

  static class Point {
    int x;
    int y;
    Point(int x, int y) {
      this.x = x;
      this.y = y;
    }
    Point() {}
    @Override public boolean equals(Object o) {
      return o instanceof Point && ((Point) o).x == x && ((Point) o).y == y;
    }
    @Override public int hashCode() {
      return x * 37 + y;
    }
    @Override public String toString() {
      return "(" + x + "," + y + ")";
    }
  }
}

@@ -2932,24 +2932,687 @@
  %7B%0A    %7D%0A  %7D
+%0A  %0A  public void testMultipleEnableComplexKeyRegistrationHasNoEffect() throws Exception %7B%0A    Type type = new TypeToken%3CMap%3CPoint, String%3E%3E() %7B%7D.getType();%0A    Gson gson = new GsonBuilder()%0A        .enableComplexMapKeySerialization()%0A        .enableComplexMapKeySerialization()%0A        .create();%0A%0A    Map%3CPoint, String%3E original = new LinkedHashMap%3CPoint, String%3E();%0A    original.put(new Point(6, 5), %22abc%22);%0A    original.put(new Point(1, 8), %22def%22);%0A    String json = gson.toJson(original, type);%0A    assertEquals(%22%5B%5B%7B%5C%22x%5C%22:6,%5C%22y%5C%22:5%7D,%5C%22abc%5C%22%5D,%5B%7B%5C%22x%5C%22:1,%5C%22y%5C%22:8%7D,%5C%22def%5C%22%5D%5D%22, json);%0A    assertEquals(original, gson.%3CMap%3CPoint, String%3E%3EfromJson(json, type));%0A  %7D
 %0A%0A  static c

Add test for multiple calls to register complex map key serialization.