require 'test_helper'

class UriTemplateTest < Minitest::Test
  def test_uri_template_format
    schema = JSONSchemer.schema({ 'type' => 'string', 'format' => 'uri-template' })

    [
      '{justright:9999}',
      '{#has.lots.of.dots}',
      '{an_underscore}',
      '{=reserved}',
      '{,reserved}',
      '{!reserved}',
      '{@reserved}',
      '{|reserved}',
      '{percent%20encoded}',
      '{UPCASED}',
      'literal%20encoded',
      "literal🖥️unicode"
    ].each do |data|
      assert(schema.valid?(data), data)
    end

    [
      '{toobig:10000}',
      '{#.starts.with.dot}',
      '{#ends.with.dot.}',
      '{a-dash}',
      '{doubleexplode**}',
      '{percent%unencoded}',
      '{not percent encoded}',
      '{hangingprefix:}',
      '{prefixandexplode:3*',
      '{explodeandprefix*:3',
      '{varchar🖥️unicode}',
      '{{double curly}}',
      '{hanging curlopen',
      'hanging curlyclose}',
      'literal space',
      'literal"dquote',
      "literal'squote",
      'literal%percent',
      'literal<lessthan',
      'literal>greaterthan',
      'literal\backslash',
      'literal^caret',
      'literal`backtick',
      'literal{curlyopen',
      'literal}curlyclose',
      'literal|bar'
    ].each do |data|
      refute(schema.valid?(data), data)
    end

    # examples from https://datatracker.ietf.org/doc/html/rfc6570
    [
      'http://example.com/~{username}/',
      'http://example.com/dictionary/{term:1}/{term}',
      'http://example.com/search{?q,lang}',
      'http://www.example.com/foo{?query,number}',
      '{var}',
      '{hello}',
      '{+var}',
      '{+hello}',
      '{+path}/here',
      'here?ref={+path}',
      'X{#var}',
      'X{#hello}',
      'map?{x,y}',
      '{x,hello,y}',
      '{+x,hello,y}',
      '{#x,hello,y}',
      '{#path,x}/here',
      'X{.var}',
      'X{.x,y}',
      '{/var}',
      '{/var,x}/here',
      '{;x,y}',
      '{;x,y,empty}',
      '{?x,y}',
      '{?x,y,empty}',
      '?fixed=yes{&x}',
      '{&x,y,empty}',
      '{var:3}',
      '{var:30}',
      '{list}',
      '{list*}',
      '{keys}',
      '{keys*}',
      '{+path:6}/here',
      '{+list}',
      '{+list*}',
      '{+keys}',
      '{+keys*}',
      '{#path:6}/here',
      '{#list}',
      '{#list*}',
      '{#keys}',
      '{#keys*}',
      'X{.var:3}',
      'X{.list}',
      'X{.list*}',
      'X{.keys}',
      'X{.keys*}',
      '{/var:1,var}',
      '{/list}',
      '{/list*}',
      '{/list*,path:4}',
      '{/keys}',
      '{/keys*}',
      '{;hello:5}',
      '{;list}',
      '{;list*}',
      '{;keys}',
      '{;keys*}',
      '{?var:3}',
      '{?list}',
      '{?list*}',
      '{?keys}',
      '{?keys*}',
      '{&var:3}',
      '{&list}',
      '{&list*}',
      '{&keys}',
      '{&keys*}',
      'find{?year*}',
      'www{.dom*}',
      '{count}',
      '{count*}',
      '{/count}',
      '{/count*}',
      '{;count}',
      '{;count*}',
      '{?count}',
      '{?count*}',
      '{&count*}',
      '{var}',
      '{hello}',
      '{half}',
      'O{empty}X',
      'O{undef}X',
      '{x,y}',
      '{x,hello,y}',
      '?{x,empty}',
      '?{x,undef}',
      '?{undef,y}',
      '{var:3}',
      '{var:30}',
      '{list}',
      '{list*}',
      '{keys}',
      '{keys*}',
      '{+var}',
      '{+hello}',
      '{+half}',
      '{base}index',
      '{+base}index',
      'O{+empty}X',
      'O{+undef}X',
      '{+path}/here',
      'here?ref={+path}',
      'up{+path}{var}/here',
      '{+x,hello,y}',
      '{+path,x}/here',
      '{+path:6}/here',
      '{+list}',
      '{+list*}',
      '{+keys}',
      '{+keys*}',
      '{#var}',
      '{#hello}',
      '{#half}',
      'foo{#empty}',
      'foo{#undef}',
      '{#x,hello,y}',
      '{#path,x}/here',
      '{#path:6}/here',
      '{#list}',
      '{#list*}',
      '{#keys}',
      '{#keys*}',
      '{.who}',
      '{.who,who}',
      '{.half,who}',
      'www{.dom*}',
      'X{.var}',
      'X{.empty}',
      'X{.undef}',
      'X{.var:3}',
      'X{.list}',
      'X{.list*}',
      'X{.keys}',
      'X{.keys*}',
      'X{.empty_keys}',
      'X{.empty_keys*}',
      '{/who}',
      '{/who,who}',
      '{/half,who}',
      '{/who,dub}',
      '{/var}',
      '{/var,empty}',
      '{/var,undef}',
      '{/var,x}/here',
      '{/var:1,var}',
      '{/list}',
      '{/list*}',
      '{/list*,path:4}',
      '{/keys}',
      '{/keys*}',
      '{;who}',
      '{;half}',
      '{;empty}',
      '{;v,empty,who}',
      '{;v,bar,who}',
      '{;x,y}',
      '{;x,y,empty}',
      '{;x,y,undef}',
      '{;hello:5}',
      '{;list}',
      '{;list*}',
      '{;keys}',
      '{;keys*}',
      '{?who}',
      '{?half}',
      '{?x,y}',
      '{?x,y,empty}',
      '{?x,y,undef}',
      '{?var:3}',
      '{?list}',
      '{?list*}',
      '{?keys}',
      '{?keys*}',
      '{&who}',
      '{&half}',
      '?fixed=yes{&x}',
      '{&x,y,empty}',
      '{&x,y,undef}',
      '{&var:3}',
      '{&list}',
      '{&list*}',
      '{&keys}',
      '{&keys*}'
    ].each do |data|
      assert(schema.valid?(data), data)
    end
  end
end
