From 81ed564793609a32be20a569cc15da2cc02dd734 Mon Sep 17 00:00:00 2001 From: Cameron Moore Date: Sat, 23 Sep 2017 19:57:28 -0500 Subject: tpl: Add urls.Parse function Add a urls.Parse template function that front-ends url.Parse from the Go stdlib. Fixes #3849 --- tpl/urls/urls.go | 13 ++++++++++ tpl/urls/urls_test.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tpl/urls/urls_test.go (limited to 'tpl/urls') diff --git a/tpl/urls/urls.go b/tpl/urls/urls.go index 817ed8b15..d89069901 100644 --- a/tpl/urls/urls.go +++ b/tpl/urls/urls.go @@ -15,7 +15,9 @@ package urls import ( "errors" + "fmt" "html/template" + "net/url" "github.com/gohugoio/hugo/deps" "github.com/spf13/cast" @@ -43,6 +45,17 @@ func (ns *Namespace) AbsURL(a interface{}) (template.HTML, error) { return template.HTML(ns.deps.PathSpec.AbsURL(s, false)), nil } +// Parse parses rawurl into a URL structure. The rawurl may be relative or +// absolute. +func (ns *Namespace) Parse(rawurl interface{}) (*url.URL, error) { + s, err := cast.ToStringE(rawurl) + if err != nil { + return nil, fmt.Errorf("Error in Parse: %s", err) + } + + return url.Parse(s) +} + // RelURL takes a given string and prepends the relative path according to a // page's position in the project directory structure. func (ns *Namespace) RelURL(a interface{}) (template.HTML, error) { diff --git a/tpl/urls/urls_test.go b/tpl/urls/urls_test.go new file mode 100644 index 000000000..7bcef9cd5 --- /dev/null +++ b/tpl/urls/urls_test.go @@ -0,0 +1,68 @@ +// Copyright 2017 The Hugo Authors. All rights reserved. +// +// 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. + +package urls + +import ( + "fmt" + "net/url" + "testing" + + "github.com/gohugoio/hugo/deps" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ns = New(&deps.Deps{Cfg: viper.New()}) + +type tstNoStringer struct{} + +func TestParse(t *testing.T) { + t.Parallel() + + for i, test := range []struct { + rawurl interface{} + expect interface{} + }{ + { + "http://www.google.com", + &url.URL{ + Scheme: "http", + Host: "www.google.com", + }, + }, + { + "http://j@ne:password@google.com", + &url.URL{ + Scheme: "http", + User: url.UserPassword("j@ne", "password"), + Host: "google.com", + }, + }, + // errors + {tstNoStringer{}, false}, + } { + errMsg := fmt.Sprintf("[%d] %v", i, test) + + result, err := ns.Parse(test.rawurl) + + if b, ok := test.expect.(bool); ok && !b { + require.Error(t, err, errMsg) + continue + } + + require.NoError(t, err, errMsg) + assert.Equal(t, test.expect, result, errMsg) + } +} -- cgit v1.2.3