<commit_before>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package entry

import (
	stdregexp "regexp"
	"strings"
	"testing"

	"github.com/issue9/assert"
	"github.com/issue9/mux/internal/syntax"
)

var _ Entry = &regexp{}

func TestNewRegexp(t *testing.T) {
	a := assert.New(t)

	pattern := "/posts/{id:\\d+}"
	r, err := newRegexp(&syntax.Syntax{
		Pattern:   pattern,
		HasParams: true,
		Type:      syntax.TypeRegexp,
		Patterns:  []string{"/posts/", "(?P<id>\\d+)"},
	})
	a.NotError(err).NotNil(r)
	a.Equal(r.pattern, pattern)
	a.Equal(r.expr.String(), "/posts/(?P<id>\\d+)")

	pattern = "/posts/{id}/page/{page:\\d+}/size/{:\\d+}"
	r, err = newRegexp(&syntax.Syntax{
		Pattern:   pattern,
		HasParams: true,
		Type:      syntax.TypeRegexp,
		Patterns:  []string{"/posts/", "(?P<id>[^/]+)", "/page/", "(?P<page>\\d+)", "/size/", "(\\d+)"},
	})
	a.NotError(err).NotNil(r)
	a.Equal(r.pattern, pattern)
	a.Equal(r.expr.String(), "/posts/(?P<id>[^/]+)/page/(?P<page>\\d+)/size/(\\d+)")
}

