pax_global_header 0000666 0000000 0000000 00000000064 12735757532 0014532 g ustar 00root root 0000000 0000000 52 comment=307ae868f90f4ee1b73ebe4596e0394237dacce8
golang-github-jtacoma-uritemplates-1.0.0/ 0000775 0000000 0000000 00000000000 12735757532 0020407 5 ustar 00root root 0000000 0000000 golang-github-jtacoma-uritemplates-1.0.0/.gitignore 0000664 0000000 0000000 00000000374 12735757532 0022403 0 ustar 00root root 0000000 0000000 # Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
golang-github-jtacoma-uritemplates-1.0.0/.gitmodules 0000664 0000000 0000000 00000000137 12735757532 0022565 0 ustar 00root root 0000000 0000000 [submodule "tests"]
path = tests
url = https://github.com/uri-templates/uritemplate-test.git
golang-github-jtacoma-uritemplates-1.0.0/.godocdown.md 0000664 0000000 0000000 00000000602 12735757532 0022770 0 ustar 00root root 0000000 0000000 {{ .EmitHeader }}
[](https://travis-ci.org/jtacoma/uritemplates) [](https://coveralls.io/r/jtacoma/uritemplates)
{{ .EmitSynopsis }}
## License
Use of this source code is governed by a BSD-style license that can be found in
the LICENSE file.
golang-github-jtacoma-uritemplates-1.0.0/.travis.yml 0000664 0000000 0000000 00000000015 12735757532 0022514 0 ustar 00root root 0000000 0000000 language: go
golang-github-jtacoma-uritemplates-1.0.0/LICENSE 0000664 0000000 0000000 00000002706 12735757532 0021421 0 ustar 00root root 0000000 0000000 Copyright (c) 2013 Joshua Tacoma. 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.
golang-github-jtacoma-uritemplates-1.0.0/README.md 0000664 0000000 0000000 00000001515 12735757532 0021670 0 ustar 00root root 0000000 0000000 # uritemplates
--
import "github.com/jtacoma/uritemplates"
[](https://travis-ci.org/jtacoma/uritemplates) [](https://coveralls.io/r/jtacoma/uritemplates)
Package uritemplates is a level 4 implementation of RFC 6570 (URI
Template, http://tools.ietf.org/html/rfc6570).
To use uritemplates, parse a template string and expand it with a value
map:
template, _ := uritemplates.Parse("https://api.github.com/repos{/user,repo}")
values := make(map[string]interface{})
values["user"] = "jtacoma"
values["repo"] = "uritemplates"
expanded, _ := template.Expand(values)
fmt.Printf(expanded)
## License
Use of this source code is governed by a BSD-style license that can be found in
the LICENSE file.
golang-github-jtacoma-uritemplates-1.0.0/tests/ 0000775 0000000 0000000 00000000000 12735757532 0021551 5 ustar 00root root 0000000 0000000 golang-github-jtacoma-uritemplates-1.0.0/uritemplates.go 0000664 0000000 0000000 00000021273 12735757532 0023461 0 ustar 00root root 0000000 0000000 // Copyright 2013 Joshua Tacoma. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package uritemplates is a level 4 implementation of RFC 6570 (URI
// Template, http://tools.ietf.org/html/rfc6570).
//
// To use uritemplates, parse a template string and expand it with a value
// map:
//
// template, _ := uritemplates.Parse("https://api.github.com/repos{/user,repo}")
// values := make(map[string]interface{})
// values["user"] = "jtacoma"
// values["repo"] = "uritemplates"
// expanded, _ := template.Expand(values)
// fmt.Printf(expanded)
//
package uritemplates
import (
"bytes"
"errors"
"fmt"
"reflect"
"regexp"
"strconv"
"strings"
)
var (
unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]")
reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]")
validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$")
hex = []byte("0123456789ABCDEF")
)
func pctEncode(src []byte) []byte {
dst := make([]byte, len(src)*3)
for i, b := range src {
buf := dst[i*3 : i*3+3]
buf[0] = 0x25
buf[1] = hex[b/16]
buf[2] = hex[b%16]
}
return dst
}
func escape(s string, allowReserved bool) (escaped string) {
if allowReserved {
escaped = string(reserved.ReplaceAllFunc([]byte(s), pctEncode))
} else {
escaped = string(unreserved.ReplaceAllFunc([]byte(s), pctEncode))
}
return escaped
}
// A UriTemplate is a parsed representation of a URI template.
type UriTemplate struct {
raw string
parts []templatePart
}
// Parse parses a URI template string into a UriTemplate object.
func Parse(rawtemplate string) (template *UriTemplate, err error) {
template = new(UriTemplate)
template.raw = rawtemplate
split := strings.Split(rawtemplate, "{")
template.parts = make([]templatePart, len(split)*2-1)
for i, s := range split {
if i == 0 {
if strings.Contains(s, "}") {
err = errors.New("unexpected }")
break
}
template.parts[i].raw = s
} else {
subsplit := strings.Split(s, "}")
if len(subsplit) != 2 {
err = errors.New("malformed template")
break
}
expression := subsplit[0]
template.parts[i*2-1], err = parseExpression(expression)
if err != nil {
break
}
template.parts[i*2].raw = subsplit[1]
}
}
if err != nil {
template = nil
}
return template, err
}
func (t UriTemplate) String() string {
return t.raw
}
type templatePart struct {
raw string
terms []templateTerm
first string
sep string
named bool
ifemp string
allowReserved bool
}
type templateTerm struct {
name string
explode bool
truncate int
}
func parseExpression(expression string) (result templatePart, err error) {
switch expression[0] {
case '+':
result.sep = ","
result.allowReserved = true
expression = expression[1:]
case '.':
result.first = "."
result.sep = "."
expression = expression[1:]
case '/':
result.first = "/"
result.sep = "/"
expression = expression[1:]
case ';':
result.first = ";"
result.sep = ";"
result.named = true
expression = expression[1:]
case '?':
result.first = "?"
result.sep = "&"
result.named = true
result.ifemp = "="
expression = expression[1:]
case '&':
result.first = "&"
result.sep = "&"
result.named = true
result.ifemp = "="
expression = expression[1:]
case '#':
result.first = "#"
result.sep = ","
result.allowReserved = true
expression = expression[1:]
default:
result.sep = ","
}
rawterms := strings.Split(expression, ",")
result.terms = make([]templateTerm, len(rawterms))
for i, raw := range rawterms {
result.terms[i], err = parseTerm(raw)
if err != nil {
break
}
}
return result, err
}
func parseTerm(term string) (result templateTerm, err error) {
if strings.HasSuffix(term, "*") {
result.explode = true
term = term[:len(term)-1]
}
split := strings.Split(term, ":")
if len(split) == 1 {
result.name = term
} else if len(split) == 2 {
result.name = split[0]
var parsed int64
parsed, err = strconv.ParseInt(split[1], 10, 0)
result.truncate = int(parsed)
} else {
err = errors.New("multiple colons in same term")
}
if !validname.MatchString(result.name) {
err = errors.New("not a valid name: " + result.name)
}
if result.explode && result.truncate > 0 {
err = errors.New("both explode and prefix modifers on same term")
}
return result, err
}
// Names returns the names of all variables within the template.
func (self *UriTemplate) Names() []string {
names := make([]string, 0, len(self.parts))
for _, p := range self.parts {
if len(p.raw) > 0 || len(p.terms) == 0 {
continue
}
for _, term := range p.terms {
names = append(names, term.name)
}
}
return names
}
// Expand expands a URI template with a set of values to produce a string.
func (self *UriTemplate) Expand(value interface{}) (string, error) {
values, ismap := value.(map[string]interface{})
if !ismap {
if m, ismap := struct2map(value); !ismap {
return "", errors.New("expected map[string]interface{}, struct, or pointer to struct.")
} else {
return self.Expand(m)
}
}
var buf bytes.Buffer
for _, p := range self.parts {
err := p.expand(&buf, values)
if err != nil {
return "", err
}
}
return buf.String(), nil
}
func (self *templatePart) expand(buf *bytes.Buffer, values map[string]interface{}) error {
if len(self.raw) > 0 {
buf.WriteString(self.raw)
return nil
}
var zeroLen = buf.Len()
buf.WriteString(self.first)
var firstLen = buf.Len()
for _, term := range self.terms {
value, exists := values[term.name]
if !exists {
continue
}
if buf.Len() != firstLen {
buf.WriteString(self.sep)
}
switch v := value.(type) {
case string:
self.expandString(buf, term, v)
case []interface{}:
self.expandArray(buf, term, v)
case map[string]interface{}:
if term.truncate > 0 {
return errors.New("cannot truncate a map expansion")
}
self.expandMap(buf, term, v)
default:
if m, ismap := struct2map(value); ismap {
if term.truncate > 0 {
return errors.New("cannot truncate a map expansion")
}
self.expandMap(buf, term, m)
} else {
str := fmt.Sprintf("%v", value)
self.expandString(buf, term, str)
}
}
}
if buf.Len() == firstLen {
original := buf.Bytes()[:zeroLen]
buf.Reset()
buf.Write(original)
}
return nil
}
func (self *templatePart) expandName(buf *bytes.Buffer, name string, empty bool) {
if self.named {
buf.WriteString(name)
if empty {
buf.WriteString(self.ifemp)
} else {
buf.WriteString("=")
}
}
}
func (self *templatePart) expandString(buf *bytes.Buffer, t templateTerm, s string) {
if len(s) > t.truncate && t.truncate > 0 {
s = s[:t.truncate]
}
self.expandName(buf, t.name, len(s) == 0)
buf.WriteString(escape(s, self.allowReserved))
}
func (self *templatePart) expandArray(buf *bytes.Buffer, t templateTerm, a []interface{}) {
if len(a) == 0 {
return
} else if !t.explode {
self.expandName(buf, t.name, false)
}
for i, value := range a {
if t.explode && i > 0 {
buf.WriteString(self.sep)
} else if i > 0 {
buf.WriteString(",")
}
var s string
switch v := value.(type) {
case string:
s = v
default:
s = fmt.Sprintf("%v", v)
}
if len(s) > t.truncate && t.truncate > 0 {
s = s[:t.truncate]
}
if self.named && t.explode {
self.expandName(buf, t.name, len(s) == 0)
}
buf.WriteString(escape(s, self.allowReserved))
}
}
func (self *templatePart) expandMap(buf *bytes.Buffer, t templateTerm, m map[string]interface{}) {
if len(m) == 0 {
return
}
if !t.explode {
self.expandName(buf, t.name, len(m) == 0)
}
var firstLen = buf.Len()
for k, value := range m {
if firstLen != buf.Len() {
if t.explode {
buf.WriteString(self.sep)
} else {
buf.WriteString(",")
}
}
var s string
switch v := value.(type) {
case string:
s = v
default:
s = fmt.Sprintf("%v", v)
}
if t.explode {
buf.WriteString(escape(k, self.allowReserved))
buf.WriteRune('=')
buf.WriteString(escape(s, self.allowReserved))
} else {
buf.WriteString(escape(k, self.allowReserved))
buf.WriteRune(',')
buf.WriteString(escape(s, self.allowReserved))
}
}
}
func struct2map(v interface{}) (map[string]interface{}, bool) {
value := reflect.ValueOf(v)
switch value.Type().Kind() {
case reflect.Ptr:
return struct2map(value.Elem().Interface())
case reflect.Struct:
m := make(map[string]interface{})
for i := 0; i < value.NumField(); i++ {
tag := value.Type().Field(i).Tag
var name string
if strings.Contains(string(tag), ":") {
name = tag.Get("uri")
} else {
name = strings.TrimSpace(string(tag))
}
if len(name) == 0 {
name = value.Type().Field(i).Name
}
m[name] = value.Field(i).Interface()
}
return m, true
}
return nil, false
}
golang-github-jtacoma-uritemplates-1.0.0/uritemplates_test.go 0000664 0000000 0000000 00000013311 12735757532 0024512 0 ustar 00root root 0000000 0000000 // Copyright 2013 Joshua Tacoma. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uritemplates
import (
"encoding/json"
"os"
"reflect"
"testing"
)
type spec struct {
title string
values map[string]interface{}
tests []specTest
}
type specTest struct {
template string
expected []string
}
func loadSpec(t *testing.T, path string) []spec {
file, err := os.Open(path)
if err != nil {
t.Errorf("Failed to load test specification: %s", err)
}
stat, _ := file.Stat()
buffer := make([]byte, stat.Size())
_, err = file.Read(buffer)
if err != nil {
t.Errorf("Failed to load test specification: %s", err)
}
var root_ interface{}
err = json.Unmarshal(buffer, &root_)
if err != nil {
t.Errorf("Failed to load test specification: %s", err)
}
root := root_.(map[string]interface{})
results := make([]spec, 1024)
i := -1
for title, spec_ := range root {
i = i + 1
results[i].title = title
specMap := spec_.(map[string]interface{})
results[i].values = specMap["variables"].(map[string]interface{})
tests := specMap["testcases"].([]interface{})
results[i].tests = make([]specTest, len(tests))
for k, test_ := range tests {
test := test_.([]interface{})
results[i].tests[k].template = test[0].(string)
switch typ := test[1].(type) {
case string:
results[i].tests[k].expected = make([]string, 1)
results[i].tests[k].expected[0] = test[1].(string)
case []interface{}:
arr := test[1].([]interface{})
results[i].tests[k].expected = make([]string, len(arr))
for m, s := range arr {
results[i].tests[k].expected[m] = s.(string)
}
case bool:
results[i].tests[k].expected = make([]string, 0)
default:
t.Errorf("Unrecognized value type %v", typ)
}
}
}
return results
}
func runSpec(t *testing.T, path string) {
var spec = loadSpec(t, path)
for _, group := range spec {
for _, test := range group.tests {
template, err := Parse(test.template)
if err != nil {
if len(test.expected) > 0 {
t.Errorf("%s: %s %v", group.title, err, test.template)
}
continue
}
result, err := template.Expand(group.values)
if err != nil {
if len(test.expected) > 0 {
t.Errorf("%s: %s %v", group.title, err, test.template)
}
continue
} else if len(test.expected) == 0 {
t.Errorf("%s: should have failed while parsing or expanding %v but got %v", group.title, test.template, result)
continue
}
pass := false
for _, expected := range test.expected {
if result == expected {
pass = true
}
}
if !pass {
t.Errorf("%s: expected %v, but got %v", group.title, test.expected[0], result)
}
}
}
}
func TestExtended(t *testing.T) {
runSpec(t, "tests/extended-tests.json")
}
func TestNegative(t *testing.T) {
runSpec(t, "tests/negative-tests.json")
}
func TestSpecExamples(t *testing.T) {
runSpec(t, "tests/spec-examples.json")
}
var parse_tests = []struct {
Template string
ParseOk bool
}{
{
// Syntax error, too many colons:
"{opts:1:2}",
false,
},
}
func TestParse(t *testing.T) {
for itest, test := range parse_tests {
if _, err := Parse(test.Template); err != nil {
if test.ParseOk {
t.Errorf("%v", err)
}
} else if !test.ParseOk {
t.Errorf("%d: expected error, got none.", itest)
}
}
}
type Location struct {
Path []interface{} `uri:"path"`
Version int `json:"version"`
Opts Options `opts`
}
type Options struct {
Format string `uri:"fmt"`
}
var expand_tests = []struct {
Source interface{}
Template string
Expected string
ExpandOk bool
Names []string
}{
{
// General struct expansion:
Location{
Path: []interface{}{"main", "quux"},
Version: 2,
Opts: Options{
Format: "pdf",
},
},
"{/path*,Version}{?opts*}",
"/main/quux/2?fmt=pdf",
true,
[]string{"path", "Version", "opts"},
}, {
// Pointer to struct:
&Location{Opts: Options{Format: "pdf"}},
"{?opts*}",
"?fmt=pdf",
true,
[]string{"opts"},
}, {
// Map expansion cannot be truncated:
Location{Opts: Options{Format: "pdf"}},
"{?opts:3}",
"",
false,
[]string{"opts"},
}, {
// Map whose values are not all strings:
map[string]interface{}{
"one": map[string]interface{}{
"two": 42,
},
},
"{?one*}",
"?two=42",
true,
[]string{"one"},
}, {
// Value of inappropriate type:
42,
"{?one*}",
"",
false,
[]string{"one"},
}, {
// Truncated array whose values are not all strings:
map[string]interface{}{"one": []interface{}{1234}},
"{?one:3}",
"?one=123",
true,
[]string{"one"},
},
}
func TestUriTemplate_Expand(t *testing.T) {
for itest, test := range expand_tests {
if template, err := Parse(test.Template); err != nil {
t.Errorf("%d: %v", itest, err)
} else if names := template.Names(); !reflect.DeepEqual(names, test.Names) {
t.Errorf("%d: expected names %v, got %v", itest, test.Names, names)
} else if expanded, err := template.Expand(test.Source); err != nil {
if test.ExpandOk {
t.Errorf("%d: unexpected error: %v", itest, err)
}
} else if !test.ExpandOk {
t.Errorf("%d: expected error, got none.", itest, err)
} else if expanded != test.Expected {
t.Errorf("%d: expected %v, got %v", itest, test.Expected, expanded)
}
}
}
func BenchmarkParse(b *testing.B) {
for i := 0; i < b.N; i++ {
Parse("http://localhost:6060{/type,path}{.fmt}{?q*}")
}
}
func BenchmarkExpand(b *testing.B) {
templ, _ := Parse("http://localhost:6060{/type,path}{.fmt}{?q*}")
data := map[string]interface{}{
"type": "pkg",
"path": [...]string{"github.com", "jtacoma", "uritemplates"},
"q": map[string]interface{}{
"somequery": "x!@#$",
"other": "y&*()",
},
}
for i := 0; i < b.N; i++ {
templ.Expand(data)
}
}
pax_global_header 0000666 0000000 0000000 00000000064 12207277062 0014517 g ustar 00root root 0000000 0000000 52 comment=fdd5d611a849b922c2ff40fc3997fd265dd14c02
golang-github-jtacoma-uritemplates-1.0.0/tests/ 0000775 0000000 0000000 00000000000 12207277062 0021536 5 ustar 00root root 0000000 0000000 golang-github-jtacoma-uritemplates-1.0.0/tests/README.md 0000664 0000000 0000000 00000006147 12207277062 0023025 0 ustar 00root root 0000000 0000000
URI Template Tests
==================
This is a set of tests for implementations of
[RFC6570](http://tools.ietf.org/html/rfc6570) - URI Template. It is designed
to be reused by any implementation, to improve interoperability and
implementation quality.
If your project uses Git for version control, you can make uritemplate-tests into a [submodule](http://help.github.com/submodules/).
Test Format
-----------
Each test file is a [JSON](http://tools.ietf.org/html/RFC6627) document
containing an object whose properties are groups of related tests.
Alternatively, all tests are available in XML as well, with the XML files
being generated by transform-json-tests.xslt which uses json2xml.xslt as a
general-purpose JSON-to-XML parsing library.
Each group, in turn, is an object with three children:
* level - the level of the tests covered, as per the RFC (optional; if absent,
assume level 4).
* variables - an object representing the variables that are available to the
tests in the suite
* testcases - a list of testcases, where each case is a two-member list, the
first being the template, the second being the result of expanding the
template with the provided variables.
Note that the result string can be a few different things:
* string - if the second member is a string, the result of expansion is
expected to match it, character-for-character.
* list - if the second member is a list of strings, the result of expansion
is expected to match one of them; this allows for templates that can
expand into different, equally-acceptable URIs.
* false - if the second member is boolean false, expansion is expected to
fail (i.e., the template was invalid).
For example:
{
"Level 1 Examples" :
{
"level": 1,
"variables": {
"var" : "value",
"hello" : "Hello World!"
},
"testcases" : [
["{var}", "value"],
["{hello}", "Hello%20World%21"]
]
}
}
Tests Included
--------------
The following test files are included:
* spec-examples.json - The complete set of example templates from the RFC
* spec-examples-by-section.json - The examples, section by section
* extended-tests.json - more complex test cases
* negative-tests.json - invalid templates
For all these test files, XML versions with the names *.xml can be
generated with the transform-json-tests.xslt XSLT stylesheet. The XSLT
contains the names of the above test files as a parameter, and can be
started with any XML as input (i.e., the XML input is ignored).
License
-------
Copyright 2011-2012 The Authors
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.
golang-github-jtacoma-uritemplates-1.0.0/tests/extended-tests.json 0000664 0000000 0000000 00000013513 12207277062 0025374 0 ustar 00root root 0000000 0000000 {
"Additional Examples 1":{
"level":4,
"variables":{
"id" : "person",
"token" : "12345",
"fields" : ["id", "name", "picture"],
"format" : "json",
"q" : "URI Templates",
"page" : "5",
"lang" : "en",
"geocode" : ["37.76","-122.427"],
"first_name" : "John",
"last.name" : "Doe",
"Some%20Thing" : "foo",
"number" : 6,
"long" : 37.76,
"lat" : -122.427,
"group_id" : "12345",
"query" : "PREFIX dc: SELECT ?book ?who WHERE { ?book dc:creator ?who }",
"uri" : "http://example.org/?uri=http%3A%2F%2Fexample.org%2F",
"word" : "drücken",
"Stra%C3%9Fe" : "Grüner Weg",
"random" : "šö䟜ñꀣ¥‡ÑÒÓÔÕÖרÙÚàáâãäåæçÿ",
"assoc_special_chars" :
{ "šö䟜ñꀣ¥‡ÑÒÓÔÕ" : "ÖרÙÚàáâãäåæçÿ" }
},
"testcases":[
[ "{/id*}" , "/person" ],
[ "{/id*}{?fields,first_name,last.name,token}" , [
"/person?fields=id,name,picture&first_name=John&last.name=Doe&token=12345",
"/person?fields=id,picture,name&first_name=John&last.name=Doe&token=12345",
"/person?fields=picture,name,id&first_name=John&last.name=Doe&token=12345",
"/person?fields=picture,id,name&first_name=John&last.name=Doe&token=12345",
"/person?fields=name,picture,id&first_name=John&last.name=Doe&token=12345",
"/person?fields=name,id,picture&first_name=John&last.name=Doe&token=12345"]
],
["/search.{format}{?q,geocode,lang,locale,page,result_type}",
[ "/search.json?q=URI%20Templates&geocode=37.76,-122.427&lang=en&page=5",
"/search.json?q=URI%20Templates&geocode=-122.427,37.76&lang=en&page=5"]
],
["/test{/Some%20Thing}", "/test/foo" ],
["/set{?number}", "/set?number=6"],
["/loc{?long,lat}" , "/loc?long=37.76&lat=-122.427"],
["/base{/group_id,first_name}/pages{/page,lang}{?format,q}","/base/12345/John/pages/5/en?format=json&q=URI%20Templates"],
["/sparql{?query}", "/sparql?query=PREFIX%20dc%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%20SELECT%20%3Fbook%20%3Fwho%20WHERE%20%7B%20%3Fbook%20dc%3Acreator%20%3Fwho%20%7D"],
["/go{?uri}", "/go?uri=http%3A%2F%2Fexample.org%2F%3Furi%3Dhttp%253A%252F%252Fexample.org%252F"],
["/service{?word}", "/service?word=dr%C3%BCcken"],
["/lookup{?Stra%C3%9Fe}", "/lookup?Stra%C3%9Fe=Gr%C3%BCner%20Weg"],
["{random}" , "%C5%A1%C3%B6%C3%A4%C5%B8%C5%93%C3%B1%C3%AA%E2%82%AC%C2%A3%C2%A5%E2%80%A1%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%BF"],
["{?assoc_special_chars*}", "?%C5%A1%C3%B6%C3%A4%C5%B8%C5%93%C3%B1%C3%AA%E2%82%AC%C2%A3%C2%A5%E2%80%A1%C3%91%C3%92%C3%93%C3%94%C3%95=%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%BF"]
]
},
"Additional Examples 2":{
"level":4,
"variables":{
"id" : ["person","albums"],
"token" : "12345",
"fields" : ["id", "name", "picture"],
"format" : "atom",
"q" : "URI Templates",
"page" : "10",
"start" : "5",
"lang" : "en",
"geocode" : ["37.76","-122.427"]
},
"testcases":[
[ "{/id*}" , ["/person/albums","/albums/person"] ],
[ "{/id*}{?fields,token}" , [
"/person/albums?fields=id,name,picture&token=12345",
"/person/albums?fields=id,picture,name&token=12345",
"/person/albums?fields=picture,name,id&token=12345",
"/person/albums?fields=picture,id,name&token=12345",
"/person/albums?fields=name,picture,id&token=12345",
"/person/albums?fields=name,id,picture&token=12345",
"/albums/person?fields=id,name,picture&token=12345",
"/albums/person?fields=id,picture,name&token=12345",
"/albums/person?fields=picture,name,id&token=12345",
"/albums/person?fields=picture,id,name&token=12345",
"/albums/person?fields=name,picture,id&token=12345",
"/albums/person?fields=name,id,picture&token=12345"]
]
]
},
"Additional Examples 3: Empty Variables":{
"variables" : {
"empty_list" : [],
"empty_assoc" : {}
},
"testcases":[
[ "{/empty_list}", [ "" ] ],
[ "{/empty_list*}", [ "" ] ],
[ "{?empty_list}", [ ""] ],
[ "{?empty_list*}", [ "" ] ],
[ "{?empty_assoc}", [ "" ] ],
[ "{?empty_assoc*}", [ "" ] ]
]
},
"Additional Examples 4: Numeric Keys":{
"variables" : {
"42" : "The Answer to the Ultimate Question of Life, the Universe, and Everything",
"1337" : ["leet", "as","it", "can","be"],
"german" : {
"11": "elf",
"12": "zwölf"
}
},
"testcases":[
[ "{42}", "The%20Answer%20to%20the%20Ultimate%20Question%20of%20Life%2C%20the%20Universe%2C%20and%20Everything"],
[ "{?42}", "?42=The%20Answer%20to%20the%20Ultimate%20Question%20of%20Life%2C%20the%20Universe%2C%20and%20Everything"],
[ "{1337}", "leet,as,it,can,be"],
[ "{?1337*}", "?1337=leet&1337=as&1337=it&1337=can&1337=be"],
[ "{?german*}", [ "?11=elf&12=zw%C3%B6lf", "?12=zw%C3%B6lf&11=elf"] ]
]
}
}
golang-github-jtacoma-uritemplates-1.0.0/tests/json2xml.xslt 0000664 0000000 0000000 00000017430 12207277062 0024233 0 ustar 00root root 0000000 0000000
\b
\v
\f