package route

import (
	"reflect"
	"testing"

	"github.com/Telenav/osrm-backend/integration/api/osrm"
)

func TestRouteRequestURI(t *testing.T) {
	cases := []struct {
		r      Request
		expect string
	}{
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesValueTrue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=true",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesValuePolyline6,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?geometries=polyline6",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewValueFull,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?overview=full",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightValueFalse,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?continue_straight=false",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{0, 3, 5},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?waypoints=0;3;5",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?bearings=0,0;120,180;360,150",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?radiuses=1.2;0.6;1000.1;unlimited",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?generate_hints=false",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?hints=LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk;NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?approaches=curb;curb;unrestricted",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?exclude=toll,motoway,ferry",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     "100",
				Steps:            true,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=100&steps=true",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValueGeojson,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 3},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=5&annotations=true&continue_straight=true&geometries=geojson&overview=false&steps=true&waypoints=2;3",
		},
	}

	for _, c := range cases {
		s := c.r.RequestURI()
		if s != c.expect {
			t.Errorf("%v QueryString(), expect %s, but got %s", c.r, c.expect, s)
		}
	}

}

func TestParseRouteRequest(t *testing.T) {

	cases := []struct {
		requestURI string
		expect     *Request
		expectFail bool
	}{
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?&alternatives=5&annotations=true&steps=true&geometries=polyline&overview=false&continue_straight=true&waypoints=2;4;6&bearings=0,0;120,180;360,150&radiuses=1.2;0.6;1000.1;unlimited&generate_hints=false&hints=LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk;NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk&approaches=curb;curb;unrestricted&exclude=toll,motoway,ferry",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValuePolyline,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 4, 6},
			},
			false,
		},
		{
			"http:
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValuePolyline,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 4, 6},
			},
			false,
		},
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"http:
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=-1&annotations=tru,&steps=alse,",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767.json", nil, true},
		{"/route/v1/driving/-122.006349,   37.364336;-121.875654,37.313767", nil, true},
		{"/route/v1/driving/-122.006349,37.364336;-121.875654,   37.313767?alternatives=-1", nil, true},
	}

	for _, c := range cases {
		r, err := ParseRequestURI(c.requestURI)
		if err != nil && c.expectFail {
			continue 
		} else if (err != nil && !c.expectFail) || (err == nil && c.expectFail) {
			t.Errorf("parse %s expect fail %t, but got err %v", c.requestURI, c.expectFail, err)
			continue
		}

		if !reflect.DeepEqual(*r, *c.expect) {
			t.Errorf("parse %s, expect %v, but got %v", c.requestURI, c.expect, r)
		}

	}
}
package route

import (
	"reflect"
	"testing"

	"github.com/Telenav/osrm-backend/integration/api/osrm"
)

func TestRouteRequestURI(t *testing.T) {
	cases := []struct {
		r      Request
		expect string
	}{
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesValueTrue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=true",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesValuePolyline6,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?geometries=polyline6",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewValueFull,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?overview=full",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightValueFalse,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?continue_straight=false",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{0, 3, 5},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?waypoints=0;3;5",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?bearings=0,0;120,180;360,150",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?radiuses=1.2;0.6;1000.1;unlimited",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?generate_hints=false",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?hints=LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk;NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?approaches=curb;curb;unrestricted",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?exclude=toll,motoway,ferry",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     "100",
				Steps:            true,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=100&steps=true",
		},
		{
			Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValueGeojson,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 3},
			},
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=5&annotations=true&continue_straight=true&geometries=geojson&overview=false&steps=true&waypoints=2;3",
		},
	}

	for _, c := range cases {
		s := c.r.RequestURI()
		if s != c.expect {
			t.Errorf("%v QueryString(), expect %s, but got %s", c.r, c.expect, s)
		}
	}

}

