// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.

package rpc

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"testing"
)

const (
	float64v1         float64 = 1
	float64v2         float64 = 2
	float64v3         float64 = 3
	float64v4         float64 = 4
	float64v5         float64 = 5
	float64v6         float64 = 6
	float64v123       float64 = 123
	float64v123dot123 float64 = 123.123
	float64v456       float64 = 456
	float64v10086     float64 = 10086
)

type Parameter1 struct {
	StringValue1  string
	IntegerValue1 int
	BooleanValue1 bool
}

type TestService interface {
	ME1(string) error
	ME2(string) (string, error)
	M1(string) error
	M2(string, string) error
	M3(int) error
	M4(bool) error
	M5(string, int, bool) error
	M6(string, []int) error
	M7(int, []string) error
	M8([5]int, [4]string) error
	M9(*bool, *[2]string, *[]int) error
	M10(Parameter1, *Parameter1) error
	M11([]Parameter1) error
	M12(map[string]Parameter1) error
}

type TestImpl struct {
	err                  error
	stringValue1         string
	stringValue2         string
	integerValue1        int
	booleanValue1        bool
	integerSliceValue1   []int
	stringSliceValue1    []string
	integerArray5Value1  [5]int
	stringArray4Value1   [4]string
	boolPointer1         *bool
	stringArray2Pointer1 *[2]string
	integerSlicePointer1 *[]int
	structValue1         Parameter1
	structPointer1       *Parameter1
	structArray1         []Parameter1
	structMap1           map[string]Parameter1
}

func (impl *TestImpl) Clear() {

	impl.err = nil
	impl.stringValue1 = ""
	impl.stringValue2 = ""
	impl.integerValue1 = 0
	impl.booleanValue1 = false
	impl.integerSliceValue1 = nil
	impl.stringSliceValue1 = nil
	impl.integerArray5Value1 = [5]int{0, 0, 0, 0, 0}
	impl.stringArray4Value1 = [4]string{"", "", "", ""}
	impl.boolPointer1 = nil
	impl.stringArray2Pointer1 = nil
	impl.integerSlicePointer1 = nil
}

func (impl *TestImpl) ME1(p1 string) error {

	impl.stringValue1 = p1
	return impl.err
}

func (impl *TestImpl) ME2(p1 string) (string, error) {

	impl.stringValue1 = p1
	return "", impl.err
}

func (impl *TestImpl) M1(p1 string) error {

	impl.stringValue1 = p1
	return nil
}

func (impl *TestImpl) M2(p1 string, p2 string) error {

	impl.stringValue1 = p1
	impl.stringValue2 = p2
	return nil
}

func (impl *TestImpl) M3(p1 int) error {

	impl.integerValue1 = p1
	return nil
}

func (impl *TestImpl) M4(p1 bool) error {

	impl.booleanValue1 = p1
	return nil
}

func (impl *TestImpl) M5(p1 string, p2 int, p3 bool) error {

	impl.stringValue1 = p1
	impl.integerValue1 = p2
	impl.booleanValue1 = p3
	return nil
}

func (impl *TestImpl) M6(p1 string, p2 []int) error {

	impl.stringValue1 = p1
	impl.integerSliceValue1 = p2
	return nil
}

func (impl *TestImpl) M7(p1 int, p2 []string) error {

	impl.integerValue1 = p1
	impl.stringSliceValue1 = p2
	return nil
}

func (impl *TestImpl) M8(p1 [5]int, p2 [4]string) error {

	impl.integerArray5Value1 = p1
	impl.stringArray4Value1 = p2
	return nil
}

func (impl *TestImpl) M9(p1 *bool, p2 *[2]string, p3 *[]int) error {

	impl.boolPointer1 = p1
	impl.stringArray2Pointer1 = p2
	impl.integerSlicePointer1 = p3
	return nil
}

func (impl *TestImpl) M10(p1 Parameter1, p2 *Parameter1) error {

	impl.structValue1 = p1
	impl.structPointer1 = p2
	return nil
}

func (impl *TestImpl) M11(p1 []Parameter1) error {

	impl.structArray1 = p1
	return nil
}

func (impl *TestImpl) M12(p1 map[string]Parameter1) error {

	impl.structMap1 = p1
	return nil
}

var testImpl = &TestImpl{}

