github.com/TheSpiritXIII/controller-tools@v0.14.1/pkg/markers/collect_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package markers_test
    18  
    19  import (
    20  	. "github.com/onsi/ginkgo"
    21  	. "github.com/onsi/gomega"
    22  
    23  	. "github.com/TheSpiritXIII/controller-tools/pkg/markers"
    24  )
    25  
    26  type fieldPath struct {
    27  	typ   string
    28  	field string
    29  }
    30  
    31  var _ = Describe("Collecting", func() {
    32  	var col *Collector
    33  	var markersByType map[string]MarkerValues
    34  	var docsByType map[string]string
    35  
    36  	var markersByField map[fieldPath]MarkerValues
    37  	var docsByField map[fieldPath]string
    38  
    39  	JustBeforeEach(func() {
    40  		By("setting up the registry and collector")
    41  		reg := &Registry{}
    42  
    43  		mustDefine(reg, "testing:pkglvl", DescribesPackage, "")
    44  		mustDefine(reg, "testing:typelvl", DescribesType, "")
    45  		mustDefine(reg, "testing:fieldlvl", DescribesField, "")
    46  		mustDefine(reg, "testing:eitherlvl", DescribesType, "")
    47  		mustDefine(reg, "testing:eitherlvl", DescribesPackage, "")
    48  
    49  		col = &Collector{Registry: reg}
    50  
    51  		By("gathering markers/docs by type/field name")
    52  		markersByType = make(map[string]MarkerValues)
    53  		docsByType = make(map[string]string)
    54  		markersByField = make(map[fieldPath]MarkerValues)
    55  		docsByField = make(map[fieldPath]string)
    56  
    57  		err := EachType(col, fakePkg, func(info *TypeInfo) {
    58  			markersByType[info.Name] = info.Markers
    59  			docsByType[info.Name] = info.Doc
    60  
    61  			for _, field := range info.Fields {
    62  				fieldPath := fieldPath{typ: info.Name, field: field.Name}
    63  				markersByField[fieldPath] = field.Markers
    64  				docsByField[fieldPath] = field.Doc
    65  			}
    66  		})
    67  
    68  		Expect(err).NotTo(HaveOccurred())
    69  		Expect(fakePkg.Errors).To(HaveLen(0))
    70  	})
    71  
    72  	Context("of package-level markers", func() {
    73  
    74  		It("should consider markers anywhere not obviously type- or field-level as package-level", func() {
    75  			By("grabbing all package-level markers")
    76  			pkgMarkers, err := PackageMarkers(col, fakePkg)
    77  			Expect(err).NotTo(HaveOccurred())
    78  			Expect(fakePkg.Errors).To(HaveLen(0))
    79  
    80  			By("checking that it only contains package-level markers")
    81  			Expect(pkgMarkers).NotTo(HaveKey("testing:typelvl"))
    82  
    83  			By("checking that it contains the right package-level markers")
    84  			Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", ContainElement("here unattached")))
    85  			Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", ContainElement("here at end after last node")))
    86  
    87  			By("checking that it doesn't contain any markers it's not supposed to")
    88  			Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", Not(ContainElement(ContainSubstring("not here")))))
    89  		})
    90  	})
    91  
    92  	Context("of type-level markers", func() {
    93  		It("should not have package-level markers associated", func() {
    94  			Expect(markersByType).To(HaveKeyWithValue("Foo", Not(HaveKey("testing:pkglvl"))))
    95  		})
    96  
    97  		It("should not contain markers it's not supposed to", func() {
    98  			Expect(markersByType).NotTo(ContainElement(HaveKeyWithValue("testing:typelvl", ContainElement(ContainSubstring("not here")))))
    99  			Expect(markersByType).NotTo(ContainElement(HaveKeyWithValue("testing:eitherlvl", ContainElement(ContainSubstring("not here")))))
   100  		})
   101  
   102  		Context("with godoc", func() {
   103  			It("should associate markers in godoc", func() {
   104  				Expect(markersByType).To(HaveKeyWithValue("Foo",
   105  					HaveKeyWithValue("testing:typelvl", ContainElement("here on type"))))
   106  			})
   107  
   108  			It("should have docs without markers", func() {
   109  				Expect(docsByType).To(HaveKeyWithValue("Foo", "normal godoc\nnormal godoc"))
   110  			})
   111  
   112  			It("should associate markers in the closest non-godoc block", func() {
   113  				Expect(markersByType).To(HaveKeyWithValue("Foo",
   114  					HaveKeyWithValue("testing:typelvl", ContainElement("here before type"))))
   115  			})
   116  
   117  			It("should re-associate package-level markers from the closest non-godoc", func() {
   118  				By("grabbing package markers")
   119  				pkgMarkers, err := PackageMarkers(col, fakePkg)
   120  				Expect(err).NotTo(HaveOccurred())
   121  				Expect(fakePkg.Errors).To(HaveLen(0))
   122  
   123  				By("checking that the marker got reassociated")
   124  				Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", ContainElement("here reassociated")))
   125  			})
   126  		})
   127  
   128  		Context("types with /*…*/-style comments", func() {
   129  			It("should have doc without extraneous spaces", func() {
   130  				Expect(docsByType).To(HaveKeyWithValue("HasDocsWithSpaces",
   131  					"This type of doc has spaces preserved in go-ast, but we'd like to trim them."))
   132  			})
   133  
   134  			It("should have doc without extraneous spaces, even over multiple lines", func() {
   135  				Expect(docsByType).To(HaveKeyWithValue("HasDocsWithSpaces2",
   136  					"This type of doc has spaces preserved in go-ast, but we'd like to trim them,\nespecially when formatted like this."))
   137  			})
   138  		})
   139  		Context("types with //-style comments and yaml embeeded", func() {
   140  			It("should keep spaces and multiline", func() {
   141  				Expect(docsByType).To(HaveKeyWithValue("HasNonAsteriskDocWithYamlEmbeeded",
   142  					`This is a description
   143  this is an example as yaml:
   144  ---
   145  foo:
   146    bar:
   147      dar:
   148      - value1
   149      - value2`))
   150  			})
   151  		})
   152  
   153  		Context("without godoc", func() {
   154  			It("should associate markers in the closest block", func() {
   155  				Expect(markersByType).To(HaveKeyWithValue("Quux",
   156  					HaveKeyWithValue("testing:typelvl", ContainElement("here without godoc"))))
   157  			})
   158  
   159  			It("should re-associate package-level markers from the closest block", func() {
   160  				By("grabbing package markers")
   161  				pkgMarkers, err := PackageMarkers(col, fakePkg)
   162  				Expect(err).NotTo(HaveOccurred())
   163  				Expect(fakePkg.Errors).To(HaveLen(0))
   164  
   165  				By("checking that the marker got reassociated")
   166  				Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", ContainElement("here reassociated no godoc")))
   167  
   168  			})
   169  		})
   170  
   171  		It("should not re-associate package-level markers in godoc", func() {
   172  			By("grabbing package markers")
   173  			pkgMarkers, err := PackageMarkers(col, fakePkg)
   174  			Expect(err).NotTo(HaveOccurred())
   175  			Expect(fakePkg.Errors).To(HaveLen(0))
   176  
   177  			By("checking that the marker didn't get reassociated")
   178  			Expect(pkgMarkers).To(HaveKeyWithValue("testing:pkglvl", Not(ContainElement("not here godoc"))))
   179  		})
   180  
   181  		It("should not re-associate package-level markers if there's also a type-level marker", func() {
   182  			By("checking that the type has the marker")
   183  			Expect(markersByType).To(HaveKeyWithValue("Foo",
   184  				HaveKeyWithValue("testing:eitherlvl", ContainElement("here not reassociated"))))
   185  
   186  			By("grabbing package markers")
   187  			pkgMarkers, err := PackageMarkers(col, fakePkg)
   188  			Expect(err).NotTo(HaveOccurred())
   189  			Expect(fakePkg.Errors).To(HaveLen(0))
   190  
   191  			By("checking that the marker didn't get reassociated to the package")
   192  			Expect(pkgMarkers).To(SatisfyAny(
   193  				Not(HaveKey("testing:eitherlvl")),
   194  				HaveKeyWithValue("testing:eitherlvl", Not(ContainElement("here not reassociated")))))
   195  
   196  		})
   197  
   198  		It("should consider markers on the gendecl even if there are no more markers in the file", func() {
   199  			Expect(markersByType).To(HaveKeyWithValue("Cheese",
   200  				HaveKeyWithValue("testing:typelvl", ContainElement("here on typedecl with no more"))))
   201  
   202  		})
   203  	})
   204  
   205  	Context("of field-level markers", func() {
   206  		It("should not contain markers it's not supposed to", func() {
   207  			Expect(markersByField).NotTo(ContainElement(HaveKeyWithValue("testing:fieldlvl", ContainElement(ContainSubstring("not here")))))
   208  		})
   209  		Context("with godoc", func() {
   210  			It("should associate markers in godoc", func() {
   211  				Expect(markersByField).To(HaveKeyWithValue(fieldPath{typ: "Foo", field: "WithGodoc"},
   212  					HaveKeyWithValue("testing:fieldlvl", ContainElement("here in godoc"))))
   213  			})
   214  
   215  			It("should associate markers in the closest non-godoc block", func() {
   216  				Expect(markersByField).To(HaveKeyWithValue(fieldPath{typ: "Foo", field: "WithGodoc"},
   217  					HaveKeyWithValue("testing:fieldlvl", ContainElement("here before godoc"))))
   218  			})
   219  		})
   220  		Context("without godoc", func() {
   221  			It("should associate markers in the closest block", func() {
   222  				Expect(markersByField).To(HaveKeyWithValue(fieldPath{typ: "Foo", field: "WithoutGodoc"},
   223  					HaveKeyWithValue("testing:fieldlvl", ContainElement("here without godoc"))))
   224  			})
   225  		})
   226  
   227  		It("should not consider markers at the end of a line", func() {
   228  			Expect(markersByField).To(HaveKeyWithValue(fieldPath{typ: "Foo", field: "WithGodoc"},
   229  				HaveKeyWithValue("testing:fieldlvl", Not(ContainElement("not here after field")))))
   230  
   231  			Expect(markersByField).To(HaveKeyWithValue(fieldPath{typ: "Foo", field: "WithoutGodoc"},
   232  				HaveKeyWithValue("testing:fieldlvl", Not(ContainElement("not here after field")))))
   233  		})
   234  	})
   235  })