func TestParseRouteRequest(t *testing.T) {

	cases := []struct {
		requestURI string
		expect     *Request
		expectFail bool
	}{
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?&alternatives=5&annotations=true&steps=true&geometries=polyline&overview=false&continue_straight=true&waypoints=2;4;6&bearings=0,0;120,180;360,150&radiuses=1.2;0.6;1000.1;unlimited&generate_hints=false&hints=LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk;NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk&approaches=curb;curb;unrestricted&exclude=toll,motoway,ferry",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValuePolyline,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 4, 6},
			},
			false,
		},
		{
			"http://localhost:8080/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=5&annotations=true&steps=true&geometries=polyline&overview=false&continue_straight=true&waypoints=2;4;6&bearings=0,0;120,180;360,150&radiuses=1.2;0.6;1000.1;unlimited&generate_hints=false&hints=LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk;NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk&approaches=curb;curb;unrestricted&exclude=toll,motoway,ferry",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{"0,0", "120,180", "360,150"},
				Radiuses:         osrm.OptionElements{"1.2", "0.6", "1000.1", "unlimited"},
				GenerateHints:    false,
				Hints:            osrm.OptionElements{"LZ42gzaeNoMwAAAABwAAAAkAAAB3AAAAIccvQp1vtUDjiPpAQ9TUQjAAAAAHAAAACQAAAHcAAAC1VgAArlS6-DEjOgKzVLr4cCI6AgEAjwXzVESk", "NoM5g0CDOYMAAAAAKgAAAAAAAAApAAAAAAAAAJ_1F0IAAAAAkhEUQgAAAAAqAAAAAAAAACkAAAC1VgAA-FK8-GZeOQI6U7z451w5AgAA7wLzVESk"},
				Approaches:       osrm.OptionElements{"curb", "curb", "unrestricted"},
				Exclude:          osrm.OptionClasses{"toll", "motoway", "ferry"},
				Alternatives:     "5",
				Steps:            true,
				Annotations:      OptionAnnotationsValueTrue,
				Geometries:       OptionGeometriesValuePolyline,
				Overview:         OptionOverviewValueFalse,
				ContinueStraight: OptionContinueStraightValueTrue,
				Waypoints:        osrm.CoordinateIndexes{2, 4, 6},
			},
			false,
		},
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"http://localhost:8080/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"route/v1/driving/-122.006349,37.364336;-121.875654,37.313767",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{
			"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767?alternatives=-1&annotations=tru,&steps=alse,",
			&Request{
				Service:          "route",
				Version:          "v1",
				Profile:          "driving",
				Coordinates:      osrm.Coordinates{osrm.Coordinate{Lat: 37.364336, Lon: -122.006349}, osrm.Coordinate{Lat: 37.313767, Lon: -121.875654}},
				Bearings:         osrm.OptionElements{},
				Radiuses:         osrm.OptionElements{},
				GenerateHints:    osrm.OptionGenerateHintsDefaultValue,
				Hints:            osrm.OptionElements{},
				Approaches:       osrm.OptionElements{},
				Exclude:          osrm.OptionClasses{},
				Alternatives:     OptionAlternativesDefaultValue,
				Steps:            OptionStepsDefaultValue,
				Annotations:      OptionAnnotationsDefaultValue,
				Geometries:       OptionGeometriesDefaultValue,
				Overview:         OptionOverviewDefaultValue,
				ContinueStraight: OptionContinueStraightDefaultValue,
				Waypoints:        osrm.CoordinateIndexes{},
			},
			false,
		},
		{"/route/v1/driving/-122.006349,37.364336;-121.875654,37.313767.json", nil, true},
		{"/route/v1/driving/-122.006349,   37.364336;-121.875654,37.313767", nil, true},
		{"/route/v1/driving/-122.006349,37.364336;-121.875654,   37.313767?alternatives=-1", nil, true},
	}

	for _, c := range cases {
		r, err := ParseRequestURI(c.requestURI)
		if err != nil && c.expectFail {
			continue //right
		} else if (err != nil && !c.expectFail) || (err == nil && c.expectFail) {
			t.Errorf("parse %s expect fail %t, but got err %v", c.requestURI, c.expectFail, err)
			continue
		}

		if !reflect.DeepEqual(*r, *c.expect) {
			t.Errorf("parse %s, expect %v, but got %v", c.requestURI, c.expect, r)
		}

	}
}