var methodInvokerBuilder = &MethodInvokerBuilder{&ValueParserBuilder{}, map[reflect.Type]valueParser{}}

func NewTestService() TestService {
	return testImpl
}

var serviceValue = reflect.ValueOf(testImpl)
var serviceType = reflect.ValueOf(NewTestService).Type().Out(0)

func getInvoker(methodName string) (Handler, error) {

	method, ok := serviceType.MethodByName(methodName)
	if !ok {
		return nil, errors.New(fmt.Sprintf("未找到方法!"))
	}
	serviceName := strings.ToLower(fmt.Sprintf("%s.%s", serviceType.Name(), methodName))
	methodInvoker, err := methodInvokerBuilder.buildMethodInvoker(serviceName, method.Type, serviceValue.MethodByName(methodName).Call)
	if err != nil {
		return nil, err
	}
	return methodInvoker, nil
}

func getInvokerMapping() (map[string]Handler, error) {

	mapping := make(map[string]Handler, serviceType.NumMethod())
	for i := 0; i < serviceType.NumMethod(); i++ {
		method := serviceType.Method(i)
		methodInvoker, err := getInvoker(method.Name)
		if err != nil {
			return nil, err
		}
		mapping[strings.ToLower(fmt.Sprintf("/testservice/%s", method.Name))] = methodInvoker
	}
	return mapping, nil
}

func TestError(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		testImpl.err = errors.New("error1")
		parameters := []interface{}{
			"small",
		}
		_, err := invokerMapping["/testservice/me1"].Process(parameters)
		if err != testImpl.err {
			t.Fatalf("意外错误:%s", err.Error())
		}
	}
	{
		testImpl.Clear()
		testImpl.err = errors.New("error2")
		parameters := []interface{}{
			"small",
		}
		_, err := invokerMapping["/testservice/me2"].Process(parameters)
		if err != testImpl.err {
			t.Fatalf("意外错误:%s", err.Error())
		}
	}
}

func TestParameterCount(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			"big",
		}
		_, err := invokerMapping["/testservice/m1"].Process(parameters)
		if err == nil {
			t.Fatalf("意外的没有错误!")
		}
		if err.Error() != "参数长度错误!" {
			t.Fatalf("意外错误:%s", err.Error())
		}
	}
}

