github.com/ccrossley/goa@v1.3.1/design/apidsl/media_type_test.go (about)

     1  package apidsl_test
     2  
     3  import (
     4  	. "github.com/goadesign/goa/design"
     5  	. "github.com/goadesign/goa/design/apidsl"
     6  	"github.com/goadesign/goa/dslengine"
     7  	. "github.com/onsi/ginkgo"
     8  	. "github.com/onsi/gomega"
     9  )
    10  
    11  var _ = Describe("MediaType", func() {
    12  	var name string
    13  	var dslFunc func()
    14  
    15  	var mt *MediaTypeDefinition
    16  
    17  	BeforeEach(func() {
    18  		dslengine.Reset()
    19  		name = ""
    20  		dslFunc = nil
    21  	})
    22  
    23  	JustBeforeEach(func() {
    24  		mt = MediaType(name, dslFunc)
    25  		dslengine.Run()
    26  	})
    27  
    28  	Context("with no dsl and no identifier", func() {
    29  		It("produces an error", func() {
    30  			Ω(mt).ShouldNot(BeNil())
    31  			Ω(mt.Validate()).Should(HaveOccurred())
    32  		})
    33  	})
    34  
    35  	Context("with no dsl", func() {
    36  		BeforeEach(func() {
    37  			name = "application/foo"
    38  		})
    39  
    40  		It("produces an error", func() {
    41  			Ω(mt).ShouldNot(BeNil())
    42  			Ω(mt.Validate()).Should(HaveOccurred())
    43  		})
    44  	})
    45  
    46  	Context("with attributes", func() {
    47  		const attName = "att"
    48  
    49  		BeforeEach(func() {
    50  			name = "application/foo"
    51  			dslFunc = func() {
    52  				Attributes(func() {
    53  					Attribute(attName)
    54  				})
    55  				View("default", func() { Attribute(attName) })
    56  			}
    57  		})
    58  
    59  		It("sets the attributes", func() {
    60  			Ω(mt).ShouldNot(BeNil())
    61  			Ω(mt.Validate()).ShouldNot(HaveOccurred())
    62  			Ω(mt.AttributeDefinition).ShouldNot(BeNil())
    63  			Ω(mt.Type).Should(BeAssignableToTypeOf(Object{}))
    64  			o := mt.Type.(Object)
    65  			Ω(o).Should(HaveLen(1))
    66  			Ω(o).Should(HaveKey(attName))
    67  		})
    68  	})
    69  
    70  	Context("with a content type", func() {
    71  		const attName = "att"
    72  		const contentType = "application/json"
    73  
    74  		BeforeEach(func() {
    75  			name = "application/foo"
    76  			dslFunc = func() {
    77  				ContentType(contentType)
    78  				Attributes(func() {
    79  					Attribute(attName)
    80  				})
    81  				View("default", func() { Attribute(attName) })
    82  			}
    83  		})
    84  
    85  		It("sets the content type", func() {
    86  			Ω(mt).ShouldNot(BeNil())
    87  			Ω(mt.Validate()).ShouldNot(HaveOccurred())
    88  			Ω(mt.ContentType).Should(Equal(contentType))
    89  		})
    90  	})
    91  
    92  	Context("with a description", func() {
    93  		const description = "desc"
    94  
    95  		BeforeEach(func() {
    96  			name = "application/foo"
    97  			dslFunc = func() {
    98  				Description(description)
    99  				Attributes(func() {
   100  					Attribute("attName")
   101  				})
   102  				View("default", func() { Attribute("attName") })
   103  			}
   104  		})
   105  
   106  		It("sets the description", func() {
   107  			Ω(mt).ShouldNot(BeNil())
   108  			Ω(mt.Validate()).ShouldNot(HaveOccurred())
   109  			Ω(mt.Description).Should(Equal(description))
   110  		})
   111  	})
   112  
   113  	Context("with links", func() {
   114  		const linkName = "link"
   115  		var link1Name, link2Name string
   116  		var link2View string
   117  		var mt1, mt2 *MediaTypeDefinition
   118  
   119  		BeforeEach(func() {
   120  			name = "foo"
   121  			link1Name = "l1"
   122  			link2Name = "l2"
   123  			link2View = "l2v"
   124  			mt1 = NewMediaTypeDefinition("application/mt1", "application/mt1", func() {
   125  				Attributes(func() {
   126  					Attribute("foo")
   127  				})
   128  				View("default", func() {
   129  					Attribute("foo")
   130  				})
   131  				View("link", func() {
   132  					Attribute("foo")
   133  				})
   134  			})
   135  			mt2 = NewMediaTypeDefinition("application/mt2", "application/mt2", func() {
   136  				Attributes(func() {
   137  					Attribute("foo")
   138  				})
   139  				View("l2v", func() {
   140  					Attribute("foo")
   141  				})
   142  				View("default", func() {
   143  					Attribute("foo")
   144  				})
   145  			})
   146  			Design.MediaTypes = make(map[string]*MediaTypeDefinition)
   147  			Design.MediaTypes["application/mt1"] = mt1
   148  			Design.MediaTypes["application/mt2"] = mt2
   149  			dslFunc = func() {
   150  				Attributes(func() {
   151  					Attributes(func() {
   152  						Attribute(link1Name, mt1)
   153  						Attribute(link2Name, mt2)
   154  					})
   155  					Links(func() {
   156  						Link(link1Name)
   157  						Link(link2Name, link2View)
   158  					})
   159  					View("default", func() {
   160  						Attribute(link1Name)
   161  						Attribute(link2Name)
   162  					})
   163  				})
   164  			}
   165  		})
   166  
   167  		It("sets the links", func() {
   168  			Ω(mt).ShouldNot(BeNil())
   169  			Ω(dslengine.Errors).Should(BeEmpty())
   170  			Ω(mt.Validate()).ShouldNot(HaveOccurred())
   171  			Ω(mt.Links).ShouldNot(BeNil())
   172  			Ω(mt.Links).Should(HaveLen(2))
   173  			Ω(mt.Links).Should(HaveKey(link1Name))
   174  			Ω(mt.Links[link1Name].Name).Should(Equal(link1Name))
   175  			Ω(mt.Links[link1Name].View).Should(Equal("link"))
   176  			Ω(mt.Links[link1Name].Parent).Should(Equal(mt))
   177  			Ω(mt.Links[link2Name].Name).Should(Equal(link2Name))
   178  			Ω(mt.Links[link2Name].View).Should(Equal(link2View))
   179  			Ω(mt.Links[link2Name].Parent).Should(Equal(mt))
   180  		})
   181  	})
   182  
   183  	Context("with views", func() {
   184  		const viewName = "view"
   185  		const viewAtt = "att"
   186  
   187  		BeforeEach(func() {
   188  			name = "application/foo"
   189  			dslFunc = func() {
   190  				Attributes(func() {
   191  					Attribute(viewAtt)
   192  				})
   193  				View(viewName, func() {
   194  					Attribute(viewAtt)
   195  				})
   196  				View("default", func() {
   197  					Attribute(viewAtt)
   198  				})
   199  			}
   200  		})
   201  
   202  		It("sets the views", func() {
   203  			Ω(mt).ShouldNot(BeNil())
   204  			Ω(mt.Validate()).ShouldNot(HaveOccurred())
   205  			Ω(mt.Views).ShouldNot(BeNil())
   206  			Ω(mt.Views).Should(HaveLen(2))
   207  			Ω(mt.Views).Should(HaveKey(viewName))
   208  			v := mt.Views[viewName]
   209  			Ω(v.Name).Should(Equal(viewName))
   210  			Ω(v.Parent).Should(Equal(mt))
   211  			Ω(v.AttributeDefinition).ShouldNot(BeNil())
   212  			Ω(v.AttributeDefinition.Type).Should(BeAssignableToTypeOf(Object{}))
   213  			o := v.AttributeDefinition.Type.(Object)
   214  			Ω(o).Should(HaveLen(1))
   215  			Ω(o).Should(HaveKey(viewAtt))
   216  			Ω(o[viewAtt]).ShouldNot(BeNil())
   217  			Ω(o[viewAtt].Type).Should(Equal(String))
   218  		})
   219  	})
   220  })
   221  
   222  var _ = Describe("Duplicate media types", func() {
   223  	var duplicate *MediaTypeDefinition
   224  	const id = "application/foo"
   225  	const attName = "bar"
   226  	var dslFunc = func() {
   227  		Attributes(func() {
   228  			Attribute(attName)
   229  		})
   230  		View("default", func() { Attribute(attName) })
   231  	}
   232  
   233  	BeforeEach(func() {
   234  		dslengine.Reset()
   235  		MediaType(id, dslFunc)
   236  		duplicate = MediaType(id, dslFunc)
   237  	})
   238  
   239  	It("produces an error", func() {
   240  		Ω(dslengine.Errors).Should(HaveOccurred())
   241  		Ω(dslengine.Errors.Error()).Should(ContainSubstring("is defined twice"))
   242  	})
   243  
   244  	Context("with a response definition using the duplicate", func() {
   245  		BeforeEach(func() {
   246  			Resource("foo", func() {
   247  				Action("show", func() {
   248  					Routing(GET(""))
   249  					Response(OK, func() {
   250  						Media(duplicate)
   251  					})
   252  				})
   253  			})
   254  		})
   255  
   256  		It("does not panic", func() {
   257  			Ω(func() { dslengine.Run() }).ShouldNot(Panic())
   258  		})
   259  	})
   260  })
   261  
   262  var _ = Describe("CollectionOf", func() {
   263  	Context("used on a global variable", func() {
   264  		var col *MediaTypeDefinition
   265  		BeforeEach(func() {
   266  			dslengine.Reset()
   267  			mt := MediaType("application/vnd.example", func() {
   268  				Attribute("id")
   269  				View("default", func() {
   270  					Attribute("id")
   271  				})
   272  			})
   273  			col = CollectionOf(mt)
   274  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   275  		})
   276  
   277  		JustBeforeEach(func() {
   278  			dslengine.Run()
   279  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   280  		})
   281  
   282  		It("produces a media type", func() {
   283  			Ω(col).ShouldNot(BeNil())
   284  			Ω(col.Identifier).Should(Equal("application/vnd.example; type=collection"))
   285  			Ω(col.TypeName).ShouldNot(BeEmpty())
   286  			Ω(Design.MediaTypes).Should(HaveKey(col.Identifier))
   287  		})
   288  	})
   289  
   290  	Context("defined with a collection identifier", func() {
   291  		var col *MediaTypeDefinition
   292  		BeforeEach(func() {
   293  			dslengine.Reset()
   294  			mt := MediaType("application/vnd.example", func() {
   295  				Attribute("id")
   296  				View("default", func() {
   297  					Attribute("id")
   298  				})
   299  			})
   300  			col = CollectionOf(mt, "application/vnd.examples")
   301  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   302  		})
   303  
   304  		JustBeforeEach(func() {
   305  			dslengine.Run()
   306  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   307  		})
   308  
   309  		It("produces a media type", func() {
   310  			Ω(col).ShouldNot(BeNil())
   311  			Ω(col.Identifier).Should(Equal("application/vnd.examples"))
   312  			Ω(col.TypeName).ShouldNot(BeEmpty())
   313  			Ω(Design.MediaTypes).Should(HaveKey(col.Identifier))
   314  		})
   315  	})
   316  
   317  	Context("defined with the media type identifier", func() {
   318  		var col *MediaTypeDefinition
   319  		BeforeEach(func() {
   320  			dslengine.Reset()
   321  			MediaType("application/vnd.example+json", func() {
   322  				Attribute("id")
   323  				View("default", func() {
   324  					Attribute("id")
   325  				})
   326  			})
   327  			col = MediaType("application/vnd.parent+json", func() {
   328  				Attribute("mt", CollectionOf("application/vnd.example"))
   329  				View("default", func() {
   330  					Attribute("mt")
   331  				})
   332  			})
   333  		})
   334  
   335  		JustBeforeEach(func() {
   336  			dslengine.Run()
   337  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   338  		})
   339  
   340  		It("produces a media type", func() {
   341  			Ω(col).ShouldNot(BeNil())
   342  			Ω(col.Identifier).Should(Equal("application/vnd.parent+json"))
   343  			Ω(col.TypeName).Should(Equal("Parent"))
   344  			Ω(col.Type).ShouldNot(BeNil())
   345  			Ω(col.Type.ToObject()).ShouldNot(BeNil())
   346  			Ω(col.Type.ToObject()).Should(HaveKey("mt"))
   347  			mt := col.Type.ToObject()["mt"]
   348  			Ω(mt.Type).ShouldNot(BeNil())
   349  			Ω(mt.Type).Should(BeAssignableToTypeOf(&MediaTypeDefinition{}))
   350  			Ω(mt.Type.Name()).Should(Equal("array"))
   351  			et := mt.Type.ToArray().ElemType
   352  			Ω(et).ShouldNot(BeNil())
   353  			Ω(et.Type).Should(BeAssignableToTypeOf(&MediaTypeDefinition{}))
   354  			Ω(et.Type.(*MediaTypeDefinition).Identifier).Should(Equal("application/vnd.example+json"))
   355  		})
   356  	})
   357  })
   358  
   359  var _ = Describe("Example", func() {
   360  	Context("defined examples in a media type", func() {
   361  		BeforeEach(func() {
   362  			dslengine.Reset()
   363  			ProjectedMediaTypes = make(MediaTypeRoot)
   364  		})
   365  		It("produces a media type with examples", func() {
   366  			mt := MediaType("application/vnd.example+json", func() {
   367  				Attributes(func() {
   368  					Attribute("test1", String, "test1 desc", func() {
   369  						Example("test1")
   370  					})
   371  					Attribute("test2", String, "test2 desc", func() {
   372  						NoExample()
   373  					})
   374  					Attribute("test3", Integer, "test3 desc", func() {
   375  						Minimum(1)
   376  					})
   377  					Attribute("test4", String, func() {
   378  						Format("email")
   379  						Pattern("@")
   380  					})
   381  					Attribute("test5", Any)
   382  
   383  					Attribute("test-failure1", Integer, func() {
   384  						Minimum(0)
   385  						Maximum(0)
   386  					})
   387  				})
   388  				View("default", func() {
   389  					Attribute("test1")
   390  				})
   391  			})
   392  
   393  			dslengine.Run()
   394  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   395  
   396  			Ω(mt).ShouldNot(BeNil())
   397  			attr := mt.Type.ToObject()["test1"]
   398  			Ω(attr.Example).Should(Equal("test1"))
   399  			attr = mt.Type.ToObject()["test2"]
   400  			Ω(attr.Example).Should(Equal("-"))
   401  			attr = mt.Type.ToObject()["test3"]
   402  			Ω(attr.Example).Should(BeNumerically(">=", 1))
   403  			attr = mt.Type.ToObject()["test4"]
   404  			Ω(attr.Example).Should(MatchRegexp(`\w+@`))
   405  			attr = mt.Type.ToObject()["test5"]
   406  			Ω(attr.Example).ShouldNot(BeNil())
   407  			attr = mt.Type.ToObject()["test-failure1"]
   408  			Ω(attr.Example).Should(Equal(0))
   409  		})
   410  
   411  		It("produces a media type with HashOf examples", func() {
   412  			ut := Type("example", func() {
   413  				Attribute("test1", Integer)
   414  				Attribute("test2", Any)
   415  			})
   416  
   417  			mt := MediaType("application/vnd.example+json", func() {
   418  				Attributes(func() {
   419  					Attribute("test1", HashOf(String, Integer))
   420  					Attribute("test2", HashOf(Any, String))
   421  					Attribute("test3", HashOf(String, Any))
   422  					Attribute("test4", HashOf(Any, Any))
   423  
   424  					Attribute("test-with-user-type-1", HashOf(String, ut))
   425  					Attribute("test-with-user-type-2", HashOf(Any, ut))
   426  
   427  					Attribute("test-with-array-1", HashOf(String, ArrayOf(Integer)))
   428  					Attribute("test-with-array-2", HashOf(String, ArrayOf(Any)))
   429  					Attribute("test-with-array-3", HashOf(String, ArrayOf(ut)))
   430  					Attribute("test-with-array-4", HashOf(Any, ArrayOf(String)))
   431  					Attribute("test-with-array-5", HashOf(Any, ArrayOf(Any)))
   432  					Attribute("test-with-array-6", HashOf(Any, ArrayOf(ut)))
   433  
   434  					Attribute("test-with-example-1", HashOf(String, Boolean), func() {
   435  						Example(map[string]bool{})
   436  					})
   437  					Attribute("test-with-example-2", HashOf(Any, Boolean), func() {
   438  						Example(map[string]int{})
   439  					})
   440  				})
   441  				View("default", func() {
   442  					Attribute("test1")
   443  				})
   444  			})
   445  
   446  			dslengine.Run()
   447  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   448  			Ω(mt).ShouldNot(BeNil())
   449  
   450  			attr := mt.Type.ToObject()["test1"]
   451  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]int{}))
   452  			attr = mt.Type.ToObject()["test2"]
   453  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}]string{}))
   454  			attr = mt.Type.ToObject()["test3"]
   455  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   456  			attr = mt.Type.ToObject()["test4"]
   457  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}]interface{}{}))
   458  
   459  			attr = mt.Type.ToObject()["test-with-user-type-1"]
   460  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]map[string]interface{}{}))
   461  			for _, utattr := range attr.Example.(map[string]map[string]interface{}) {
   462  				Expect(utattr).Should(HaveKey("test1"))
   463  				Expect(utattr).Should(HaveKey("test2"))
   464  				Expect(utattr["test1"]).Should(BeAssignableToTypeOf(int(0)))
   465  			}
   466  			attr = mt.Type.ToObject()["test-with-user-type-2"]
   467  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}]map[string]interface{}{}))
   468  			for _, utattr := range attr.Example.(map[interface{}]map[string]interface{}) {
   469  				Expect(utattr).Should(HaveKey("test1"))
   470  				Expect(utattr).Should(HaveKey("test2"))
   471  				Expect(utattr["test1"]).Should(BeAssignableToTypeOf(int(0)))
   472  			}
   473  
   474  			attr = mt.Type.ToObject()["test-with-array-1"]
   475  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string][]int{}))
   476  			attr = mt.Type.ToObject()["test-with-array-2"]
   477  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string][]interface{}{}))
   478  			attr = mt.Type.ToObject()["test-with-array-3"]
   479  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string][]map[string]interface{}{}))
   480  			attr = mt.Type.ToObject()["test-with-array-4"]
   481  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}][]string{}))
   482  			attr = mt.Type.ToObject()["test-with-array-5"]
   483  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}][]interface{}{}))
   484  			attr = mt.Type.ToObject()["test-with-array-6"]
   485  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[interface{}][]map[string]interface{}{}))
   486  
   487  			attr = mt.Type.ToObject()["test-with-example-1"]
   488  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]bool{}))
   489  			attr = mt.Type.ToObject()["test-with-example-2"]
   490  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]int{}))
   491  		})
   492  
   493  		It("produces a media type with examples in cyclical dependencies", func() {
   494  			mt := MediaType("vnd.application/foo", func() {
   495  				Attributes(func() {
   496  					Attribute("foo", "vnd.application/bar")
   497  					Attribute("others", Integer, func() {
   498  						Minimum(3)
   499  						Maximum(3)
   500  					})
   501  				})
   502  				View("default", func() {
   503  					Attribute("foo")
   504  					Attribute("others")
   505  				})
   506  			})
   507  
   508  			mt2 := MediaType("vnd.application/bar", func() {
   509  				Attributes(func() {
   510  					Attribute("bar", mt)
   511  					Attribute("others", Integer, func() {
   512  						Minimum(1)
   513  						Maximum(2)
   514  					})
   515  				})
   516  				View("default", func() {
   517  					Attribute("bar")
   518  					Attribute("others")
   519  				})
   520  			})
   521  
   522  			dslengine.Run()
   523  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   524  
   525  			Ω(mt).ShouldNot(BeNil())
   526  			attr := mt.Type.ToObject()["foo"]
   527  			Ω(attr.Example).ShouldNot(BeNil())
   528  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   529  			attrChild := attr.Example.(map[string]interface{})
   530  			Ω(attrChild).Should(HaveKey("bar"))
   531  			Ω(attrChild["others"]).Should(BeNumerically(">=", 1))
   532  			Ω(attrChild["others"]).Should(BeNumerically("<=", 2))
   533  			attr = mt.Type.ToObject()["others"]
   534  			Ω(attr.Example).Should(Equal(3))
   535  
   536  			Ω(mt2).ShouldNot(BeNil())
   537  			attr = mt2.Type.ToObject()["bar"]
   538  			Ω(attr.Example).ShouldNot(BeNil())
   539  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   540  			attrChild = attr.Example.(map[string]interface{})
   541  			Ω(attrChild).Should(HaveKey("foo"))
   542  			Ω(attrChild["others"]).Should(Equal(3))
   543  			attr = mt2.Type.ToObject()["others"]
   544  			Ω(attr.Example).Should(BeNumerically(">=", 1))
   545  			Ω(attr.Example).Should(BeNumerically("<=", 2))
   546  		})
   547  
   548  		It("produces media type examples from the linked media type", func() {
   549  			mt := MediaType("application/vnd.example+json", func() {
   550  				Attributes(func() {
   551  					Attribute("test1", String, "test1 desc", func() {
   552  						Example("test1")
   553  					})
   554  					Attribute("test2", String, "test2 desc", func() {
   555  						NoExample()
   556  					})
   557  					Attribute("test3", Integer, "test3 desc", func() {
   558  						Minimum(1)
   559  					})
   560  				})
   561  				View("default", func() {
   562  					Attribute("test1")
   563  					Attribute("test2")
   564  					Attribute("test3")
   565  				})
   566  			})
   567  
   568  			pmt := MediaType("application/vnd.example.parent+json", func() {
   569  				Attributes(func() {
   570  					Attribute("test1", String, "test1 desc", func() {
   571  						Example("test1")
   572  					})
   573  					Attribute("test2", String, "test2 desc", func() {
   574  						NoExample()
   575  					})
   576  					Attribute("test3", Integer, "test3 desc", func() {
   577  						Minimum(1)
   578  					})
   579  					Attribute("test4", mt, "test4 desc")
   580  				})
   581  				View("default", func() {
   582  					Attribute("test1")
   583  					Attribute("test2")
   584  					Attribute("test3")
   585  					Attribute("test4")
   586  				})
   587  			})
   588  
   589  			dslengine.Run()
   590  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   591  
   592  			Ω(mt).ShouldNot(BeNil())
   593  			attr := mt.Type.ToObject()["test1"]
   594  			Ω(attr.Example).Should(Equal("test1"))
   595  			attr = mt.Type.ToObject()["test2"]
   596  			Ω(attr.Example).Should(Equal("-"))
   597  			attr = mt.Type.ToObject()["test3"]
   598  			Ω(attr.Example).Should(BeNumerically(">=", 1))
   599  
   600  			Ω(pmt).ShouldNot(BeNil())
   601  			attr = pmt.Type.ToObject()["test1"]
   602  			Ω(attr.Example).Should(Equal("test1"))
   603  			attr = pmt.Type.ToObject()["test2"]
   604  			Ω(attr.Example).Should(Equal("-"))
   605  			attr = pmt.Type.ToObject()["test3"]
   606  			Ω(attr.Example).Should(BeNumerically(">=", 1))
   607  			attr = pmt.Type.ToObject()["test4"]
   608  			Ω(attr.Example).ShouldNot(BeNil())
   609  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   610  			attrChild := attr.Example.(map[string]interface{})
   611  			Ω(attrChild["test1"]).Should(Equal("test1"))
   612  			Ω(attrChild["test2"]).Should(Equal("-"))
   613  			Ω(attrChild["test3"]).Should(BeNumerically(">=", 1))
   614  		})
   615  
   616  		It("produces media type examples from the linked media type collection with custom examples", func() {
   617  			mt := MediaType("application/vnd.example+json", func() {
   618  				Attributes(func() {
   619  					Attribute("test1", String, "test1 desc", func() {
   620  						Example("test1")
   621  					})
   622  					Attribute("test2", String, "test2 desc", func() {
   623  						NoExample()
   624  					})
   625  					Attribute("test3", Integer, "test3 desc", func() {
   626  						Minimum(1)
   627  					})
   628  				})
   629  				View("default", func() {
   630  					Attribute("test1")
   631  					Attribute("test2")
   632  					Attribute("test3")
   633  				})
   634  			})
   635  
   636  			pmt := MediaType("application/vnd.example.parent+json", func() {
   637  				Attributes(func() {
   638  					Attribute("test1", String, "test1 desc", func() {
   639  						Example("test1")
   640  					})
   641  					Attribute("test2", String, "test2 desc", func() {
   642  						NoExample()
   643  					})
   644  					Attribute("test3", String, "test3 desc", func() {
   645  						Pattern("^1$")
   646  					})
   647  					Attribute("test4", CollectionOf(mt), "test4 desc")
   648  				})
   649  				View("default", func() {
   650  					Attribute("test1")
   651  					Attribute("test2")
   652  					Attribute("test3")
   653  					Attribute("test4")
   654  				})
   655  			})
   656  
   657  			dslengine.Run()
   658  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   659  
   660  			Ω(mt).ShouldNot(BeNil())
   661  			attr := mt.Type.ToObject()["test1"]
   662  			Ω(attr.Example).Should(Equal("test1"))
   663  			attr = mt.Type.ToObject()["test2"]
   664  			Ω(attr.Example).Should(Equal("-"))
   665  			attr = mt.Type.ToObject()["test3"]
   666  			Ω(attr.Example).Should(BeNumerically(">=", 1))
   667  
   668  			Ω(pmt).ShouldNot(BeNil())
   669  			attr = pmt.Type.ToObject()["test1"]
   670  			Ω(attr.Example).Should(Equal("test1"))
   671  			attr = pmt.Type.ToObject()["test2"]
   672  			Ω(attr.Example).Should(Equal("-"))
   673  			attr = pmt.Type.ToObject()["test3"]
   674  			Ω(attr.Example).Should(Equal("1"))
   675  			attr = pmt.Type.ToObject()["test4"]
   676  			Ω(attr.Example).ShouldNot(BeNil())
   677  			Expect(attr.Example).Should(BeAssignableToTypeOf([]map[string]interface{}{}))
   678  			attrChildren := attr.Example.([]map[string]interface{})
   679  			Ω(attrChildren).Should(HaveLen(1))
   680  			Ω(attrChildren[0]).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   681  			Ω(attrChildren[0]["test1"]).Should(Equal("test1"))
   682  			Ω(attrChildren[0]["test2"]).Should(Equal("-"))
   683  			Ω(attrChildren[0]["test3"]).Should(BeNumerically(">=", 1))
   684  		})
   685  
   686  		It("produces media type examples from the linked media type without custom examples", func() {
   687  			mt := MediaType("application/vnd.example.child+json", func() {
   688  				Attributes(func() {
   689  					Attribute("test1", String, "test1 desc")
   690  				})
   691  				View("default", func() {
   692  					Attribute("test1")
   693  				})
   694  			})
   695  
   696  			pmt := MediaType("application/vnd.example.parent+json", func() {
   697  				Attributes(func() {
   698  					Attribute("test1", String, "test1 desc", func() {
   699  						Example("test1")
   700  					})
   701  					Attribute("test2", String, "test2 desc", func() {
   702  						NoExample()
   703  					})
   704  					Attribute("test3", mt, "test3 desc")
   705  				})
   706  				View("default", func() {
   707  					Attribute("test1")
   708  					Attribute("test2")
   709  					Attribute("test3")
   710  				})
   711  			})
   712  
   713  			dslengine.Run()
   714  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   715  			Ω(mt).ShouldNot(BeNil())
   716  			attr := mt.Type.ToObject()["test1"]
   717  			cexample := attr.Example
   718  			Ω(cexample).ShouldNot(BeEmpty())
   719  
   720  			Ω(pmt).ShouldNot(BeNil())
   721  			attr = pmt.Type.ToObject()["test1"]
   722  			Ω(attr.Example).Should(Equal("test1"))
   723  			attr = pmt.Type.ToObject()["test2"]
   724  			Ω(attr.Example).Should(Equal("-"))
   725  			attr = pmt.Type.ToObject()["test3"]
   726  			Ω(attr.Example).ShouldNot(BeNil())
   727  			Expect(attr.Example).Should(BeAssignableToTypeOf(map[string]interface{}{}))
   728  		})
   729  
   730  		It("produces media type examples from the linked media type collection without custom examples", func() {
   731  			mt := MediaType("application/vnd.example.child+json", func() {
   732  				Attributes(func() {
   733  					Attribute("test1", String, "test1 desc")
   734  				})
   735  				View("default", func() {
   736  					Attribute("test1")
   737  				})
   738  			})
   739  
   740  			pmt := MediaType("application/vnd.example.parent+json", func() {
   741  				Attributes(func() {
   742  					Attribute("test1", String, "test1 desc", func() {
   743  						Example("test1")
   744  					})
   745  					Attribute("test2", String, "test2 desc", func() {
   746  						NoExample()
   747  					})
   748  					Attribute("test3", CollectionOf(mt), "test3 desc")
   749  				})
   750  				View("default", func() {
   751  					Attribute("test1")
   752  				})
   753  			})
   754  
   755  			dslengine.Run()
   756  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   757  
   758  			Ω(mt).ShouldNot(BeNil())
   759  			attr := mt.Type.ToObject()["test1"]
   760  			cexample := attr.Example
   761  			Ω(cexample).ShouldNot(BeEmpty())
   762  
   763  			Ω(pmt).ShouldNot(BeNil())
   764  			attr = pmt.Type.ToObject()["test1"]
   765  			Ω(attr.Example).Should(Equal("test1"))
   766  			attr = pmt.Type.ToObject()["test2"]
   767  			Ω(attr.Example).Should(Equal("-"))
   768  			attr = pmt.Type.ToObject()["test3"]
   769  			Ω(attr.Example).ShouldNot(BeNil())
   770  			Expect(attr.Example).Should(BeAssignableToTypeOf([]map[string]interface{}{}))
   771  			attrChildren := attr.Example.([]map[string]interface{})
   772  			Ω(len(attrChildren)).Should(BeNumerically(">=", 1))
   773  		})
   774  
   775  		It("produces a media type with appropriate MinLength and MaxLength examples", func() {
   776  			ut := Type("example", func() {
   777  				Attribute("test1", Integer, func() {
   778  					Minimum(-200)
   779  					Maximum(-100)
   780  				})
   781  			})
   782  
   783  			mt := MediaType("application/vnd.example+json", func() {
   784  				Attributes(func() {
   785  					Attribute("test1", ArrayOf(Any), func() {
   786  						MinLength(0)
   787  						MaxLength(10)
   788  					})
   789  					Attribute("test2", ArrayOf(Any), func() {
   790  						MinLength(1000)
   791  						MaxLength(2000)
   792  					})
   793  					Attribute("test3", ArrayOf(Any), func() {
   794  						MinLength(1000)
   795  						MaxLength(1000)
   796  					})
   797  
   798  					Attribute("test-failure1", ArrayOf(ut), func() {
   799  						MinLength(0)
   800  						MaxLength(0)
   801  					})
   802  				})
   803  				View("default", func() {
   804  					Attribute("test1")
   805  				})
   806  			})
   807  
   808  			dslengine.Run()
   809  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   810  
   811  			Ω(mt).ShouldNot(BeNil())
   812  			attr := mt.Type.ToObject()["test1"]
   813  			Ω(attr.Example).Should(BeAssignableToTypeOf([]interface{}{}))
   814  			Ω(len(attr.Example.([]interface{}))).Should(BeNumerically("<=", 10))
   815  			attr = mt.Type.ToObject()["test2"]
   816  			Ω(attr.Example).Should(BeAssignableToTypeOf([]interface{}{}))
   817  			Ω(attr.Example.([]interface{})).Should(HaveLen(10))
   818  			attr = mt.Type.ToObject()["test3"]
   819  			Ω(attr.Example).Should(BeAssignableToTypeOf([]interface{}{}))
   820  			Ω(attr.Example.([]interface{})).Should(HaveLen(10))
   821  			attr = mt.Type.ToObject()["test-failure1"]
   822  			Ω(attr.Example).Should(BeNil())
   823  		})
   824  	})
   825  })