1// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// author sigu-399 16// author-github https://github.com/sigu-399 17// author-mail sigu.399@gmail.com 18// 19// repository-name jsonreference 20// repository-desc An implementation of JSON Reference - Go language 21// 22// description Automated tests on package. 23// 24// created 03-03-2013 25 26package jsonreference 27 28import ( 29 "testing" 30 31 "github.com/go-openapi/jsonpointer" 32 "github.com/stretchr/testify/assert" 33) 34 35func TestIsRoot(t *testing.T) { 36 in := "#" 37 r1, err := New(in) 38 assert.NoError(t, err) 39 assert.True(t, r1.IsRoot()) 40 41 in = "#/ok" 42 r1 = MustCreateRef(in) 43 assert.False(t, r1.IsRoot()) 44 45 assert.Panics(t, assert.PanicTestFunc(func() { 46 MustCreateRef("%2") 47 })) 48} 49 50// nolint: dupl 51func TestFull(t *testing.T) { 52 53 in := "http://host/path/a/b/c#/f/a/b" 54 55 r1, err := New(in) 56 if err != nil { 57 t.Errorf("New(%v) error %s", in, err.Error()) 58 } 59 60 if in != r1.String() { 61 t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in) 62 } 63 64 if r1.HasFragmentOnly != false { 65 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false) 66 } 67 68 if r1.HasFullURL != true { 69 t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, true) 70 } 71 72 if r1.HasURLPathOnly != false { 73 t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false) 74 } 75 76 if r1.HasFileScheme != false { 77 t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false) 78 } 79 80 if r1.GetPointer().String() != "/f/a/b" { 81 t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "/f/a/b") 82 } 83} 84 85// nolint: dupl 86func TestFullURL(t *testing.T) { 87 88 in := "http://host/path/a/b/c" 89 90 r1, err := New(in) 91 if err != nil { 92 t.Errorf("New(%v) error %s", in, err.Error()) 93 } 94 95 if in != r1.String() { 96 t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in) 97 } 98 99 if r1.HasFragmentOnly != false { 100 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false) 101 } 102 103 if r1.HasFullURL != true { 104 t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, true) 105 } 106 107 if r1.HasURLPathOnly != false { 108 t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false) 109 } 110 111 if r1.HasFileScheme != false { 112 t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false) 113 } 114 115 if r1.GetPointer().String() != "" { 116 t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "") 117 } 118} 119 120func TestFragmentOnly(t *testing.T) { 121 122 in := "#/fragment/only" 123 124 r1, err := New(in) 125 if err != nil { 126 t.Errorf("New(%v) error %s", in, err.Error()) 127 } 128 129 if in != r1.String() { 130 t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in) 131 } 132 133 if r1.HasFragmentOnly != true { 134 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, true) 135 } 136 137 if r1.HasFullURL != false { 138 t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false) 139 } 140 141 if r1.HasURLPathOnly != false { 142 t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, false) 143 } 144 145 if r1.HasFileScheme != false { 146 t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false) 147 } 148 149 if r1.GetPointer().String() != "/fragment/only" { 150 t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "/fragment/only") 151 } 152 153 p, _ := jsonpointer.New(r1.referenceURL.Fragment) 154 r2 := Ref{referencePointer: p, HasFragmentOnly: true} 155 assert.Equal(t, r2.String(), in) 156 157 r3 := Ref{referencePointer: p, HasFragmentOnly: false} 158 assert.Equal(t, r3.String(), in[1:]) 159} 160 161// nolint: dupl 162func TestURLPathOnly(t *testing.T) { 163 164 in := "/documents/document.json" 165 166 r1, err := New(in) 167 if err != nil { 168 t.Errorf("New(%v) error %s", in, err.Error()) 169 } 170 171 if in != r1.String() { 172 t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in) 173 } 174 175 if r1.HasFragmentOnly != false { 176 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false) 177 } 178 179 if r1.HasFullURL != false { 180 t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false) 181 } 182 183 if r1.HasURLPathOnly != true { 184 t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, true) 185 } 186 187 if r1.HasFileScheme != false { 188 t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false) 189 } 190 191 if r1.GetPointer().String() != "" { 192 t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "") 193 } 194} 195 196// nolint: dupl 197func TestURLRelativePathOnly(t *testing.T) { 198 199 in := "document.json" 200 201 r1, err := New(in) 202 if err != nil { 203 t.Errorf("New(%v) error %s", in, err.Error()) 204 } 205 206 if in != r1.String() { 207 t.Errorf("New(%v) = %v, expect %v", in, r1.String(), in) 208 } 209 210 if r1.HasFragmentOnly != false { 211 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in, r1.HasFragmentOnly, false) 212 } 213 214 if r1.HasFullURL != false { 215 t.Errorf("New(%v)::HasFullURL %v expect %v", in, r1.HasFullURL, false) 216 } 217 218 if r1.HasURLPathOnly != true { 219 t.Errorf("New(%v)::HasURLPathOnly %v expect %v", in, r1.HasURLPathOnly, true) 220 } 221 222 if r1.HasFileScheme != false { 223 t.Errorf("New(%v)::HasFileScheme %v expect %v", in, r1.HasFileScheme, false) 224 } 225 226 if r1.GetPointer().String() != "" { 227 t.Errorf("New(%v)::GetPointer() %v expect %v", in, r1.GetPointer().String(), "") 228 } 229} 230 231func TestInheritsInValid(t *testing.T) { 232 in1 := "http://www.test.com/doc.json" 233 in2 := "#/a/b" 234 235 r1, _ := New(in1) 236 r2 := Ref{} 237 result, err := r1.Inherits(r2) 238 assert.Error(t, err) 239 assert.Nil(t, result) 240 241 r1 = Ref{} 242 r2, _ = New(in2) 243 result, err = r1.Inherits(r2) 244 assert.NoError(t, err) 245 assert.Equal(t, r2, *result) 246} 247 248func TestInheritsValid(t *testing.T) { 249 250 in1 := "http://www.test.com/doc.json" 251 in2 := "#/a/b" 252 out := in1 + in2 253 254 r1, _ := New(in1) 255 r2, _ := New(in2) 256 257 result, err := r1.Inherits(r2) 258 if err != nil { 259 t.Errorf("Inherits(%s,%s) error %s", r1.String(), r2.String(), err.Error()) 260 } 261 262 if result.String() != out { 263 t.Errorf("Inherits(%s,%s) = %s, expect %s", r1.String(), r2.String(), result.String(), out) 264 } 265 266 if result.GetPointer().String() != "/a/b" { 267 t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "/a/b") 268 } 269} 270 271func TestInheritsDifferentHost(t *testing.T) { 272 273 in1 := "http://www.test.com/doc.json" 274 in2 := "http://www.test2.com/doc.json#bla" 275 276 r1, _ := New(in1) 277 r2, _ := New(in2) 278 279 result, err := r1.Inherits(r2) 280 281 if err != nil { 282 t.Errorf("Inherits(%s,%s) should not fail. Error: %s", r1.String(), r2.String(), err.Error()) 283 } 284 285 if result.String() != in2 { 286 t.Errorf("Inherits(%s,%s) should be %s but is %s", in1, in2, in2, result) 287 } 288 289 if result.GetPointer().String() != "" { 290 t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "") 291 } 292} 293 294func TestFileScheme(t *testing.T) { 295 296 in1 := "file:///Users/mac/1.json#a" 297 in2 := "file:///Users/mac/2.json#b" 298 299 r1, _ := New(in1) 300 r2, _ := New(in2) 301 302 if r1.HasFragmentOnly != false { 303 t.Errorf("New(%v)::HasFragmentOnly %v expect %v", in1, r1.HasFragmentOnly, false) 304 } 305 306 if r1.HasFileScheme != true { 307 t.Errorf("New(%v)::HasFileScheme %v expect %v", in1, r1.HasFileScheme, true) 308 } 309 310 if r1.HasFullFilePath != true { 311 t.Errorf("New(%v)::HasFullFilePath %v expect %v", in1, r1.HasFullFilePath, true) 312 } 313 314 if r1.IsCanonical() != true { 315 t.Errorf("New(%v)::IsCanonical %v expect %v", in1, r1.IsCanonical(), true) 316 } 317 318 result, err := r1.Inherits(r2) 319 if err != nil { 320 t.Errorf("Inherits(%s,%s) should not fail. Error: %s", r1.String(), r2.String(), err.Error()) 321 } 322 if result.String() != in2 { 323 t.Errorf("Inherits(%s,%s) should be %s but is %s", in1, in2, in2, result) 324 } 325 326 if result.GetPointer().String() != "" { 327 t.Errorf("result(%v)::GetPointer() %v expect %v", result.String(), result.GetPointer().String(), "") 328 } 329} 330 331func TestReferenceResolution(t *testing.T) { 332 333 // 5.4. Reference Resolution Examples 334 // http://tools.ietf.org/html/rfc3986#section-5.4 335 336 base := "http://a/b/c/d;p?q" 337 baseRef, err := New(base) 338 339 if err != nil { 340 t.Errorf("New(%s) failed error: %s", base, err.Error()) 341 } 342 if baseRef.String() != base { 343 t.Errorf("New(%s) %s expected %s", base, baseRef.String(), base) 344 } 345 346 checks := []string{ 347 // 5.4.1. Normal Examples 348 // http://tools.ietf.org/html/rfc3986#section-5.4.1 349 350 "g:h", "g:h", 351 "g", "http://a/b/c/g", 352 "./g", "http://a/b/c/g", 353 "g/", "http://a/b/c/g/", 354 "/g", "http://a/g", 355 "//g", "http://g", 356 "?y", "http://a/b/c/d;p?y", 357 "g?y", "http://a/b/c/g?y", 358 "#s", "http://a/b/c/d;p?q#s", 359 "g#s", "http://a/b/c/g#s", 360 "g?y#s", "http://a/b/c/g?y#s", 361 ";x", "http://a/b/c/;x", 362 "g;x", "http://a/b/c/g;x", 363 "g;x?y#s", "http://a/b/c/g;x?y#s", 364 "", "http://a/b/c/d;p?q", 365 ".", "http://a/b/c/", 366 "./", "http://a/b/c/", 367 "..", "http://a/b/", 368 "../", "http://a/b/", 369 "../g", "http://a/b/g", 370 "../..", "http://a/", 371 "../../", "http://a/", 372 "../../g", "http://a/g", 373 374 // 5.4.2. Abnormal Examples 375 // http://tools.ietf.org/html/rfc3986#section-5.4.2 376 377 "../../../g", "http://a/g", 378 "../../../../g", "http://a/g", 379 380 "/./g", "http://a/g", 381 "/../g", "http://a/g", 382 "g.", "http://a/b/c/g.", 383 ".g", "http://a/b/c/.g", 384 "g..", "http://a/b/c/g..", 385 "..g", "http://a/b/c/..g", 386 387 "./../g", "http://a/b/g", 388 "./g/.", "http://a/b/c/g/", 389 "g/./h", "http://a/b/c/g/h", 390 "g/../h", "http://a/b/c/h", 391 "g;x=1/./y", "http://a/b/c/g;x=1/y", 392 "g;x=1/../y", "http://a/b/c/y", 393 394 "g?y/./x", "http://a/b/c/g?y/./x", 395 "g?y/../x", "http://a/b/c/g?y/../x", 396 "g#s/./x", "http://a/b/c/g#s/./x", 397 "g#s/../x", "http://a/b/c/g#s/../x", 398 399 "http:g", "http:g", // for strict parsers 400 // "http:g", "http://a/b/c/g", // for backward compatibility 401 402 } 403 for i := 0; i < len(checks); i += 2 { 404 child := checks[i] 405 expected := checks[i+1] 406 407 childRef, e := New(child) 408 if e != nil { 409 t.Errorf("%d: New(%s) failed error: %s", i/2, child, e.Error()) 410 } 411 412 res, e := baseRef.Inherits(childRef) 413 if res == nil { 414 t.Errorf("%d: Inherits(%s, %s) nil not expected", i/2, base, child) 415 } 416 if e != nil { 417 t.Errorf("%d: Inherits(%s) failed error: %s", i/2, child, e.Error()) 418 } 419 if res.String() != expected { 420 t.Errorf("%d: Inherits(%s, %s) %s expected %s", i/2, base, child, res.String(), expected) 421 } 422 } 423} 424