func TestString(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
		}
		_, err := invokerMapping["/testservice/m1"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.stringValue1 != "small" {
			t.Fatalf("stringValue1实际值为:%s", testImpl.stringValue1)
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			"big",
		}
		_, err := invokerMapping["/testservice/m2"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.stringValue1 != "small" {
			t.Fatalf("stringValue1实际值为:%s", testImpl.stringValue1)
		}
		if testImpl.stringValue2 != "big" {
			t.Fatalf("stringValue2实际值为:%s", testImpl.stringValue1)
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			nil,
		}
		_, err := invokerMapping["/testservice/m2"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.stringValue1 != "small" {
			t.Fatalf("stringValue1实际值为:%s", testImpl.stringValue1)
		}
		if testImpl.stringValue2 != "" {
			t.Fatalf("stringValue2实际值为:%s", testImpl.stringValue1)
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			[]interface{}{},
		}
		_, err := invokerMapping["/testservice/m2"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#2 无法解析!源类型:[]interface {},目标类型:String." {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
}

func TestNumber(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			float64v123,
		}
		_, err := invokerMapping["/testservice/m3"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerValue1 != 123 {
			t.Fatalf("integerValue1实际值为:%d", testImpl.integerValue1)
		}
	}
	{
		testImpl.Clear()
		mapping := []interface{}{
			float64v123dot123,
		}
		_, err := invokerMapping["/testservice/m3"].Process(mapping)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerValue1 != 123 {
			t.Fatalf("integerValue1实际值为:%d", testImpl.integerValue1)
		}
	}
}

func TestBoolean(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			true,
		}
		_, err := invokerMapping["/testservice/m4"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if !testImpl.booleanValue1 {
			t.Fatalf("booleanValue1实际值为:%t", testImpl.booleanValue1)
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			false,
		}
		_, err := invokerMapping["/testservice/m4"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.booleanValue1 {
			t.Fatalf("booleanValue1实际值为:%t", testImpl.booleanValue1)
		}
	}
}

func TestSimpleValue(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			float64v123,
			true,
		}
		_, err := invokerMapping["/testservice/m5"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.stringValue1 != "small" {
			t.Fatalf("stringValue1实际值为:%s", testImpl.stringValue1)
		}
		if testImpl.integerValue1 != 123 {
			t.Fatalf("integerValue1实际值为:%d", testImpl.integerValue1)
		}
		if !testImpl.booleanValue1 {
			t.Fatalf("booleanValue1实际值为:%t", testImpl.booleanValue1)
		}
	}
}

func TestSlice(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			"small",
			[]interface{}{
				float64v1,
				float64v2,
				float64v3,
			},
		}
		_, err := invokerMapping["/testservice/m6"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.stringValue1 != "small" {
			t.Fatalf("stringValue1实际值为:%s", testImpl.stringValue1)
		}
		if len(testImpl.integerSliceValue1) != 3 {
			t.Fatalf("integerSliceValue1实际长度为:%d", len(testImpl.integerSliceValue1))
		}
		if testImpl.integerSliceValue1[0] != 1 {
			t.Fatalf("integerSliceValue1#0实际值为:%d", testImpl.integerSliceValue1[0])
		}
		if testImpl.integerSliceValue1[1] != 2 {
			t.Fatalf("integerSliceValue1#1实际值为:%d", testImpl.integerSliceValue1[1])
		}
		if testImpl.integerSliceValue1[2] != 3 {
			t.Fatalf("integerSliceValue1#2实际值为:%d", testImpl.integerSliceValue1[2])
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			float64v10086,
			[]interface{}{
				"small",
				"big",
			},
		}
		_, err := invokerMapping["/testservice/m7"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerValue1 != 10086 {
			t.Fatalf("stringValue1实际值为:%d", testImpl.integerValue1)
		}
		if len(testImpl.stringSliceValue1) != 2 {
			t.Fatalf("istringSliceValue1实际长度为:%d", len(testImpl.stringSliceValue1))
		}
		if testImpl.stringSliceValue1[0] != "small" {
			t.Fatalf("stringSliceValue1#0实际值为:%s", testImpl.stringSliceValue1[0])
		}
		if testImpl.stringSliceValue1[1] != "big" {
			t.Fatalf("stringSliceValue1#1实际值为:%s", testImpl.stringSliceValue1[1])
		}
	}
}

func TestArray(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			[]interface{}{
				float64v5,
				float64v4,
				float64v3,
				float64v2,
				float64v1,
			},
			[]interface{}{
				"A",
				"B",
				"C",
				"D",
			},
		}
		_, err := invokerMapping["/testservice/m8"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerArray5Value1[0] != 5 {
			t.Fatalf("integerArray5Value1#0实际值为:%d", testImpl.integerArray5Value1[0])
		}
		if testImpl.integerArray5Value1[1] != 4 {
			t.Fatalf("integerArray5Value1#1实际值为:%d", testImpl.integerArray5Value1[1])
		}
		if testImpl.integerArray5Value1[2] != 3 {
			t.Fatalf("integerArray5Value1#2实际值为:%d", testImpl.integerArray5Value1[2])
		}
		if testImpl.integerArray5Value1[3] != 2 {
			t.Fatalf("integerArray5Value1#3实际值为:%d", testImpl.integerArray5Value1[3])
		}
		if testImpl.integerArray5Value1[4] != 1 {
			t.Fatalf("integerArray5Value1#4实际值为:%d", testImpl.integerArray5Value1[4])
		}
		if testImpl.stringArray4Value1[0] != "A" {
			t.Fatalf("stringArray4Value1#1实际值为:%s", testImpl.stringArray4Value1[0])
		}
		if testImpl.stringArray4Value1[1] != "B" {
			t.Fatalf("stringArray4Value1#2实际值为:%s", testImpl.stringArray4Value1[1])
		}
		if testImpl.stringArray4Value1[2] != "C" {
			t.Fatalf("stringArray4Value1#3实际值为:%s", testImpl.stringArray4Value1[2])
		}
		if testImpl.stringArray4Value1[3] != "D" {
			t.Fatalf("stringArray4Value1#4实际值为:%s", testImpl.stringArray4Value1[3])
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			[]interface{}{
				float64v6,
				float64v5,
				float64v4,
				float64v3,
				float64v2,
				float64v1,
			},
			[]interface{}{
				"A",
				"B",
				"C",
				"D",
			},
		}
		_, err := invokerMapping["/testservice/m8"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#1 数组长度匹配!期望长度:5,实际长度:6." {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
}

func TestPointer(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			[]interface{}{
				float64v5,
				float64v4,
				float64v3,
				float64v2,
				float64v1,
			},
			[]interface{}{
				"A",
				"B",
				"C",
				"D",
			},
		}
		_, err := invokerMapping["/testservice/m8"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerArray5Value1[0] != 5 {
			t.Fatalf("integerArray5Value1#0实际值为:%d", testImpl.integerArray5Value1[0])
		}
		if testImpl.integerArray5Value1[1] != 4 {
			t.Fatalf("integerArray5Value1#1实际值为:%d", testImpl.integerArray5Value1[1])
		}
		if testImpl.integerArray5Value1[2] != 3 {
			t.Fatalf("integerArray5Value1#2实际值为:%d", testImpl.integerArray5Value1[2])
		}
		if testImpl.integerArray5Value1[3] != 2 {
			t.Fatalf("integerArray5Value1#3实际值为:%d", testImpl.integerArray5Value1[3])
		}
		if testImpl.integerArray5Value1[4] != 1 {
			t.Fatalf("integerArray5Value1#4实际值为:%d", testImpl.integerArray5Value1[4])
		}
		if testImpl.stringArray4Value1[0] != "A" {
			t.Fatalf("stringArray4Value1#1实际值为:%s", testImpl.stringArray4Value1[0])
		}
		if testImpl.stringArray4Value1[1] != "B" {
			t.Fatalf("stringArray4Value1#2实际值为:%s", testImpl.stringArray4Value1[1])
		}
		if testImpl.stringArray4Value1[2] != "C" {
			t.Fatalf("stringArray4Value1#3实际值为:%s", testImpl.stringArray4Value1[2])
		}
		if testImpl.stringArray4Value1[3] != "D" {
			t.Fatalf("stringArray4Value1#4实际值为:%s", testImpl.stringArray4Value1[3])
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			false,
			[]interface{}{
				"A",
				"B",
			},
			[]interface{}{
				float64v123,
				float64v456,
			},
		}
		_, err := invokerMapping["/testservice/m9"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.boolPointer1 == nil {
			t.Fatal("boolPointer1不应为空!")
		}
		if *testImpl.boolPointer1 {
			t.Fatalf("booleanValue1实际值为:%t", *testImpl.boolPointer1)
		}
		if testImpl.integerSlicePointer1 == nil {
			t.Fatal("integerSlicePointer1不应为空!")
		}
		stringArray2 := *testImpl.stringArray2Pointer1
		if stringArray2[0] != "A" {
			t.Fatalf("stringArray2Pointer1#0实际值为:%s", stringArray2[0])
		}
		if stringArray2[1] != "B" {
			t.Fatalf("stringArray2Pointer1#1实际值为:%s", stringArray2[1])
		}
		if testImpl.stringArray2Pointer1 == nil {
			t.Fatal("tringArray2Pointer1不应为空!")
		}
		integerSlic := *testImpl.integerSlicePointer1
		if integerSlic[0] != 123 {
			t.Fatalf("integerSlicePointer1#0实际值为:%d", integerSlic[0])
		}
		if integerSlic[1] != 456 {
			t.Fatalf("integerSlicePointer1#1实际值为:%d", integerSlic[1])
		}
	}
}

func TestNil(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			nil,
			[]interface{}{
				"A",
				"B",
			},
			nil,
		}
		_, err := invokerMapping["/testservice/m9"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.boolPointer1 != nil {
			t.Fatal("boolPointer1应当为空!")
		}
		if testImpl.stringArray2Pointer1 == nil {
			t.Fatal("stringArray2Pointer1不应为空!")
		}
		stringArray2 := *testImpl.stringArray2Pointer1
		if stringArray2[0] != "A" {
			t.Fatalf("stringArray2Pointer1#0实际值为:%s", stringArray2[0])
		}
		if stringArray2[1] != "B" {
			t.Fatalf("stringArray2Pointer1#1实际值为:%s", stringArray2[1])
		}
		if testImpl.integerSlicePointer1 != nil {
			t.Fatal("integerSlicePointer1不应为空!")
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			nil,
			[]interface{}{
				"A",
				"B",
			},
			nil,
		}
		_, err := invokerMapping["/testservice/m9"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.boolPointer1 != nil {
			t.Fatal("boolPointer1应当为空!")
		}
		if testImpl.stringArray2Pointer1 == nil {
			t.Fatal("stringArray2Pointer1不应为空!")
		}
		stringArray2 := *testImpl.stringArray2Pointer1
		if stringArray2[0] != "A" {
			t.Fatalf("stringArray2Pointer1#0实际值为:%s", stringArray2[0])
		}
		if stringArray2[1] != "B" {
			t.Fatalf("stringArray2Pointer1#1实际值为:%s", stringArray2[1])
		}
		if testImpl.integerSlicePointer1 != nil {
			t.Fatal("integerSlicePointer1不应为空!")
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			float64v10086,
			nil,
		}
		_, err := invokerMapping["/testservice/m7"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerValue1 != 10086 {
			t.Fatalf("stringValue1实际值为:%d", testImpl.integerValue1)
		}
		if testImpl.stringSliceValue1 != nil {
			t.Fatal("boolPointer1应当为空!")
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			float64v10086,
			nil,
		}
		_, err := invokerMapping["/testservice/m7"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.integerValue1 != 10086 {
			t.Fatalf("stringValue1实际值为:%d", testImpl.integerValue1)
		}
		if testImpl.stringSliceValue1 != nil {
			t.Fatal("boolPointer1应当为空!")
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			nil,
		}
		_, err := invokerMapping["/testservice/m4"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#1 不能为空!" {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			nil,
		}
		_, err := invokerMapping["/testservice/m3"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#1 不能为空!" {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			[]interface{}{
				float64v5,
				float64v4,
				float64v3,
				float64v2,
				float64v1,
			},
			nil,
		}
		_, err := invokerMapping["/testservice/m8"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#2 不能为空!" {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
}

func TestStruct(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			map[string]interface{}{
				"StringValue1":  "A",
				"IntegerValue1": float64v1,
				"BooleanValue1": true,
			},
			map[string]interface{}{
				"StringValue1":  "B",
				"IntegerValue1": float64v2,
				"BooleanValue1": false,
			},
		}
		_, err := invokerMapping["/testservice/m10"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.structValue1.StringValue1 != "A" {
			t.Fatalf("structValue1.StringValue1实际值为:%s", testImpl.structValue1.StringValue1)
		}
		if testImpl.structValue1.IntegerValue1 != 1 {
			t.Fatalf("structValue1.IntegerValue1实际值为:%d", testImpl.structValue1.IntegerValue1)
		}
		if !testImpl.structValue1.BooleanValue1 {
			t.Fatalf("structValue1.BooleanValue1实际值为:%t", testImpl.structValue1.BooleanValue1)
		}
		if testImpl.structPointer1.StringValue1 != "B" {
			t.Fatalf("structPointer1.StringValue1实际值为:%s", testImpl.structPointer1.StringValue1)
		}
		if testImpl.structPointer1.IntegerValue1 != 2 {
			t.Fatalf("structPointer1.IntegerValue1实际值为:%d", testImpl.structPointer1.IntegerValue1)
		}
		if testImpl.structPointer1.BooleanValue1 {
			t.Fatalf("structPointer1.BooleanValue1实际值为:%t", testImpl.structPointer1.BooleanValue1)
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			map[string]interface{}{
				"StringValue1":  "A",
				"IntegerValue1": float64v1,
				"BooleanValue1": true,
			},
			nil,
		}
		_, err := invokerMapping["/testservice/m10"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.structValue1.StringValue1 != "A" {
			t.Fatalf("structValue1.StringValue1实际值为:%s", testImpl.structValue1.StringValue1)
		}
		if testImpl.structValue1.IntegerValue1 != 1 {
			t.Fatalf("structValue1.IntegerValue1实际值为:%d", testImpl.structValue1.IntegerValue1)
		}
		if !testImpl.structValue1.BooleanValue1 {
			t.Fatalf("structValue1.BooleanValue1实际值为:%t", testImpl.structValue1.BooleanValue1)
		}
		if testImpl.structPointer1 != nil {
			t.Fatal("structPointer1应当为空!")
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			nil,
			map[string]interface{}{
				"StringValue1":  "B",
				"IntegerValue1": float64v2,
				"BooleanValue1": false,
			},
		}
		_, err := invokerMapping["/testservice/m10"].Process(parameters)
		if err == nil {
			t.Fatal("意外没有错误!")
		}
		if err.Error() != "#1 不能为空!" {
			t.Fatalf("意外错误%s", err.Error())
		}
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			[]interface{}{
				map[string]interface{}{
					"StringValue1":  "A",
					"IntegerValue1": float64v1,
					"BooleanValue1": true,
				},
				map[string]interface{}{
					"StringValue1":  "B",
					"IntegerValue1": float64v2,
					"BooleanValue1": false,
				},
			},
		}
		_, err := invokerMapping["/testservice/m11"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.structArray1 == nil {
			t.Fatal("structArray1不应为空!")
		}
		if len(testImpl.structArray1) != 2 {
			t.Fatalf("structArray1实际长度为:%d", len(testImpl.integerSliceValue1))
		}
		if testImpl.structArray1[0].StringValue1 != "A" {
			t.Fatalf("structArray1[0].StringValue1实际值为:%s", testImpl.structPointer1.StringValue1)
		}
		if testImpl.structArray1[0].IntegerValue1 != 1 {
			t.Fatalf("structArray1[0].IntegerValue1实际值为:%d", testImpl.structValue1.IntegerValue1)
		}
		if !testImpl.structArray1[0].BooleanValue1 {
			t.Fatalf("structArray1[0].BooleanValue1实际值为:%t", testImpl.structValue1.BooleanValue1)
		}
		if testImpl.structArray1[1].StringValue1 != "B" {
			t.Fatalf("structArray1[1].StringValue1实际值为:%s", testImpl.structPointer1.StringValue1)
		}
		if testImpl.structArray1[1].IntegerValue1 != 2 {
			t.Fatalf("structArray1[1].IntegerValue1实际值为:%d", testImpl.structPointer1.IntegerValue1)
		}
		if testImpl.structArray1[1].BooleanValue1 {
			t.Fatalf("structArray1[1].BooleanValue1实际值为:%t", testImpl.structPointer1.BooleanValue1)
		}
	}
}

func TestMap(t *testing.T) {

	invokerMapping, err := getInvokerMapping()
	if err != nil {
		t.Fatalf("意外错误:%s", err.Error())
	}
	{
		testImpl.Clear()
		parameters := []interface{}{
			map[string]interface{}{
				"key1": map[string]interface{}{
					"StringValue1":  "A",
					"IntegerValue1": float64v1,
					"BooleanValue1": true,
				},
				"key2": map[string]interface{}{
					"StringValue1":  "B",
					"IntegerValue1": float64v2,
					"BooleanValue1": false,
				},
			},
		}
		_, err := invokerMapping["/testservice/m12"].Process(parameters)
		if err != nil {
			t.Fatalf("意外错误:%s", err.Error())
		}
		if testImpl.structMap1 == nil {
			t.Fatal("structMap1不应为空!")
		}
		if len(testImpl.structMap1) != 2 {
			t.Fatalf("structMap1实际长度为:%d", len(testImpl.integerSliceValue1))
		}
		if testImpl.structMap1["key1"].StringValue1 != "A" {
			t.Fatalf("structMap1[\"key1\"].StringValue1实际值为:%s", testImpl.structPointer1.StringValue1)
		}
		if testImpl.structMap1["key1"].IntegerValue1 != 1 {
			t.Fatalf("structMap1[\"key1\"].IntegerValue1实际值为:%d", testImpl.structValue1.IntegerValue1)
		}
		if !testImpl.structMap1["key1"].BooleanValue1 {
			t.Fatalf("structMap1[\"key1\"].BooleanValue1实际值为:%t", testImpl.structValue1.BooleanValue1)
		}
		if testImpl.structMap1["key2"].StringValue1 != "B" {
			t.Fatalf("structMap1[\"key2\"].StringValue1实际值为:%s", testImpl.structPointer1.StringValue1)
		}
		if testImpl.structMap1["key2"].IntegerValue1 != 2 {
			t.Fatalf("structMap1[\"key2\"].IntegerValue1实际值为:%d", testImpl.structPointer1.IntegerValue1)
		}
		if testImpl.structMap1["key2"].BooleanValue1 {
			t.Fatalf("structMap1[\"key2\"].BooleanValue1实际值为:%t", testImpl.structPointer1.BooleanValue1)
		}
	}
}