func TestRegexp_Match(t *testing.T) {
	a := assert.New(t)

	newMatcher(a, "/posts/{id:\\d+}").
		True("/posts/1", map[string]string{"id": "1"}).
		False("/posts/", nil).
		False("/posts", nil).
		False("/posts/id", nil).
		False("/posts/id.html/", nil).
		False("/posts/id.html/page", nil).
		False("/post/id", nil)

	newMatcher(a, "/posts/{id:\\d+}.html").
		True("/posts/1.html", map[string]string{"id": "1"}).
		False("/posts/", nil).
		False("/posts", nil).
		False("/posts/id", nil).
		False("/posts/id.html", nil).
		False("/posts/id.html/page", nil).
		False("/post/id", nil)

	newMatcher(a, "/posts/{id:[^/]+}.html").
		True("/posts/a.b.html", map[string]string{"id": "a.b"})

	newMatcher(a, "/posts/{id}/page/{page:\\d+}").
		True("/posts/1/page/1", map[string]string{"id": "1", "page": "1"}).
		True("/posts/1.html/page/1", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x", nil).
		False("/posts/id-1/page/1/", nil).
		False("/posts/id-1/page/1/size/1", nil)

	// size 为未命名参数
	newMatcher(a, "/posts/{id}/page/{page:\\d+}/size/{:\\d+}").
		True("/posts/1.html/page/1/size/11", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x/size/11", nil)

	newMatcher(a, "/users/{user:\\w+}/{repos}/pulls").
		False("/users/user/repos/pulls/number", nil)
}

func TestRegexp_match_wildcard(t *testing.T) {
	a := assert.New(t)

	newMatcher(a, "/posts/{id:\\d+}/*").
		False("/posts/1", nil).
		False("/posts", nil).
		True("/posts/1/", map[string]string{"id": "1"}).
		True("/posts/1/index.html", map[string]string{"id": "1"}).
		False("/posts/id.html/page", nil)

	newMatcher(a, "/posts/{id}/page/{page:\\d+}/*").
		False("/posts/1/page/1", nil).
		True("/posts/1.html/page/1/", map[string]string{"id": "1.html", "page": "1"}).
		True("/posts/1.html/page/1/index.html", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x/index.html", nil)

	// size 为未命名参数<commit_msg>[internal/entry] 添加测试内容<commit_after>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package entry

import (
	stdregexp "regexp"
	"strings"
	"testing"

	"github.com/issue9/assert"
	"github.com/issue9/mux/internal/syntax"
)

var _ Entry = &regexp{}

func TestNewRegexp(t *testing.T) {
	a := assert.New(t)

	pattern := "/posts/{id:\\d+}"
	r, err := newRegexp(&syntax.Syntax{
		Pattern:   pattern,
		HasParams: true,
		Type:      syntax.TypeRegexp,
		Patterns:  []string{"/posts/", "(?P<id>\\d+)"},
	})
	a.NotError(err).NotNil(r)
	a.Equal(r.pattern, pattern)
	a.Equal(r.expr.String(), "/posts/(?P<id>\\d+)")

	pattern = "/posts/{id}/page/{page:\\d+}/size/{:\\d+}"
	r, err = newRegexp(&syntax.Syntax{
		Pattern:   pattern,
		HasParams: true,
		Type:      syntax.TypeRegexp,
		Patterns:  []string{"/posts/", "(?P<id>[^/]+)", "/page/", "(?P<page>\\d+)", "/size/", "(\\d+)"},
	})
	a.NotError(err).NotNil(r)
	a.Equal(r.pattern, pattern)
	a.Equal(r.expr.String(), "/posts/(?P<id>[^/]+)/page/(?P<page>\\d+)/size/(\\d+)")
}

func TestRegexp_Match(t *testing.T) {
	a := assert.New(t)

	newMatcher(a, "/posts/{id:\\d+}").
		True("/posts/1", map[string]string{"id": "1"}).
		False("/posts/", nil).
		False("/posts", nil).
		False("/posts/id", nil).
		False("/posts/id.html/", nil).
		False("/posts/id.html/page", nil).
		False("/post/id", nil)

	newMatcher(a, "/posts/{id:\\d+}.html").
		True("/posts/1.html", map[string]string{"id": "1"}).
		False("/posts/", nil).
		False("/posts", nil).
		False("/posts/id", nil).
		False("/posts/id.html", nil).
		False("/posts/id.html/page", nil).
		False("/post/id", nil)

	newMatcher(a, "/posts/{id:[^/]+}.html").
		True("/posts/a.b.html", map[string]string{"id": "a.b"})

	newMatcher(a, "/posts/{id}/page/{page:\\d+}").
		True("/posts/1/page/1", map[string]string{"id": "1", "page": "1"}).
		True("/posts/1.html/page/1", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x", nil).
		False("/posts/id-1/page/1/", nil).
		False("/posts/id-1/page/1/size/1", nil)

	newMatcher(a, "/posts/{id:\\w+}{page:\\d+}").
		True("/posts/aa1", map[string]string{"id": "aa", "page": "1"})

	// size 为未命名参数
	newMatcher(a, "/posts/{id}/page/{page:\\d+}/size/{:\\d+}").
		True("/posts/1.html/page/1/size/11", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x/size/11", nil)

	newMatcher(a, "/users/{user:\\w+}/{repos}/pulls").
		False("/users/user/repos/pulls/number", nil)
}

func TestRegexp_match_wildcard(t *testing.T) {
	a := assert.New(t)

	newMatcher(a, "/posts/{id:\\d+}/*").
		False("/posts/1", nil).
		False("/posts", nil).
		True("/posts/1/", map[string]string{"id": "1"}).
		True("/posts/1/index.html", map[string]string{"id": "1"}).
		False("/posts/id.html/page", nil)

	newMatcher(a, "/posts/{id}/page/{page:\\d+}/*").
		False("/posts/1/page/1", nil).
		True("/posts/1.html/page/1/", map[string]string{"id": "1.html", "page": "1"}).
		True("/posts/1.html/page/1/index.html", map[string]string{"id": "1.html", "page": "1"}).
		False("/posts/1.html/page/x/index.html", nil)

	// size 为未命名参数
{'fraction_non_alphanumeric': 0.28661188980183666, 'fraction_numerical': 0.016110842597067826, 'mean_word_length': 3.6293810589112603, 'pattern_counts': {'":': 32, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4422106', 'n_tokens_mistral': 2728, 'n_tokens_neox': 2563, 'n_words': 407}