diff --git a/go.mod b/go.mod index 93cd021b13..704b9ffb4f 100644 --- a/go.mod +++ b/go.mod @@ -9,18 +9,18 @@ require ( github.com/cert-manager/cert-manager v1.21.1 github.com/containerd/containerd v1.7.34 github.com/cucumber/gherkin/go/v26 v26.2.0 - github.com/cucumber/godog v0.15.1 + github.com/cucumber/godog v0.16.0 github.com/cucumber/messages/go/v21 v21.0.1 github.com/evanphx/json-patch v5.9.11+incompatible github.com/fsnotify/fsnotify v1.10.1 github.com/go-logr/logr v1.4.4 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-cmp v0.7.0 - github.com/google/go-containerregistry v0.21.7 + github.com/google/go-containerregistry v0.21.9 github.com/google/renameio/v2 v2.0.2 github.com/gorilla/handlers v1.5.2 github.com/graphql-go/graphql v0.8.1 - github.com/klauspost/compress v1.19.1 + github.com/klauspost/compress v1.19.2 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/operator-framework/api v0.45.0 @@ -31,7 +31,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v6 v6.0.3 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 - github.com/stretchr/testify v1.11.1 + github.com/stretchr/testify v1.12.0 go.podman.io/image/v5 v5.41.0 go.uber.org/mock v0.6.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f @@ -88,6 +88,8 @@ require ( github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.3.2 // indirect + github.com/cucumber/gherkin/go/v42 v42.0.0 // indirect + github.com/cucumber/messages/go/v34 v34.2.0 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect github.com/cyphar/filepath-securejoin v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/go.sum b/go.sum index 37ea1e65d6..800a0320ff 100644 --- a/go.sum +++ b/go.sum @@ -90,17 +90,19 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA= github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= -github.com/cucumber/godog v0.15.1 h1:rb/6oHDdvVZKS66hrhpjFQFHjthFSrQBCOI1LwshNTI= -github.com/cucumber/godog v0.15.1/go.mod h1:qju+SQDewOljHuq9NSM66s0xEhogx0q30flfxL4WUk8= +github.com/cucumber/gherkin/go/v42 v42.0.0 h1:Ulh3E2awUUSSja+wonP/IOQ+ycmiZwZbgmzqk5H8JNI= +github.com/cucumber/gherkin/go/v42 v42.0.0/go.mod h1:CsaumaO2dR9XvBc6ZyiGLMhWCKtTRDxgoxqJigSjSSg= +github.com/cucumber/godog v0.16.0 h1:ezQbgItuWqZrjPUQwLJ3muwIlvzXBOfZso5QZfG7efE= +github.com/cucumber/godog v0.16.0/go.mod h1:EDUX9yCqANK+GpbftMDeu61sUDtdLuo1JJgXD2n3bbM= github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= -github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= +github.com/cucumber/messages/go/v34 v34.2.0 h1:VCbcNOMz+f8ccjjOOx1NLBNhwvE7/X49Atc8klJa+i8= +github.com/cucumber/messages/go/v34 v34.2.0/go.mod h1:LYUPjqlTS1kS0pdkdf6sS5uirnjwiIzEGyXPezXNhL8= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyphar/filepath-securejoin v0.7.0 h1:s0Y3ITPy6sQn5xt54DuYvTF8hu134ooYLUb58DX/HjE= @@ -218,8 +220,6 @@ github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4 github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -261,8 +261,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU= -github.com/google/go-containerregistry v0.21.7/go.mod h1:kjSbt7/zMsKLWfnHrIvKvhXHUw91jbe9DNjPPJ32gXE= +github.com/google/go-containerregistry v0.21.9 h1:F+D4uZ3iA3DLMJLfhaqMdHJbzeqm/216WGQq2dokuLs= +github.com/google/go-containerregistry v0.21.9/go.mod h1:dP5XNKcL7kMFF/TB3LfvWmVhAcv7iqkHb3oDK8aauTo= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -297,10 +297,8 @@ github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -332,15 +330,12 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= -github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -485,11 +480,8 @@ github.com/smallstep/pkcs7 v0.2.1 h1:6Kfzr/QizdIuB6LSv8y1LJdZ3aPSfTNhTLqAx9CTLfA github.com/smallstep/pkcs7 v0.2.1/go.mod h1:RcXHsMfL+BzH8tRhmrF1NkkpebKpq3JEM66cOFxanf0= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -507,9 +499,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= +github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= github.com/ulikunitz/xz v0.5.16 h1:ld6NyySjx5lowVKwJvMRLnW5nxKX/xnpSiFYZ/Lxur0= github.com/ulikunitz/xz v0.5.16/go.mod h1:H9Rt/W6/Qj27PGauhQc6nfCDy7vHpzsOThBSaYDoEhw= github.com/vbatts/tar-split v0.12.3 h1:Cd46rkGXI3Td4yrVNwU8ripbxFaQbmesqhjBUUYAJSw= diff --git a/openshift/tests-extension/go.sum b/openshift/tests-extension/go.sum index b4c3143f79..b529372d3d 100644 --- a/openshift/tests-extension/go.sum +++ b/openshift/tests-extension/go.sum @@ -98,8 +98,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= -github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -189,8 +189,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= +github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= diff --git a/requirements.txt b/requirements.txt index 493d112da7..b28981411b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,14 +9,14 @@ ghp-import==2.1.0 idna==3.18 Jinja2==3.1.6 lxml==6.1.1 -Markdown==3.10.2 +Markdown==3.10.3 markdown2==2.5.5 MarkupSafe==3.0.3 mergedeep==1.3.4 mkdocs==1.6.1 mkdocs-material==9.7.7 mkdocs-material-extensions==1.3.1 -packaging==26.2 +packaging==26.3 paginate==0.5.7 pathspec==1.1.1 platformdirs==4.11.0 @@ -30,7 +30,7 @@ readtime==3.0.0 regex==2026.7.19 requests==2.34.2 six==1.17.0 -soupsieve==2.9.1 +soupsieve==2.9.2 urllib3==2.7.0 watchdog==6.0.0 mkdocs-asciinema-player==1.2.0 diff --git a/vendor/github.com/cucumber/gherkin/go/v42/.gitignore b/vendor/github.com/cucumber/gherkin/go/v42/.gitignore new file mode 100644 index 0000000000..7b0ee7aeb6 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/.gitignore @@ -0,0 +1,17 @@ +.built +.compared +.deps +.dist +.dist-compressed +.go-get +.gofmt +.linted +.tested* +acceptance/ +bin/ +dist/ +dist_compressed/ +*.bin +*.iml +# upx dist/cucumber-gherkin-openbsd-386 fails with a core dump +core.*.!usr!bin!upx-ucl diff --git a/vendor/github.com/cucumber/gherkin/go/v42/LICENSE b/vendor/github.com/cucumber/gherkin/go/v42/LICENSE new file mode 100644 index 0000000000..58780c68e1 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Cucumber Ltd, Gaspar Nagy, Björn Rasmusson, Peter Sergeant, and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cucumber/gherkin/go/v42/Makefile b/vendor/github.com/cucumber/gherkin/go/v42/Makefile new file mode 100644 index 0000000000..c1e75e42ed --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/Makefile @@ -0,0 +1,91 @@ +SHELL := /usr/bin/env bash + +GHERKIN_LANGUAGES_JSON = dialects_builtin.go +GHERKIN_PARSER = parser.go +GHERKIN_RAZOR = parser.go.razor +SOURCE_FILES = $(shell find . -name "*.go" | grep -v $(GHERKIN_PARSER)) + +GHERKIN = bin/gherkin +GHERKIN_GENERATE_TOKENS = bin/gherkin-generate-tokens + +GOOD_FEATURE_FILES = $(shell find ../testdata/good -name "*.feature") +BAD_FEATURE_FILES = $(shell find ../testdata/bad -name "*.feature") + +TOKENS = $(patsubst ../testdata/%,acceptance/testdata/%.tokens,$(GOOD_FEATURE_FILES)) +ASTS = $(patsubst ../testdata/%,acceptance/testdata/%.ast.ndjson,$(GOOD_FEATURE_FILES)) +PICKLES = $(patsubst ../testdata/%,acceptance/testdata/%.pickles.ndjson,$(GOOD_FEATURE_FILES)) +SOURCES = $(patsubst ../testdata/%,acceptance/testdata/%.source.ndjson,$(GOOD_FEATURE_FILES)) +ERRORS = $(patsubst ../testdata/%,acceptance/testdata/%.errors.ndjson,$(BAD_FEATURE_FILES)) + +.DEFAULT_GOAL = help + +help: ## Show this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) +.PHONY: help + +generate: $(GHERKIN_PARSER) ## Generate gherkin parser files +.PHONY: generate + +clean-generate: ## Remove generated Gherkin parser files ## Generate gherkin parser files + rm -f $(GHERKIN_PARSER) +.PHONY: clean-generate + +copy-gherkin-languages: $(GHERKIN_LANGUAGES_JSON) ## Copy gherkin-languages.json and/or generate derived files +.PHONY: copy-gherkin-languages + +clean-gherkin-languages: ## Remove gherkin-languages.json and any derived files + rm -f $(GHERKIN_LANGUAGES_JSON) +.PHONY: clean-gherkin-languages + +mostlyclean: + rm -rf .built + rm -rf acceptance + rm -rf bin +.PHONY: mostlyclean + +clean: mostlyclean ## Remove all build artifacts and files generated by the acceptance tests +.PHONY: clean + +.DELETE_ON_ERROR: + +acceptance: .built $(TOKENS) $(ASTS) $(PICKLES) $(ERRORS) $(SOURCES) ## Build acceptance test dir and compare results with reference + +.built: bin/gherkin-generate-tokens bin/gherkin + touch $@ + +bin/gherkin-generate-tokens: + go build -o $@ ./gherkin-generate-tokens + +bin/gherkin: + go build -o $@ -a ./main + +dialects_builtin.go: ../gherkin-languages.json dialects_builtin.go.jq + cat $< | jq --sort-keys --from-file dialects_builtin.go.jq --raw-output --compact-output > $@ + +$(GHERKIN_PARSER): $(GHERKIN_RAZOR) ../gherkin.berp + berp -g ../gherkin.berp -t $< -o $@ --noBOM + +acceptance/testdata/%.tokens: ../testdata/% ../testdata/%.tokens + mkdir -p $(@D) + $(GHERKIN_GENERATE_TOKENS) $< > $@ + diff --unified $<.tokens $@ + +acceptance/testdata/%.ast.ndjson: ../testdata/% ../testdata/%.ast.ndjson + mkdir -p $(@D) + $(GHERKIN) --no-source --no-pickles --predictable-ids $< | jq --sort-keys --compact-output "." > $@ + diff --unified <(jq "." $<.ast.ndjson) <(jq "." $@) + +acceptance/testdata/%.pickles.ndjson: ../testdata/% ../testdata/%.pickles.ndjson + mkdir -p $(@D) + $(GHERKIN) --no-source --no-ast --predictable-ids $< | jq --sort-keys --compact-output "." > $@ + diff --unified <(jq "." $<.pickles.ndjson) <(jq "." $@) + +acceptance/testdata/%.source.ndjson: ../testdata/% ../testdata/%.source.ndjson + mkdir -p $(@D) + $(GHERKIN) --no-ast --no-pickles --predictable-ids $< | jq --sort-keys --compact-output "." > $@ + diff --unified <(jq "." $<.source.ndjson) <(jq "." $@) + +acceptance/testdata/%.errors.ndjson: ../testdata/% ../testdata/%.errors.ndjson + mkdir -p $(@D) + $(GHERKIN) --no-source --predictable-ids $< | jq --sort-keys --compact-output "." > $@ + diff --unified <(jq "." $<.errors.ndjson) <(jq "." $@) diff --git a/vendor/github.com/cucumber/gherkin/go/v42/README.md b/vendor/github.com/cucumber/gherkin/go/v42/README.md new file mode 100644 index 0000000000..cdaba03c98 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/README.md @@ -0,0 +1,37 @@ +# Gherkin for Go + +[![GoDoc](https://pkg.go.dev/github.com/cucumber/gherkin/go?status.svg)](http://godoc.org/github.com/cucumber/gherkin/go) + +Gherkin parser/compiler for Go. Please see [Gherkin](https://github.com/cucumber/gherkin) for details. + +## Building + +You need Go installed (obviously). You also need to make sure your `PATH` +points to where Go installs packages: + +```bash +# Add go bin to path +export PATH=$(go env GOPATH)/bin:${PATH} +``` + +Now build it: + +``` +make .dist +``` + +You should have cross-compiled binaries in `./dist/`. + +## Compress binaries + +You need [upx](https://upx.github.io/) installed. + +``` +make .dist +make .dist-compressed +``` + +Your `./dist_compressed/` directory should now have compressed binaries. +Compression fails for some binaries, so you likely won't have a full set. + +The build copies the successfully compressed binaries back to `./dist/`. diff --git a/vendor/github.com/cucumber/gherkin/go/v42/astbuilder.go b/vendor/github.com/cucumber/gherkin/go/v42/astbuilder.go new file mode 100644 index 0000000000..78c8cdba38 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/astbuilder.go @@ -0,0 +1,452 @@ +package gherkin + +import ( + "github.com/cucumber/messages/go/v34" + "strings" +) + +type AstBuilder interface { + Builder + GetGherkinDocument() *messages.GherkinDocument +} + +type astBuilder struct { + stack []*astNode + comments []*messages.Comment + newId func() string +} + +func (t *astBuilder) Reset() { + t.comments = []*messages.Comment{} + t.stack = []*astNode{} + t.push(newAstNode(RuleTypeNone)) +} + +func (t *astBuilder) GetGherkinDocument() *messages.GherkinDocument { + res := t.currentNode().getSingle(RuleTypeGherkinDocument, nil) + if val, ok := res.(*messages.GherkinDocument); ok { + return val + } + return nil +} + +type astNode struct { + ruleType RuleType + subNodes map[RuleType][]interface{} +} + +func (a *astNode) add(rt RuleType, obj interface{}) { + a.subNodes[rt] = append(a.subNodes[rt], obj) +} + +func (a *astNode) getSingle(rt RuleType, defaultValue interface{}) interface{} { + if val, ok := a.subNodes[rt]; ok { + for i := range val { + return val[i] + } + } + return defaultValue +} + +func (a *astNode) getItems(rt RuleType) []interface{} { + var res []interface{} + if val, ok := a.subNodes[rt]; ok { + for i := range val { + res = append(res, val[i]) + } + } + return res +} + +func (a *astNode) getToken(tt TokenType) *Token { + if val, ok := a.getSingle(tt.RuleType(), nil).(*Token); ok { + return val + } + return nil +} + +func (a *astNode) getTokens(tt TokenType) []*Token { + var items = a.getItems(tt.RuleType()) + var tokens []*Token + for i := range items { + if val, ok := items[i].(*Token); ok { + tokens = append(tokens, val) + } + } + return tokens +} + +func (t *astBuilder) currentNode() *astNode { + if len(t.stack) > 0 { + return t.stack[len(t.stack)-1] + } + return nil +} + +func newAstNode(rt RuleType) *astNode { + return &astNode{ + ruleType: rt, + subNodes: make(map[RuleType][]interface{}), + } +} + +func NewAstBuilder(newId func() string) AstBuilder { + builder := new(astBuilder) + builder.newId = newId + builder.comments = []*messages.Comment{} + builder.push(newAstNode(RuleTypeNone)) + return builder +} + +func (t *astBuilder) push(n *astNode) { + t.stack = append(t.stack, n) +} + +func (t *astBuilder) pop() *astNode { + x := t.stack[len(t.stack)-1] + t.stack = t.stack[:len(t.stack)-1] + return x +} + +func (t *astBuilder) Build(tok *Token) (bool, error) { + if tok.Type == TokenTypeComment { + comment := &messages.Comment{ + Location: astLocation(tok), + Text: tok.Text, + } + t.comments = append(t.comments, comment) + } else { + t.currentNode().add(tok.Type.RuleType(), tok) + } + return true, nil +} + +func (t *astBuilder) StartRule(r RuleType) (bool, error) { + t.push(newAstNode(r)) + return true, nil +} + +func (t *astBuilder) EndRule(r RuleType) (bool, error) { + node := t.pop() + transformedNode, err := t.transformNode(node) + t.currentNode().add(node.ruleType, transformedNode) + return true, err +} + +func (t *astBuilder) transformNode(node *astNode) (interface{}, error) { + switch node.ruleType { + + case RuleTypeStep: + stepLine := node.getToken(TokenTypeStepLine) + + step := &messages.Step{ + Location: astLocation(stepLine), + Keyword: stepLine.Keyword, + KeywordType: stepLine.KeywordType, + Text: stepLine.Text, + Id: t.newId(), + } + dataTable := node.getSingle(RuleTypeDataTable, nil) + if dataTable != nil { + step.DataTable = dataTable.(*messages.DataTable) + } + docString := node.getSingle(RuleTypeDocString, nil) + if docString != nil { + step.DocString = docString.(*messages.DocString) + } + + return step, nil + + case RuleTypeDocString: + separatorToken := node.getToken(TokenTypeDocStringSeparator) + lineTokens := node.getTokens(TokenTypeOther) + var text string + for i := range lineTokens { + if i > 0 { + text += "\n" + } + text += lineTokens[i].Text + } + docString := &messages.DocString{ + Location: astLocation(separatorToken), + Content: text, + Delimiter: separatorToken.Keyword, + } + if len(separatorToken.Text) > 0 { + docString.MediaType = separatorToken.Text + } + + return docString, nil + + case RuleTypeDataTable: + rows, err := astTableRows(node, t.newId) + dt := &messages.DataTable{ + Location: rows[0].Location, + Rows: rows, + } + return dt, err + + case RuleTypeBackground: + backgroundLine := node.getToken(TokenTypeBackgroundLine) + bg := &messages.Background{ + Id: t.newId(), + Location: astLocation(backgroundLine), + Keyword: backgroundLine.Keyword, + Name: backgroundLine.Text, + Description: getDescription(node), + Steps: astSteps(node), + } + return bg, nil + + case RuleTypeScenarioDefinition: + scenarioNode := node.getSingle(RuleTypeScenario, nil).(*astNode) + scenarioLine := scenarioNode.getToken(TokenTypeScenarioLine) + tags := astTags(node, t.newId) + sc := &messages.Scenario{ + Id: t.newId(), + Tags: tags, + Location: astLocation(scenarioLine), + Keyword: scenarioLine.Keyword, + Name: scenarioLine.Text, + Description: getDescription(scenarioNode), + Steps: astSteps(scenarioNode), + Examples: astExamples(scenarioNode), + } + + return sc, nil + + case RuleTypeExamplesDefinition: + tags := astTags(node, t.newId) + examplesNode := node.getSingle(RuleTypeExamples, nil).(*astNode) + examplesLine := examplesNode.getToken(TokenTypeExamplesLine) + examplesTable := examplesNode.getSingle(RuleTypeExamplesTable, make([]*messages.TableRow, 0)).([]*messages.TableRow) + + var tableHeader *messages.TableRow + var tableBody []*messages.TableRow + + if len(examplesTable) > 0 { + tableHeader = examplesTable[0] + tableBody = examplesTable[1:] + } else { + tableHeader = nil + tableBody = examplesTable + } + + ex := &messages.Examples{ + Id: t.newId(), + Tags: tags, + Location: astLocation(examplesLine), + Keyword: examplesLine.Keyword, + Name: examplesLine.Text, + Description: getDescription(examplesNode), + TableHeader: tableHeader, + TableBody: tableBody, + } + return ex, nil + + case RuleTypeExamplesTable: + allRows, err := astTableRows(node, t.newId) + return allRows, err + + case RuleTypeDescription: + lineTokens := node.getTokens(TokenTypeOther) + // Trim trailing empty lines + end := len(lineTokens) + for end > 0 && strings.TrimSpace(lineTokens[end-1].Text) == "" { + end-- + } + var desc []string + for i := range lineTokens[0:end] { + desc = append(desc, lineTokens[i].Text) + } + return strings.Join(desc, "\n"), nil + + case RuleTypeFeature: + header := node.getSingle(RuleTypeFeatureHeader, nil).(*astNode) + tags := astTags(header, t.newId) + featureLine := header.getToken(TokenTypeFeatureLine) + if featureLine == nil { + return nil, nil + } + + children := make([]*messages.FeatureChild, 0) + background, _ := node.getSingle(RuleTypeBackground, nil).(*messages.Background) + if background != nil { + children = append(children, &messages.FeatureChild{ + Background: background, + }) + } + scenarios := node.getItems(RuleTypeScenarioDefinition) + for i := range scenarios { + scenario := scenarios[i].(*messages.Scenario) + children = append(children, &messages.FeatureChild{ + Scenario: scenario, + }) + } + rules := node.getItems(RuleTypeRule) + for i := range rules { + rule := rules[i].(*messages.Rule) + children = append(children, &messages.FeatureChild{ + Rule: rule, + }) + } + + feature := &messages.Feature{ + Tags: tags, + Location: astLocation(featureLine), + Language: featureLine.GherkinDialect, + Keyword: featureLine.Keyword, + Name: featureLine.Text, + Description: getDescription(header), + Children: children, + } + return feature, nil + + case RuleTypeRule: + header := node.getSingle(RuleTypeRuleHeader, nil).(*astNode) + ruleLine := header.getToken(TokenTypeRuleLine) + if ruleLine == nil { + return nil, nil + } + + tags := astTags(header, t.newId) + var children []*messages.RuleChild + background, _ := node.getSingle(RuleTypeBackground, nil).(*messages.Background) + + if background != nil { + children = append(children, &messages.RuleChild{ + Background: background, + }) + } + scenarios := node.getItems(RuleTypeScenarioDefinition) + for i := range scenarios { + scenario := scenarios[i].(*messages.Scenario) + children = append(children, &messages.RuleChild{ + Scenario: scenario, + }) + } + + rule := &messages.Rule{ + Id: t.newId(), + Location: astLocation(ruleLine), + Keyword: ruleLine.Keyword, + Name: ruleLine.Text, + Description: getDescription(header), + Children: children, + Tags: tags, + } + return rule, nil + + case RuleTypeGherkinDocument: + feature, _ := node.getSingle(RuleTypeFeature, nil).(*messages.Feature) + + doc := &messages.GherkinDocument{} + if feature != nil { + doc.Feature = feature + } + doc.Comments = t.comments + return doc, nil + } + return node, nil +} + +func getDescription(node *astNode) string { + return node.getSingle(RuleTypeDescription, "").(string) +} + +func astLocation(t *Token) *messages.Location { + return &messages.Location{ + Line: int64(t.Location.Line), + Column: int64(t.Location.Column), + } +} + +func astTableRows(t *astNode, newId func() string) (rows []*messages.TableRow, err error) { + rows = []*messages.TableRow{} + tokens := t.getTokens(TokenTypeTableRow) + for i := range tokens { + row := &messages.TableRow{ + Id: newId(), + Location: astLocation(tokens[i]), + Cells: astTableCells(tokens[i]), + } + rows = append(rows, row) + } + err = ensureCellCount(rows) + return +} + +func ensureCellCount(rows []*messages.TableRow) error { + if len(rows) <= 1 { + return nil + } + cellCount := len(rows[0].Cells) + for i := range rows { + if cellCount != len(rows[i].Cells) { + return &parseError{"inconsistent cell count within the table", &Location{ + Line: int(rows[i].Location.Line), + Column: int(rows[i].Location.Column), + }} + } + } + return nil +} + +func astTableCells(t *Token) (cells []*messages.TableCell) { + cells = []*messages.TableCell{} + for i := range t.Items { + item := t.Items[i] + cell := &messages.TableCell{} + cell.Location = &messages.Location{ + Line: int64(t.Location.Line), + Column: int64(item.Column), + } + cell.Value = item.Text + cells = append(cells, cell) + } + return +} + +func astSteps(t *astNode) (steps []*messages.Step) { + steps = []*messages.Step{} + tokens := t.getItems(RuleTypeStep) + for i := range tokens { + step, _ := tokens[i].(*messages.Step) + steps = append(steps, step) + } + return +} + +func astExamples(t *astNode) (examples []*messages.Examples) { + examples = []*messages.Examples{} + tokens := t.getItems(RuleTypeExamplesDefinition) + for i := range tokens { + example, _ := tokens[i].(*messages.Examples) + examples = append(examples, example) + } + return +} + +func astTags(node *astNode, newId func() string) (tags []*messages.Tag) { + tags = []*messages.Tag{} + tagsNode, ok := node.getSingle(RuleTypeTags, nil).(*astNode) + if !ok { + return + } + tokens := tagsNode.getTokens(TokenTypeTagLine) + for i := range tokens { + token := tokens[i] + for k := range token.Items { + item := token.Items[k] + tag := &messages.Tag{} + tag.Location = &messages.Location{ + Line: int64(token.Location.Line), + Column: int64(item.Column), + } + tag.Name = item.Text + tag.Id = newId() + tags = append(tags, tag) + } + } + return +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/dialect.go b/vendor/github.com/cucumber/gherkin/go/v42/dialect.go new file mode 100644 index 0000000000..7e51ca09e2 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/dialect.go @@ -0,0 +1,74 @@ +package gherkin + +import ( + "sort" + + messages "github.com/cucumber/messages/go/v34" +) + +func init() { + // only needs to be calcuated one, on startup + for _, d := range builtinDialects { + d.stepKeywords = []string{} + d.stepKeywords = append(d.stepKeywords, d.Keywords[given]...) + d.stepKeywords = append(d.stepKeywords, d.Keywords[when]...) + d.stepKeywords = append(d.stepKeywords, d.Keywords[then]...) + d.stepKeywords = append(d.stepKeywords, d.Keywords[and]...) + d.stepKeywords = append(d.stepKeywords, d.Keywords[but]...) + sort.Slice(d.stepKeywords, func(i, j int) bool { + return d.stepKeywords[i] > d.stepKeywords[j] + }) + } +} + +type Dialect struct { + Language string + Name string + Native string + Keywords map[string][]string + KeywordTypes map[string]messages.StepKeywordType + + stepKeywords []string +} + +func (g *Dialect) FeatureKeywords() []string { + return g.Keywords["feature"] +} + +func (g *Dialect) RuleKeywords() []string { + return g.Keywords["rule"] +} + +func (g *Dialect) ScenarioKeywords() []string { + return g.Keywords["scenario"] +} + +func (g *Dialect) StepKeywords() []string { + return g.stepKeywords +} + +func (g *Dialect) BackgroundKeywords() []string { + return g.Keywords["background"] +} + +func (g *Dialect) ScenarioOutlineKeywords() []string { + return g.Keywords["scenarioOutline"] +} + +func (g *Dialect) ExamplesKeywords() []string { + return g.Keywords["examples"] +} + +func (g *Dialect) StepKeywordType(keyword string) messages.StepKeywordType { + return g.KeywordTypes[keyword] +} + +type DialectProvider interface { + GetDialect(language string) *Dialect +} + +type gherkinDialectMap map[string]*Dialect + +func (g gherkinDialectMap) GetDialect(language string) *Dialect { + return g[language] +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go b/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go new file mode 100644 index 0000000000..7abb5ae4ab --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go @@ -0,0 +1,5758 @@ +// Code generated from dialects_builtin.go.jq (make dialects_builtin.go); DO NOT EDIT. + +package gherkin + +import messages "github.com/cucumber/messages/go/v34" + +// Builtin dialects for af (Afrikaans), am (Armenian), an (Aragonese), ar (Arabic), ast (Asturian), az (Azerbaijani), be (Belarusian), bg (Bulgarian), bm (Malay), bs (Bosnian), ca (Catalan), cs (Czech), cy-GB (Welsh), da (Danish), de (German), el (Greek), em (Emoji), en (English), en-Scouse (Scouse), en-au (Australian), en-lol (LOLCAT), en-old (Old English), en-pirate (Pirate), en-tx (Texas), eo (Esperanto), es (Spanish), et (Estonian), fa (Persian), fi (Finnish), fr (French), ga (Irish), gj (Gujarati), gl (Galician), he (Hebrew), hi (Hindi), hr (Croatian), ht (Creole), hu (Hungarian), id (Indonesian), is (Icelandic), it (Italian), ja (Japanese), jv (Javanese), ka (Georgian), kn (Kannada), ko (Korean), lt (Lithuanian), lu (Luxemburgish), lv (Latvian), mk-Cyrl (Macedonian), mk-Latn (Macedonian (Latin)), mn (Mongolian), ne (Nepali), nl (Dutch), no (Norwegian), pa (Panjabi), pl (Polish), pt (Portuguese), ro (Romanian), ru (Russian), sk (Slovak), sl (Slovenian), sr-Cyrl (Serbian), sr-Latn (Serbian (Latin)), sv (Swedish), ta (Tamil), th (Thai), te (Telugu), tlh (Klingon), tr (Turkish), tt (Tatar), uk (Ukrainian), ur (Urdu), uz (Uzbek), vi (Vietnamese), zh-CN (Chinese simplified), ml (Malayalam), zh-TW (Chinese traditional), mr (Marathi), amh (Amharic) +func DialectsBuiltin() DialectProvider { + return builtinDialects +} + +const ( + feature = "feature" + rule = "rule" + background = "background" + scenario = "scenario" + scenarioOutline = "scenarioOutline" + examples = "examples" + given = "given" + when = "when" + then = "then" + and = "and" + but = "but" +) + +var builtinDialects = gherkinDialectMap{ + "af": &Dialect{ + Language: "af", + Name: "Afrikaans", + Native: "Afrikaans", + Keywords: map[string][]string{ + feature: { + "Funksie", + "Besigheid Behoefte", + "Vermoë", + }, + rule: { + "Reël", + "Reel", + }, + background: { + "Agtergrond", + }, + scenario: { + "Voorbeeld", + "Situasie", + }, + scenarioOutline: { + "Situasie Uiteensetting", + }, + examples: { + "Voorbeelde", + }, + given: { + "* ", + "Gegewe ", + }, + when: { + "* ", + "Wanneer ", + }, + then: { + "* ", + "Dan ", + }, + and: { + "* ", + "En ", + }, + but: { + "* ", + "Maar ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Gegewe ": messages.StepKeywordType_CONTEXT, + + "Wanneer ": messages.StepKeywordType_ACTION, + + "Dan ": messages.StepKeywordType_OUTCOME, + + "En ": messages.StepKeywordType_CONJUNCTION, + + "Maar ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "am": &Dialect{ + Language: "am", + Name: "Armenian", + Native: "հայերեն", + Keywords: map[string][]string{ + feature: { + "Ֆունկցիոնալություն", + "Հատկություն", + }, + rule: { + "Rule", + }, + background: { + "Կոնտեքստ", + }, + scenario: { + "Օրինակ", + "Սցենար", + }, + scenarioOutline: { + "Սցենարի կառուցվացքը", + }, + examples: { + "Օրինակներ", + }, + given: { + "* ", + "Դիցուք ", + }, + when: { + "* ", + "Եթե ", + "Երբ ", + }, + then: { + "* ", + "Ապա ", + }, + and: { + "* ", + "Եվ ", + }, + but: { + "* ", + "Բայց ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Դիցուք ": messages.StepKeywordType_CONTEXT, + + "Եթե ": messages.StepKeywordType_ACTION, + + "Երբ ": messages.StepKeywordType_ACTION, + + "Ապա ": messages.StepKeywordType_OUTCOME, + + "Եվ ": messages.StepKeywordType_CONJUNCTION, + + "Բայց ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "an": &Dialect{ + Language: "an", + Name: "Aragonese", + Native: "Aragonés", + Keywords: map[string][]string{ + feature: { + "Caracteristica", + }, + rule: { + "Rule", + }, + background: { + "Antecedents", + }, + scenario: { + "Eixemplo", + "Caso", + }, + scenarioOutline: { + "Esquema del caso", + }, + examples: { + "Eixemplos", + }, + given: { + "* ", + "Dau ", + "Dada ", + "Daus ", + "Dadas ", + }, + when: { + "* ", + "Cuan ", + }, + then: { + "* ", + "Alavez ", + "Allora ", + "Antonces ", + }, + and: { + "* ", + "Y ", + "E ", + }, + but: { + "* ", + "Pero ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dau ": messages.StepKeywordType_CONTEXT, + + "Dada ": messages.StepKeywordType_CONTEXT, + + "Daus ": messages.StepKeywordType_CONTEXT, + + "Dadas ": messages.StepKeywordType_CONTEXT, + + "Cuan ": messages.StepKeywordType_ACTION, + + "Alavez ": messages.StepKeywordType_OUTCOME, + + "Allora ": messages.StepKeywordType_OUTCOME, + + "Antonces ": messages.StepKeywordType_OUTCOME, + + "Y ": messages.StepKeywordType_CONJUNCTION, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Pero ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ar": &Dialect{ + Language: "ar", + Name: "Arabic", + Native: "العربية", + Keywords: map[string][]string{ + feature: { + "خاصية", + }, + rule: { + "Rule", + }, + background: { + "الخلفية", + }, + scenario: { + "مثال", + "سيناريو", + }, + scenarioOutline: { + "سيناريو مخطط", + }, + examples: { + "امثلة", + }, + given: { + "* ", + "بفرض ", + }, + when: { + "* ", + "متى ", + "عندما ", + }, + then: { + "* ", + "اذاً ", + "ثم ", + }, + and: { + "* ", + "و ", + }, + but: { + "* ", + "لكن ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "بفرض ": messages.StepKeywordType_CONTEXT, + + "متى ": messages.StepKeywordType_ACTION, + + "عندما ": messages.StepKeywordType_ACTION, + + "اذاً ": messages.StepKeywordType_OUTCOME, + + "ثم ": messages.StepKeywordType_OUTCOME, + + "و ": messages.StepKeywordType_CONJUNCTION, + + "لكن ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ast": &Dialect{ + Language: "ast", + Name: "Asturian", + Native: "asturianu", + Keywords: map[string][]string{ + feature: { + "Carauterística", + }, + rule: { + "Rule", + }, + background: { + "Antecedentes", + }, + scenario: { + "Exemplo", + "Casu", + }, + scenarioOutline: { + "Esbozu del casu", + }, + examples: { + "Exemplos", + }, + given: { + "* ", + "Dáu ", + "Dada ", + "Daos ", + "Daes ", + }, + when: { + "* ", + "Cuando ", + }, + then: { + "* ", + "Entós ", + }, + and: { + "* ", + "Y ", + "Ya ", + }, + but: { + "* ", + "Peru ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dáu ": messages.StepKeywordType_CONTEXT, + + "Dada ": messages.StepKeywordType_CONTEXT, + + "Daos ": messages.StepKeywordType_CONTEXT, + + "Daes ": messages.StepKeywordType_CONTEXT, + + "Cuando ": messages.StepKeywordType_ACTION, + + "Entós ": messages.StepKeywordType_OUTCOME, + + "Y ": messages.StepKeywordType_CONJUNCTION, + + "Ya ": messages.StepKeywordType_CONJUNCTION, + + "Peru ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "az": &Dialect{ + Language: "az", + Name: "Azerbaijani", + Native: "Azərbaycanca", + Keywords: map[string][]string{ + feature: { + "Özəllik", + }, + rule: { + "Rule", + }, + background: { + "Keçmiş", + "Kontekst", + }, + scenario: { + "Nümunə", + "Ssenari", + }, + scenarioOutline: { + "Ssenarinin strukturu", + }, + examples: { + "Nümunələr", + }, + given: { + "* ", + "Tutaq ki ", + "Verilir ", + }, + when: { + "* ", + "Əgər ", + "Nə vaxt ki ", + }, + then: { + "* ", + "O halda ", + }, + and: { + "* ", + "Və ", + "Həm ", + }, + but: { + "* ", + "Amma ", + "Ancaq ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Tutaq ki ": messages.StepKeywordType_CONTEXT, + + "Verilir ": messages.StepKeywordType_CONTEXT, + + "Əgər ": messages.StepKeywordType_ACTION, + + "Nə vaxt ki ": messages.StepKeywordType_ACTION, + + "O halda ": messages.StepKeywordType_OUTCOME, + + "Və ": messages.StepKeywordType_CONJUNCTION, + + "Həm ": messages.StepKeywordType_CONJUNCTION, + + "Amma ": messages.StepKeywordType_CONJUNCTION, + + "Ancaq ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "be": &Dialect{ + Language: "be", + Name: "Belarusian", + Native: "Беларуская", + Keywords: map[string][]string{ + feature: { + "Функцыянальнасць", + "Фіча", + }, + rule: { + "Правілы", + }, + background: { + "Кантэкст", + }, + scenario: { + "Сцэнарый", + "Cцэнар", + }, + scenarioOutline: { + "Шаблон сцэнарыя", + "Узор сцэнара", + }, + examples: { + "Прыклады", + }, + given: { + "* ", + "Няхай ", + "Дадзена ", + }, + when: { + "* ", + "Калі ", + }, + then: { + "* ", + "Тады ", + }, + and: { + "* ", + "I ", + "Ды ", + "Таксама ", + }, + but: { + "* ", + "Але ", + "Інакш ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Няхай ": messages.StepKeywordType_CONTEXT, + + "Дадзена ": messages.StepKeywordType_CONTEXT, + + "Калі ": messages.StepKeywordType_ACTION, + + "Тады ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "Ды ": messages.StepKeywordType_CONJUNCTION, + + "Таксама ": messages.StepKeywordType_CONJUNCTION, + + "Але ": messages.StepKeywordType_CONJUNCTION, + + "Інакш ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "bg": &Dialect{ + Language: "bg", + Name: "Bulgarian", + Native: "български", + Keywords: map[string][]string{ + feature: { + "Функционалност", + }, + rule: { + "Правило", + }, + background: { + "Предистория", + }, + scenario: { + "Пример", + "Сценарий", + }, + scenarioOutline: { + "Рамка на сценарий", + }, + examples: { + "Примери", + }, + given: { + "* ", + "Дадено ", + }, + when: { + "* ", + "Когато ", + }, + then: { + "* ", + "То ", + }, + and: { + "* ", + "И ", + }, + but: { + "* ", + "Но ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Дадено ": messages.StepKeywordType_CONTEXT, + + "Когато ": messages.StepKeywordType_ACTION, + + "То ": messages.StepKeywordType_OUTCOME, + + "И ": messages.StepKeywordType_CONJUNCTION, + + "Но ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "bm": &Dialect{ + Language: "bm", + Name: "Malay", + Native: "Bahasa Melayu", + Keywords: map[string][]string{ + feature: { + "Fungsi", + }, + rule: { + "Rule", + }, + background: { + "Latar Belakang", + }, + scenario: { + "Senario", + "Situasi", + "Keadaan", + }, + scenarioOutline: { + "Kerangka Senario", + "Kerangka Situasi", + "Kerangka Keadaan", + "Garis Panduan Senario", + }, + examples: { + "Contoh", + }, + given: { + "* ", + "Diberi ", + "Bagi ", + }, + when: { + "* ", + "Apabila ", + }, + then: { + "* ", + "Maka ", + "Kemudian ", + }, + and: { + "* ", + "Dan ", + }, + but: { + "* ", + "Tetapi ", + "Tapi ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Diberi ": messages.StepKeywordType_CONTEXT, + + "Bagi ": messages.StepKeywordType_CONTEXT, + + "Apabila ": messages.StepKeywordType_ACTION, + + "Maka ": messages.StepKeywordType_OUTCOME, + + "Kemudian ": messages.StepKeywordType_OUTCOME, + + "Dan ": messages.StepKeywordType_CONJUNCTION, + + "Tetapi ": messages.StepKeywordType_CONJUNCTION, + + "Tapi ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "bs": &Dialect{ + Language: "bs", + Name: "Bosnian", + Native: "Bosanski", + Keywords: map[string][]string{ + feature: { + "Karakteristika", + }, + rule: { + "Rule", + }, + background: { + "Pozadina", + }, + scenario: { + "Primjer", + "Scenariju", + "Scenario", + }, + scenarioOutline: { + "Scenariju-obris", + "Scenario-outline", + }, + examples: { + "Primjeri", + }, + given: { + "* ", + "Dato ", + }, + when: { + "* ", + "Kada ", + }, + then: { + "* ", + "Zatim ", + }, + and: { + "* ", + "I ", + "A ", + }, + but: { + "* ", + "Ali ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dato ": messages.StepKeywordType_CONTEXT, + + "Kada ": messages.StepKeywordType_ACTION, + + "Zatim ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "A ": messages.StepKeywordType_CONJUNCTION, + + "Ali ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ca": &Dialect{ + Language: "ca", + Name: "Catalan", + Native: "català", + Keywords: map[string][]string{ + feature: { + "Característica", + "Funcionalitat", + }, + rule: { + "Rule", + }, + background: { + "Rerefons", + "Antecedents", + }, + scenario: { + "Exemple", + "Escenari", + }, + scenarioOutline: { + "Esquema de l'escenari", + }, + examples: { + "Exemples", + }, + given: { + "* ", + "Donat ", + "Donada ", + "Atès ", + "Atesa ", + }, + when: { + "* ", + "Quan ", + }, + then: { + "* ", + "Aleshores ", + "Cal ", + }, + and: { + "* ", + "I ", + }, + but: { + "* ", + "Però ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Donat ": messages.StepKeywordType_CONTEXT, + + "Donada ": messages.StepKeywordType_CONTEXT, + + "Atès ": messages.StepKeywordType_CONTEXT, + + "Atesa ": messages.StepKeywordType_CONTEXT, + + "Quan ": messages.StepKeywordType_ACTION, + + "Aleshores ": messages.StepKeywordType_OUTCOME, + + "Cal ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "Però ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "cs": &Dialect{ + Language: "cs", + Name: "Czech", + Native: "Česky", + Keywords: map[string][]string{ + feature: { + "Požadavek", + }, + rule: { + "Pravidlo", + }, + background: { + "Pozadí", + "Kontext", + }, + scenario: { + "Příklad", + "Scénář", + }, + scenarioOutline: { + "Náčrt Scénáře", + "Osnova scénáře", + }, + examples: { + "Příklady", + }, + given: { + "* ", + "Pokud ", + "Za předpokladu ", + }, + when: { + "* ", + "Když ", + }, + then: { + "* ", + "Pak ", + }, + and: { + "* ", + "A také ", + "A ", + }, + but: { + "* ", + "Ale ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Pokud ": messages.StepKeywordType_CONTEXT, + + "Za předpokladu ": messages.StepKeywordType_CONTEXT, + + "Když ": messages.StepKeywordType_ACTION, + + "Pak ": messages.StepKeywordType_OUTCOME, + + "A také ": messages.StepKeywordType_CONJUNCTION, + + "A ": messages.StepKeywordType_CONJUNCTION, + + "Ale ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "cy-GB": &Dialect{ + Language: "cy-GB", + Name: "Welsh", + Native: "Cymraeg", + Keywords: map[string][]string{ + feature: { + "Arwedd", + }, + rule: { + "Rule", + }, + background: { + "Cefndir", + }, + scenario: { + "Enghraifft", + "Scenario", + }, + scenarioOutline: { + "Scenario Amlinellol", + }, + examples: { + "Enghreifftiau", + }, + given: { + "* ", + "Anrhegedig a ", + }, + when: { + "* ", + "Pryd ", + }, + then: { + "* ", + "Yna ", + }, + and: { + "* ", + "A ", + }, + but: { + "* ", + "Ond ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Anrhegedig a ": messages.StepKeywordType_CONTEXT, + + "Pryd ": messages.StepKeywordType_ACTION, + + "Yna ": messages.StepKeywordType_OUTCOME, + + "A ": messages.StepKeywordType_CONJUNCTION, + + "Ond ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "da": &Dialect{ + Language: "da", + Name: "Danish", + Native: "dansk", + Keywords: map[string][]string{ + feature: { + "Egenskab", + }, + rule: { + "Regel", + }, + background: { + "Baggrund", + }, + scenario: { + "Eksempel", + "Scenarie", + }, + scenarioOutline: { + "Abstrakt Scenario", + }, + examples: { + "Eksempler", + }, + given: { + "* ", + "Givet ", + }, + when: { + "* ", + "Når ", + }, + then: { + "* ", + "Så ", + }, + and: { + "* ", + "Og ", + }, + but: { + "* ", + "Men ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Givet ": messages.StepKeywordType_CONTEXT, + + "Når ": messages.StepKeywordType_ACTION, + + "Så ": messages.StepKeywordType_OUTCOME, + + "Og ": messages.StepKeywordType_CONJUNCTION, + + "Men ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "de": &Dialect{ + Language: "de", + Name: "German", + Native: "Deutsch", + Keywords: map[string][]string{ + feature: { + "Funktionalität", + "Funktion", + }, + rule: { + "Rule", + "Regel", + }, + background: { + "Grundlage", + "Hintergrund", + "Voraussetzungen", + "Vorbedingungen", + }, + scenario: { + "Beispiel", + "Szenario", + }, + scenarioOutline: { + "Szenariogrundriss", + "Szenarien", + }, + examples: { + "Beispiele", + }, + given: { + "* ", + "Angenommen ", + "Gegeben sei ", + "Gegeben seien ", + }, + when: { + "* ", + "Wenn ", + }, + then: { + "* ", + "Dann ", + }, + and: { + "* ", + "Und ", + }, + but: { + "* ", + "Aber ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Angenommen ": messages.StepKeywordType_CONTEXT, + + "Gegeben sei ": messages.StepKeywordType_CONTEXT, + + "Gegeben seien ": messages.StepKeywordType_CONTEXT, + + "Wenn ": messages.StepKeywordType_ACTION, + + "Dann ": messages.StepKeywordType_OUTCOME, + + "Und ": messages.StepKeywordType_CONJUNCTION, + + "Aber ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "el": &Dialect{ + Language: "el", + Name: "Greek", + Native: "Ελληνικά", + Keywords: map[string][]string{ + feature: { + "Δυνατότητα", + "Λειτουργία", + }, + rule: { + "Rule", + }, + background: { + "Υπόβαθρο", + }, + scenario: { + "Παράδειγμα", + "Σενάριο", + }, + scenarioOutline: { + "Περιγραφή Σεναρίου", + "Περίγραμμα Σεναρίου", + }, + examples: { + "Παραδείγματα", + "Σενάρια", + }, + given: { + "* ", + "Δεδομένου ", + }, + when: { + "* ", + "Όταν ", + }, + then: { + "* ", + "Τότε ", + }, + and: { + "* ", + "Και ", + }, + but: { + "* ", + "Αλλά ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Δεδομένου ": messages.StepKeywordType_CONTEXT, + + "Όταν ": messages.StepKeywordType_ACTION, + + "Τότε ": messages.StepKeywordType_OUTCOME, + + "Και ": messages.StepKeywordType_CONJUNCTION, + + "Αλλά ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "em": &Dialect{ + Language: "em", + Name: "Emoji", + Native: "😀", + Keywords: map[string][]string{ + feature: { + "📚", + }, + rule: { + "Rule", + }, + background: { + "💤", + }, + scenario: { + "🥒", + "📕", + }, + scenarioOutline: { + "📖", + }, + examples: { + "📓", + }, + given: { + "* ", + "😐", + }, + when: { + "* ", + "🎬", + }, + then: { + "* ", + "🙏", + }, + and: { + "* ", + "😂", + }, + but: { + "* ", + "😔", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "😐": messages.StepKeywordType_CONTEXT, + + "🎬": messages.StepKeywordType_ACTION, + + "🙏": messages.StepKeywordType_OUTCOME, + + "😂": messages.StepKeywordType_CONJUNCTION, + + "😔": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en": &Dialect{ + Language: "en", + Name: "English", + Native: "English", + Keywords: map[string][]string{ + feature: { + "Feature", + "Business Need", + "Ability", + }, + rule: { + "Rule", + }, + background: { + "Background", + }, + scenario: { + "Example", + "Scenario", + }, + scenarioOutline: { + "Scenario Outline", + "Scenario Template", + }, + examples: { + "Examples", + "Scenarios", + }, + given: { + "* ", + "Given ", + }, + when: { + "* ", + "When ", + }, + then: { + "* ", + "Then ", + }, + and: { + "* ", + "And ", + }, + but: { + "* ", + "But ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Given ": messages.StepKeywordType_CONTEXT, + + "When ": messages.StepKeywordType_ACTION, + + "Then ": messages.StepKeywordType_OUTCOME, + + "And ": messages.StepKeywordType_CONJUNCTION, + + "But ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-Scouse": &Dialect{ + Language: "en-Scouse", + Name: "Scouse", + Native: "Scouse", + Keywords: map[string][]string{ + feature: { + "Feature", + }, + rule: { + "Rule", + }, + background: { + "Dis is what went down", + }, + scenario: { + "The thing of it is", + }, + scenarioOutline: { + "Wharrimean is", + }, + examples: { + "Examples", + }, + given: { + "* ", + "Givun ", + "Youse know when youse got ", + }, + when: { + "* ", + "Wun ", + "Youse know like when ", + }, + then: { + "* ", + "Dun ", + "Den youse gotta ", + }, + and: { + "* ", + "An ", + }, + but: { + "* ", + "Buh ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Givun ": messages.StepKeywordType_CONTEXT, + + "Youse know when youse got ": messages.StepKeywordType_CONTEXT, + + "Wun ": messages.StepKeywordType_ACTION, + + "Youse know like when ": messages.StepKeywordType_ACTION, + + "Dun ": messages.StepKeywordType_OUTCOME, + + "Den youse gotta ": messages.StepKeywordType_OUTCOME, + + "An ": messages.StepKeywordType_CONJUNCTION, + + "Buh ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-au": &Dialect{ + Language: "en-au", + Name: "Australian", + Native: "Australian", + Keywords: map[string][]string{ + feature: { + "Pretty much", + }, + rule: { + "Rule", + }, + background: { + "First off", + }, + scenario: { + "Awww, look mate", + }, + scenarioOutline: { + "Reckon it's like", + }, + examples: { + "You'll wanna", + }, + given: { + "* ", + "Y'know ", + }, + when: { + "* ", + "It's just unbelievable ", + }, + then: { + "* ", + "But at the end of the day I reckon ", + }, + and: { + "* ", + "Too right ", + }, + but: { + "* ", + "Yeah nah ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Y'know ": messages.StepKeywordType_CONTEXT, + + "It's just unbelievable ": messages.StepKeywordType_ACTION, + + "But at the end of the day I reckon ": messages.StepKeywordType_OUTCOME, + + "Too right ": messages.StepKeywordType_CONJUNCTION, + + "Yeah nah ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-lol": &Dialect{ + Language: "en-lol", + Name: "LOLCAT", + Native: "LOLCAT", + Keywords: map[string][]string{ + feature: { + "OH HAI", + }, + rule: { + "Rule", + }, + background: { + "B4", + }, + scenario: { + "MISHUN", + }, + scenarioOutline: { + "MISHUN SRSLY", + }, + examples: { + "EXAMPLZ", + }, + given: { + "* ", + "I CAN HAZ ", + }, + when: { + "* ", + "WEN ", + }, + then: { + "* ", + "DEN ", + }, + and: { + "* ", + "AN ", + }, + but: { + "* ", + "BUT ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "I CAN HAZ ": messages.StepKeywordType_CONTEXT, + + "WEN ": messages.StepKeywordType_ACTION, + + "DEN ": messages.StepKeywordType_OUTCOME, + + "AN ": messages.StepKeywordType_CONJUNCTION, + + "BUT ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-old": &Dialect{ + Language: "en-old", + Name: "Old English", + Native: "Englisc", + Keywords: map[string][]string{ + feature: { + "Hwaet", + "Hwæt", + }, + rule: { + "Rule", + }, + background: { + "Aer", + "Ær", + }, + scenario: { + "Swa", + }, + scenarioOutline: { + "Swa hwaer swa", + "Swa hwær swa", + }, + examples: { + "Se the", + "Se þe", + "Se ðe", + }, + given: { + "* ", + "Thurh ", + "Þurh ", + "Ðurh ", + }, + when: { + "* ", + "Bæþsealf ", + "Bæþsealfa ", + "Bæþsealfe ", + "Ciricæw ", + "Ciricæwe ", + "Ciricæwa ", + }, + then: { + "* ", + "Tha ", + "Þa ", + "Ða ", + "Tha the ", + "Þa þe ", + "Ða ðe ", + }, + and: { + "* ", + "Ond ", + "7 ", + }, + but: { + "* ", + "Ac ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Thurh ": messages.StepKeywordType_CONTEXT, + + "Þurh ": messages.StepKeywordType_CONTEXT, + + "Ðurh ": messages.StepKeywordType_CONTEXT, + + "Bæþsealf ": messages.StepKeywordType_ACTION, + + "Bæþsealfa ": messages.StepKeywordType_ACTION, + + "Bæþsealfe ": messages.StepKeywordType_ACTION, + + "Ciricæw ": messages.StepKeywordType_ACTION, + + "Ciricæwe ": messages.StepKeywordType_ACTION, + + "Ciricæwa ": messages.StepKeywordType_ACTION, + + "Tha ": messages.StepKeywordType_OUTCOME, + + "Þa ": messages.StepKeywordType_OUTCOME, + + "Ða ": messages.StepKeywordType_OUTCOME, + + "Tha the ": messages.StepKeywordType_OUTCOME, + + "Þa þe ": messages.StepKeywordType_OUTCOME, + + "Ða ðe ": messages.StepKeywordType_OUTCOME, + + "Ond ": messages.StepKeywordType_CONJUNCTION, + + "7 ": messages.StepKeywordType_CONJUNCTION, + + "Ac ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-pirate": &Dialect{ + Language: "en-pirate", + Name: "Pirate", + Native: "Pirate", + Keywords: map[string][]string{ + feature: { + "Ahoy matey!", + }, + rule: { + "Rule", + }, + background: { + "Yo-ho-ho", + }, + scenario: { + "Heave to", + }, + scenarioOutline: { + "Shiver me timbers", + }, + examples: { + "Dead men tell no tales", + }, + given: { + "* ", + "Gangway! ", + }, + when: { + "* ", + "Blimey! ", + }, + then: { + "* ", + "Let go and haul ", + }, + and: { + "* ", + "Aye ", + }, + but: { + "* ", + "Avast! ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Gangway! ": messages.StepKeywordType_CONTEXT, + + "Blimey! ": messages.StepKeywordType_ACTION, + + "Let go and haul ": messages.StepKeywordType_OUTCOME, + + "Aye ": messages.StepKeywordType_CONJUNCTION, + + "Avast! ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "en-tx": &Dialect{ + Language: "en-tx", + Name: "Texas", + Native: "Texas", + Keywords: map[string][]string{ + feature: { + "This ain’t my first rodeo", + "All gussied up", + }, + rule: { + "Rule ", + }, + background: { + "Lemme tell y'all a story", + }, + scenario: { + "All hat and no cattle", + }, + scenarioOutline: { + "Serious as a snake bite", + "Busy as a hound in flea season", + }, + examples: { + "Now that's a story longer than a cattle drive in July", + }, + given: { + "Fixin' to ", + "All git out ", + }, + when: { + "Quick out of the chute ", + }, + then: { + "There’s no tree but bears some fruit ", + }, + and: { + "Come hell or high water ", + }, + but: { + "Well now hold on, I'll you what ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Fixin' to ": messages.StepKeywordType_CONTEXT, + + "All git out ": messages.StepKeywordType_CONTEXT, + + "Quick out of the chute ": messages.StepKeywordType_ACTION, + + "There’s no tree but bears some fruit ": messages.StepKeywordType_OUTCOME, + + "Come hell or high water ": messages.StepKeywordType_CONJUNCTION, + + "Well now hold on, I'll you what ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "eo": &Dialect{ + Language: "eo", + Name: "Esperanto", + Native: "Esperanto", + Keywords: map[string][]string{ + feature: { + "Trajto", + }, + rule: { + "Regulo", + }, + background: { + "Fono", + }, + scenario: { + "Ekzemplo", + "Scenaro", + "Kazo", + }, + scenarioOutline: { + "Konturo de la scenaro", + "Skizo", + "Kazo-skizo", + }, + examples: { + "Ekzemploj", + }, + given: { + "* ", + "Donitaĵo ", + "Komence ", + }, + when: { + "* ", + "Se ", + }, + then: { + "* ", + "Do ", + }, + and: { + "* ", + "Kaj ", + }, + but: { + "* ", + "Sed ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Donitaĵo ": messages.StepKeywordType_CONTEXT, + + "Komence ": messages.StepKeywordType_CONTEXT, + + "Se ": messages.StepKeywordType_ACTION, + + "Do ": messages.StepKeywordType_OUTCOME, + + "Kaj ": messages.StepKeywordType_CONJUNCTION, + + "Sed ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "es": &Dialect{ + Language: "es", + Name: "Spanish", + Native: "español", + Keywords: map[string][]string{ + feature: { + "Característica", + "Necesidad del negocio", + "Requisito", + }, + rule: { + "Regla", + "Regla de negocio", + }, + background: { + "Antecedentes", + }, + scenario: { + "Ejemplo", + "Escenario", + }, + scenarioOutline: { + "Esquema del escenario", + }, + examples: { + "Ejemplos", + }, + given: { + "* ", + "Dado ", + "Dada ", + "Dados ", + "Dadas ", + }, + when: { + "* ", + "Cuando ", + }, + then: { + "* ", + "Entonces ", + }, + and: { + "* ", + "Y ", + "E ", + }, + but: { + "* ", + "Pero ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dado ": messages.StepKeywordType_CONTEXT, + + "Dada ": messages.StepKeywordType_CONTEXT, + + "Dados ": messages.StepKeywordType_CONTEXT, + + "Dadas ": messages.StepKeywordType_CONTEXT, + + "Cuando ": messages.StepKeywordType_ACTION, + + "Entonces ": messages.StepKeywordType_OUTCOME, + + "Y ": messages.StepKeywordType_CONJUNCTION, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Pero ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "et": &Dialect{ + Language: "et", + Name: "Estonian", + Native: "eesti keel", + Keywords: map[string][]string{ + feature: { + "Omadus", + }, + rule: { + "Reegel", + }, + background: { + "Taust", + }, + scenario: { + "Juhtum", + "Stsenaarium", + }, + scenarioOutline: { + "Raamjuhtum", + "Raamstsenaarium", + }, + examples: { + "Juhtumid", + }, + given: { + "* ", + "Eeldades ", + }, + when: { + "* ", + "Kui ", + }, + then: { + "* ", + "Siis ", + }, + and: { + "* ", + "Ja ", + }, + but: { + "* ", + "Kuid ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Eeldades ": messages.StepKeywordType_CONTEXT, + + "Kui ": messages.StepKeywordType_ACTION, + + "Siis ": messages.StepKeywordType_OUTCOME, + + "Ja ": messages.StepKeywordType_CONJUNCTION, + + "Kuid ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "fa": &Dialect{ + Language: "fa", + Name: "Persian", + Native: "فارسی", + Keywords: map[string][]string{ + feature: { + "ویژگی", + "قابلیت", + }, + rule: { + "قانون", + }, + background: { + "زمینه", + "پیش زمینه", + "مقدمات", + }, + scenario: { + "مثال", + "سناریو", + }, + scenarioOutline: { + "الگوی سناریو", + }, + examples: { + "نمونه ها", + }, + given: { + "* ", + "با فرض ", + "فرض کنید ", + "با در نظر گرفتن ", + }, + when: { + "* ", + "هنگامی ", + "وقتی ", + }, + then: { + "* ", + "آنگاه ", + "سپس ", + "انتظار می رود ", + }, + and: { + "* ", + "و ", + }, + but: { + "* ", + "اما ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "با فرض ": messages.StepKeywordType_CONTEXT, + + "فرض کنید ": messages.StepKeywordType_CONTEXT, + + "با در نظر گرفتن ": messages.StepKeywordType_CONTEXT, + + "هنگامی ": messages.StepKeywordType_ACTION, + + "وقتی ": messages.StepKeywordType_ACTION, + + "آنگاه ": messages.StepKeywordType_OUTCOME, + + "سپس ": messages.StepKeywordType_OUTCOME, + + "انتظار می رود ": messages.StepKeywordType_OUTCOME, + + "و ": messages.StepKeywordType_CONJUNCTION, + + "اما ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "fi": &Dialect{ + Language: "fi", + Name: "Finnish", + Native: "suomi", + Keywords: map[string][]string{ + feature: { + "Ominaisuus", + }, + rule: { + "Rule", + }, + background: { + "Tausta", + }, + scenario: { + "Tapaus", + }, + scenarioOutline: { + "Tapausaihio", + }, + examples: { + "Tapaukset", + }, + given: { + "* ", + "Oletetaan ", + }, + when: { + "* ", + "Kun ", + }, + then: { + "* ", + "Niin ", + }, + and: { + "* ", + "Ja ", + }, + but: { + "* ", + "Mutta ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Oletetaan ": messages.StepKeywordType_CONTEXT, + + "Kun ": messages.StepKeywordType_ACTION, + + "Niin ": messages.StepKeywordType_OUTCOME, + + "Ja ": messages.StepKeywordType_CONJUNCTION, + + "Mutta ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "fr": &Dialect{ + Language: "fr", + Name: "French", + Native: "français", + Keywords: map[string][]string{ + feature: { + "Fonctionnalité", + }, + rule: { + "Règle", + }, + background: { + "Contexte", + }, + scenario: { + "Exemple", + "Scénario", + }, + scenarioOutline: { + "Plan du scénario", + "Plan du Scénario", + }, + examples: { + "Exemples", + }, + given: { + "* ", + "Soit ", + "Sachant que ", + "Sachant qu'", + "Sachant ", + "Etant donné que ", + "Etant donné qu'", + "Etant donné ", + "Etant donnée ", + "Etant donnés ", + "Etant données ", + "Étant donné que ", + "Étant donné qu'", + "Étant donné ", + "Étant donnée ", + "Étant donnés ", + "Étant données ", + }, + when: { + "* ", + "Quand ", + "Lorsque ", + "Lorsqu'", + }, + then: { + "* ", + "Alors ", + "Donc ", + }, + and: { + "* ", + "Et que ", + "Et qu'", + "Et ", + }, + but: { + "* ", + "Mais que ", + "Mais qu'", + "Mais ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Soit ": messages.StepKeywordType_CONTEXT, + + "Sachant que ": messages.StepKeywordType_CONTEXT, + + "Sachant qu'": messages.StepKeywordType_CONTEXT, + + "Sachant ": messages.StepKeywordType_CONTEXT, + + "Etant donné que ": messages.StepKeywordType_CONTEXT, + + "Etant donné qu'": messages.StepKeywordType_CONTEXT, + + "Etant donné ": messages.StepKeywordType_CONTEXT, + + "Etant donnée ": messages.StepKeywordType_CONTEXT, + + "Etant donnés ": messages.StepKeywordType_CONTEXT, + + "Etant données ": messages.StepKeywordType_CONTEXT, + + "Étant donné que ": messages.StepKeywordType_CONTEXT, + + "Étant donné qu'": messages.StepKeywordType_CONTEXT, + + "Étant donné ": messages.StepKeywordType_CONTEXT, + + "Étant donnée ": messages.StepKeywordType_CONTEXT, + + "Étant donnés ": messages.StepKeywordType_CONTEXT, + + "Étant données ": messages.StepKeywordType_CONTEXT, + + "Quand ": messages.StepKeywordType_ACTION, + + "Lorsque ": messages.StepKeywordType_ACTION, + + "Lorsqu'": messages.StepKeywordType_ACTION, + + "Alors ": messages.StepKeywordType_OUTCOME, + + "Donc ": messages.StepKeywordType_OUTCOME, + + "Et que ": messages.StepKeywordType_CONJUNCTION, + + "Et qu'": messages.StepKeywordType_CONJUNCTION, + + "Et ": messages.StepKeywordType_CONJUNCTION, + + "Mais que ": messages.StepKeywordType_CONJUNCTION, + + "Mais qu'": messages.StepKeywordType_CONJUNCTION, + + "Mais ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ga": &Dialect{ + Language: "ga", + Name: "Irish", + Native: "Gaeilge", + Keywords: map[string][]string{ + feature: { + "Gné", + }, + rule: { + "Riail", + }, + background: { + "Cúlra", + }, + scenario: { + "Sampla", + "Cás", + }, + scenarioOutline: { + "Cás Achomair", + }, + examples: { + "Samplaí", + }, + given: { + "* ", + "Cuir i gcás go ", + "Cuir i gcás nach ", + "Cuir i gcás gur ", + "Cuir i gcás nár ", + }, + when: { + "* ", + "Nuair a ", + "Nuair nach ", + "Nuair ba ", + "Nuair nár ", + }, + then: { + "* ", + "Ansin ", + }, + and: { + "* ", + "Agus ", + }, + but: { + "* ", + "Ach ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Cuir i gcás go ": messages.StepKeywordType_CONTEXT, + + "Cuir i gcás nach ": messages.StepKeywordType_CONTEXT, + + "Cuir i gcás gur ": messages.StepKeywordType_CONTEXT, + + "Cuir i gcás nár ": messages.StepKeywordType_CONTEXT, + + "Nuair a ": messages.StepKeywordType_ACTION, + + "Nuair nach ": messages.StepKeywordType_ACTION, + + "Nuair ba ": messages.StepKeywordType_ACTION, + + "Nuair nár ": messages.StepKeywordType_ACTION, + + "Ansin ": messages.StepKeywordType_OUTCOME, + + "Agus ": messages.StepKeywordType_CONJUNCTION, + + "Ach ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "gj": &Dialect{ + Language: "gj", + Name: "Gujarati", + Native: "ગુજરાતી", + Keywords: map[string][]string{ + feature: { + "લક્ષણ", + "વ્યાપાર જરૂર", + "ક્ષમતા", + }, + rule: { + "નિયમ", + }, + background: { + "બેકગ્રાઉન્ડ", + }, + scenario: { + "ઉદાહરણ", + "સ્થિતિ", + }, + scenarioOutline: { + "પરિદ્દશ્ય રૂપરેખા", + "પરિદ્દશ્ય ઢાંચો", + }, + examples: { + "ઉદાહરણો", + }, + given: { + "* ", + "આપેલ છે ", + }, + when: { + "* ", + "ક્યારે ", + }, + then: { + "* ", + "પછી ", + }, + and: { + "* ", + "અને ", + }, + but: { + "* ", + "પણ ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "આપેલ છે ": messages.StepKeywordType_CONTEXT, + + "ક્યારે ": messages.StepKeywordType_ACTION, + + "પછી ": messages.StepKeywordType_OUTCOME, + + "અને ": messages.StepKeywordType_CONJUNCTION, + + "પણ ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "gl": &Dialect{ + Language: "gl", + Name: "Galician", + Native: "galego", + Keywords: map[string][]string{ + feature: { + "Característica", + }, + rule: { + "Rule", + }, + background: { + "Contexto", + }, + scenario: { + "Exemplo", + "Escenario", + }, + scenarioOutline: { + "Esbozo do escenario", + }, + examples: { + "Exemplos", + }, + given: { + "* ", + "Dado ", + "Dada ", + "Dados ", + "Dadas ", + }, + when: { + "* ", + "Cando ", + }, + then: { + "* ", + "Entón ", + "Logo ", + }, + and: { + "* ", + "E ", + }, + but: { + "* ", + "Mais ", + "Pero ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dado ": messages.StepKeywordType_CONTEXT, + + "Dada ": messages.StepKeywordType_CONTEXT, + + "Dados ": messages.StepKeywordType_CONTEXT, + + "Dadas ": messages.StepKeywordType_CONTEXT, + + "Cando ": messages.StepKeywordType_ACTION, + + "Entón ": messages.StepKeywordType_OUTCOME, + + "Logo ": messages.StepKeywordType_OUTCOME, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Mais ": messages.StepKeywordType_CONJUNCTION, + + "Pero ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "he": &Dialect{ + Language: "he", + Name: "Hebrew", + Native: "עברית", + Keywords: map[string][]string{ + feature: { + "תכונה", + }, + rule: { + "כלל", + }, + background: { + "רקע", + }, + scenario: { + "דוגמא", + "תרחיש", + }, + scenarioOutline: { + "תבנית תרחיש", + }, + examples: { + "דוגמאות", + }, + given: { + "* ", + "בהינתן ", + }, + when: { + "* ", + "כאשר ", + }, + then: { + "* ", + "אז ", + "אזי ", + }, + and: { + "* ", + "וגם ", + }, + but: { + "* ", + "אבל ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "בהינתן ": messages.StepKeywordType_CONTEXT, + + "כאשר ": messages.StepKeywordType_ACTION, + + "אז ": messages.StepKeywordType_OUTCOME, + + "אזי ": messages.StepKeywordType_OUTCOME, + + "וגם ": messages.StepKeywordType_CONJUNCTION, + + "אבל ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "hi": &Dialect{ + Language: "hi", + Name: "Hindi", + Native: "हिंदी", + Keywords: map[string][]string{ + feature: { + "रूप लेख", + }, + rule: { + "नियम", + }, + background: { + "पृष्ठभूमि", + }, + scenario: { + "परिदृश्य", + }, + scenarioOutline: { + "परिदृश्य रूपरेखा", + }, + examples: { + "उदाहरण", + }, + given: { + "* ", + "अगर ", + "यदि ", + "चूंकि ", + }, + when: { + "* ", + "जब ", + "कदा ", + }, + then: { + "* ", + "तब ", + "तदा ", + }, + and: { + "* ", + "और ", + "तथा ", + }, + but: { + "* ", + "पर ", + "परन्तु ", + "किन्तु ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "अगर ": messages.StepKeywordType_CONTEXT, + + "यदि ": messages.StepKeywordType_CONTEXT, + + "चूंकि ": messages.StepKeywordType_CONTEXT, + + "जब ": messages.StepKeywordType_ACTION, + + "कदा ": messages.StepKeywordType_ACTION, + + "तब ": messages.StepKeywordType_OUTCOME, + + "तदा ": messages.StepKeywordType_OUTCOME, + + "और ": messages.StepKeywordType_CONJUNCTION, + + "तथा ": messages.StepKeywordType_CONJUNCTION, + + "पर ": messages.StepKeywordType_CONJUNCTION, + + "परन्तु ": messages.StepKeywordType_CONJUNCTION, + + "किन्तु ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "hr": &Dialect{ + Language: "hr", + Name: "Croatian", + Native: "hrvatski", + Keywords: map[string][]string{ + feature: { + "Osobina", + "Mogućnost", + "Mogucnost", + }, + rule: { + "Rule", + }, + background: { + "Pozadina", + }, + scenario: { + "Primjer", + "Scenarij", + }, + scenarioOutline: { + "Skica", + "Koncept", + }, + examples: { + "Primjeri", + "Scenariji", + }, + given: { + "* ", + "Zadan ", + "Zadani ", + "Zadano ", + "Ukoliko ", + }, + when: { + "* ", + "Kada ", + "Kad ", + }, + then: { + "* ", + "Onda ", + }, + and: { + "* ", + "I ", + }, + but: { + "* ", + "Ali ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Zadan ": messages.StepKeywordType_CONTEXT, + + "Zadani ": messages.StepKeywordType_CONTEXT, + + "Zadano ": messages.StepKeywordType_CONTEXT, + + "Ukoliko ": messages.StepKeywordType_CONTEXT, + + "Kada ": messages.StepKeywordType_ACTION, + + "Kad ": messages.StepKeywordType_ACTION, + + "Onda ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "Ali ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ht": &Dialect{ + Language: "ht", + Name: "Creole", + Native: "kreyòl", + Keywords: map[string][]string{ + feature: { + "Karakteristik", + "Mak", + "Fonksyonalite", + }, + rule: { + "Rule", + }, + background: { + "Kontèks", + "Istorik", + }, + scenario: { + "Senaryo", + }, + scenarioOutline: { + "Plan senaryo", + "Plan Senaryo", + "Senaryo deskripsyon", + "Senaryo Deskripsyon", + "Dyagram senaryo", + "Dyagram Senaryo", + }, + examples: { + "Egzanp", + }, + given: { + "* ", + "Sipoze ", + "Sipoze ke ", + "Sipoze Ke ", + }, + when: { + "* ", + "Lè ", + "Le ", + }, + then: { + "* ", + "Lè sa a ", + "Le sa a ", + }, + and: { + "* ", + "Ak ", + "Epi ", + "E ", + }, + but: { + "* ", + "Men ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Sipoze ": messages.StepKeywordType_CONTEXT, + + "Sipoze ke ": messages.StepKeywordType_CONTEXT, + + "Sipoze Ke ": messages.StepKeywordType_CONTEXT, + + "Lè ": messages.StepKeywordType_ACTION, + + "Le ": messages.StepKeywordType_ACTION, + + "Lè sa a ": messages.StepKeywordType_OUTCOME, + + "Le sa a ": messages.StepKeywordType_OUTCOME, + + "Ak ": messages.StepKeywordType_CONJUNCTION, + + "Epi ": messages.StepKeywordType_CONJUNCTION, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Men ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "hu": &Dialect{ + Language: "hu", + Name: "Hungarian", + Native: "magyar", + Keywords: map[string][]string{ + feature: { + "Jellemző", + }, + rule: { + "Szabály", + }, + background: { + "Háttér", + }, + scenario: { + "Példa", + "Forgatókönyv", + }, + scenarioOutline: { + "Forgatókönyv vázlat", + }, + examples: { + "Példák", + }, + given: { + "* ", + "Amennyiben ", + "Adott ", + }, + when: { + "* ", + "Majd ", + "Ha ", + "Amikor ", + }, + then: { + "* ", + "Akkor ", + }, + and: { + "* ", + "És ", + }, + but: { + "* ", + "De ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Amennyiben ": messages.StepKeywordType_CONTEXT, + + "Adott ": messages.StepKeywordType_CONTEXT, + + "Majd ": messages.StepKeywordType_ACTION, + + "Ha ": messages.StepKeywordType_ACTION, + + "Amikor ": messages.StepKeywordType_ACTION, + + "Akkor ": messages.StepKeywordType_OUTCOME, + + "És ": messages.StepKeywordType_CONJUNCTION, + + "De ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "id": &Dialect{ + Language: "id", + Name: "Indonesian", + Native: "Bahasa Indonesia", + Keywords: map[string][]string{ + feature: { + "Fitur", + }, + rule: { + "Rule", + "Aturan", + }, + background: { + "Dasar", + "Latar Belakang", + }, + scenario: { + "Skenario", + }, + scenarioOutline: { + "Skenario konsep", + "Garis-Besar Skenario", + }, + examples: { + "Contoh", + "Misal", + }, + given: { + "* ", + "Dengan ", + "Diketahui ", + "Diasumsikan ", + "Bila ", + "Jika ", + }, + when: { + "* ", + "Ketika ", + }, + then: { + "* ", + "Maka ", + "Kemudian ", + }, + and: { + "* ", + "Dan ", + }, + but: { + "* ", + "Tapi ", + "Tetapi ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dengan ": messages.StepKeywordType_CONTEXT, + + "Diketahui ": messages.StepKeywordType_CONTEXT, + + "Diasumsikan ": messages.StepKeywordType_CONTEXT, + + "Bila ": messages.StepKeywordType_CONTEXT, + + "Jika ": messages.StepKeywordType_CONTEXT, + + "Ketika ": messages.StepKeywordType_ACTION, + + "Maka ": messages.StepKeywordType_OUTCOME, + + "Kemudian ": messages.StepKeywordType_OUTCOME, + + "Dan ": messages.StepKeywordType_CONJUNCTION, + + "Tapi ": messages.StepKeywordType_CONJUNCTION, + + "Tetapi ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "is": &Dialect{ + Language: "is", + Name: "Icelandic", + Native: "Íslenska", + Keywords: map[string][]string{ + feature: { + "Eiginleiki", + }, + rule: { + "Rule", + }, + background: { + "Bakgrunnur", + }, + scenario: { + "Atburðarás", + }, + scenarioOutline: { + "Lýsing Atburðarásar", + "Lýsing Dæma", + }, + examples: { + "Dæmi", + "Atburðarásir", + }, + given: { + "* ", + "Ef ", + }, + when: { + "* ", + "Þegar ", + }, + then: { + "* ", + "Þá ", + }, + and: { + "* ", + "Og ", + }, + but: { + "* ", + "En ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Ef ": messages.StepKeywordType_CONTEXT, + + "Þegar ": messages.StepKeywordType_ACTION, + + "Þá ": messages.StepKeywordType_OUTCOME, + + "Og ": messages.StepKeywordType_CONJUNCTION, + + "En ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "it": &Dialect{ + Language: "it", + Name: "Italian", + Native: "italiano", + Keywords: map[string][]string{ + feature: { + "Funzionalità", + "Esigenza di Business", + "Abilità", + }, + rule: { + "Regola", + }, + background: { + "Contesto", + }, + scenario: { + "Esempio", + "Scenario", + }, + scenarioOutline: { + "Schema dello scenario", + }, + examples: { + "Esempi", + }, + given: { + "* ", + "Dato ", + "Data ", + "Dati ", + "Date ", + }, + when: { + "* ", + "Quando ", + }, + then: { + "* ", + "Allora ", + }, + and: { + "* ", + "E ", + "Ed ", + }, + but: { + "* ", + "Ma ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dato ": messages.StepKeywordType_CONTEXT, + + "Data ": messages.StepKeywordType_CONTEXT, + + "Dati ": messages.StepKeywordType_CONTEXT, + + "Date ": messages.StepKeywordType_CONTEXT, + + "Quando ": messages.StepKeywordType_ACTION, + + "Allora ": messages.StepKeywordType_OUTCOME, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Ed ": messages.StepKeywordType_CONJUNCTION, + + "Ma ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ja": &Dialect{ + Language: "ja", + Name: "Japanese", + Native: "日本語", + Keywords: map[string][]string{ + feature: { + "フィーチャ", + "機能", + }, + rule: { + "ルール", + }, + background: { + "背景", + }, + scenario: { + "シナリオ", + }, + scenarioOutline: { + "シナリオアウトライン", + "シナリオテンプレート", + "テンプレ", + "シナリオテンプレ", + }, + examples: { + "例", + "サンプル", + }, + given: { + "* ", + "前提", + }, + when: { + "* ", + "もし", + }, + then: { + "* ", + "ならば", + }, + and: { + "* ", + "且つ", + "かつ", + }, + but: { + "* ", + "然し", + "しかし", + "但し", + "ただし", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "前提": messages.StepKeywordType_CONTEXT, + + "もし": messages.StepKeywordType_ACTION, + + "ならば": messages.StepKeywordType_OUTCOME, + + "且つ": messages.StepKeywordType_CONJUNCTION, + + "かつ": messages.StepKeywordType_CONJUNCTION, + + "然し": messages.StepKeywordType_CONJUNCTION, + + "しかし": messages.StepKeywordType_CONJUNCTION, + + "但し": messages.StepKeywordType_CONJUNCTION, + + "ただし": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "jv": &Dialect{ + Language: "jv", + Name: "Javanese", + Native: "Basa Jawa", + Keywords: map[string][]string{ + feature: { + "Fitur", + }, + rule: { + "Rule", + }, + background: { + "Dasar", + }, + scenario: { + "Skenario", + }, + scenarioOutline: { + "Konsep skenario", + }, + examples: { + "Conto", + "Contone", + }, + given: { + "* ", + "Nalika ", + "Nalikaning ", + }, + when: { + "* ", + "Manawa ", + "Menawa ", + }, + then: { + "* ", + "Njuk ", + "Banjur ", + }, + and: { + "* ", + "Lan ", + }, + but: { + "* ", + "Tapi ", + "Nanging ", + "Ananging ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Nalika ": messages.StepKeywordType_CONTEXT, + + "Nalikaning ": messages.StepKeywordType_CONTEXT, + + "Manawa ": messages.StepKeywordType_ACTION, + + "Menawa ": messages.StepKeywordType_ACTION, + + "Njuk ": messages.StepKeywordType_OUTCOME, + + "Banjur ": messages.StepKeywordType_OUTCOME, + + "Lan ": messages.StepKeywordType_CONJUNCTION, + + "Tapi ": messages.StepKeywordType_CONJUNCTION, + + "Nanging ": messages.StepKeywordType_CONJUNCTION, + + "Ananging ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ka": &Dialect{ + Language: "ka", + Name: "Georgian", + Native: "ქართული", + Keywords: map[string][]string{ + feature: { + "თვისება", + "მოთხოვნა", + }, + rule: { + "წესი", + }, + background: { + "კონტექსტი", + }, + scenario: { + "მაგალითად", + "მაგალითი", + "მაგ", + "სცენარი", + }, + scenarioOutline: { + "სცენარის ნიმუში", + "სცენარის შაბლონი", + "ნიმუში", + "შაბლონი", + }, + examples: { + "მაგალითები", + }, + given: { + "* ", + "მოცემული ", + "მოცემულია ", + "ვთქვათ ", + }, + when: { + "* ", + "როდესაც ", + "როცა ", + "როგორც კი ", + "თუ ", + }, + then: { + "* ", + "მაშინ ", + }, + and: { + "* ", + "და ", + "ასევე ", + }, + but: { + "* ", + "მაგრამ ", + "თუმცა ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "მოცემული ": messages.StepKeywordType_CONTEXT, + + "მოცემულია ": messages.StepKeywordType_CONTEXT, + + "ვთქვათ ": messages.StepKeywordType_CONTEXT, + + "როდესაც ": messages.StepKeywordType_ACTION, + + "როცა ": messages.StepKeywordType_ACTION, + + "როგორც კი ": messages.StepKeywordType_ACTION, + + "თუ ": messages.StepKeywordType_ACTION, + + "მაშინ ": messages.StepKeywordType_OUTCOME, + + "და ": messages.StepKeywordType_CONJUNCTION, + + "ასევე ": messages.StepKeywordType_CONJUNCTION, + + "მაგრამ ": messages.StepKeywordType_CONJUNCTION, + + "თუმცა ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "kn": &Dialect{ + Language: "kn", + Name: "Kannada", + Native: "ಕನ್ನಡ", + Keywords: map[string][]string{ + feature: { + "ಹೆಚ್ಚಳ", + }, + rule: { + "Rule", + }, + background: { + "ಹಿನ್ನೆಲೆ", + }, + scenario: { + "ಉದಾಹರಣೆ", + "ಕಥಾಸಾರಾಂಶ", + }, + scenarioOutline: { + "ವಿವರಣೆ", + }, + examples: { + "ಉದಾಹರಣೆಗಳು", + }, + given: { + "* ", + "ನೀಡಿದ ", + }, + when: { + "* ", + "ಸ್ಥಿತಿಯನ್ನು ", + }, + then: { + "* ", + "ನಂತರ ", + }, + and: { + "* ", + "ಮತ್ತು ", + }, + but: { + "* ", + "ಆದರೆ ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "ನೀಡಿದ ": messages.StepKeywordType_CONTEXT, + + "ಸ್ಥಿತಿಯನ್ನು ": messages.StepKeywordType_ACTION, + + "ನಂತರ ": messages.StepKeywordType_OUTCOME, + + "ಮತ್ತು ": messages.StepKeywordType_CONJUNCTION, + + "ಆದರೆ ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ko": &Dialect{ + Language: "ko", + Name: "Korean", + Native: "한국어", + Keywords: map[string][]string{ + feature: { + "기능", + }, + rule: { + "규칙", + }, + background: { + "배경", + }, + scenario: { + "시나리오", + }, + scenarioOutline: { + "시나리오 개요", + }, + examples: { + "예", + }, + given: { + "* ", + "조건 ", + "먼저 ", + }, + when: { + "* ", + "만일 ", + "만약 ", + }, + then: { + "* ", + "그러면 ", + }, + and: { + "* ", + "그리고 ", + }, + but: { + "* ", + "하지만 ", + "단 ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "조건 ": messages.StepKeywordType_CONTEXT, + + "먼저 ": messages.StepKeywordType_CONTEXT, + + "만일 ": messages.StepKeywordType_ACTION, + + "만약 ": messages.StepKeywordType_ACTION, + + "그러면 ": messages.StepKeywordType_OUTCOME, + + "그리고 ": messages.StepKeywordType_CONJUNCTION, + + "하지만 ": messages.StepKeywordType_CONJUNCTION, + + "단 ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "lt": &Dialect{ + Language: "lt", + Name: "Lithuanian", + Native: "lietuvių kalba", + Keywords: map[string][]string{ + feature: { + "Savybė", + }, + rule: { + "Rule", + }, + background: { + "Kontekstas", + }, + scenario: { + "Pavyzdys", + "Scenarijus", + }, + scenarioOutline: { + "Scenarijaus šablonas", + }, + examples: { + "Pavyzdžiai", + "Scenarijai", + "Variantai", + }, + given: { + "* ", + "Duota ", + }, + when: { + "* ", + "Kai ", + }, + then: { + "* ", + "Tada ", + }, + and: { + "* ", + "Ir ", + }, + but: { + "* ", + "Bet ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Duota ": messages.StepKeywordType_CONTEXT, + + "Kai ": messages.StepKeywordType_ACTION, + + "Tada ": messages.StepKeywordType_OUTCOME, + + "Ir ": messages.StepKeywordType_CONJUNCTION, + + "Bet ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "lu": &Dialect{ + Language: "lu", + Name: "Luxemburgish", + Native: "Lëtzebuergesch", + Keywords: map[string][]string{ + feature: { + "Funktionalitéit", + }, + rule: { + "Rule", + }, + background: { + "Hannergrond", + }, + scenario: { + "Beispill", + "Szenario", + }, + scenarioOutline: { + "Plang vum Szenario", + }, + examples: { + "Beispiller", + }, + given: { + "* ", + "ugeholl ", + }, + when: { + "* ", + "wann ", + }, + then: { + "* ", + "dann ", + }, + and: { + "* ", + "an ", + "a ", + }, + but: { + "* ", + "awer ", + "mä ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "ugeholl ": messages.StepKeywordType_CONTEXT, + + "wann ": messages.StepKeywordType_ACTION, + + "dann ": messages.StepKeywordType_OUTCOME, + + "an ": messages.StepKeywordType_CONJUNCTION, + + "a ": messages.StepKeywordType_CONJUNCTION, + + "awer ": messages.StepKeywordType_CONJUNCTION, + + "mä ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "lv": &Dialect{ + Language: "lv", + Name: "Latvian", + Native: "latviešu", + Keywords: map[string][]string{ + feature: { + "Funkcionalitāte", + "Fīča", + }, + rule: { + "Rule", + }, + background: { + "Konteksts", + "Situācija", + }, + scenario: { + "Piemērs", + "Scenārijs", + }, + scenarioOutline: { + "Scenārijs pēc parauga", + }, + examples: { + "Piemēri", + "Paraugs", + }, + given: { + "* ", + "Kad ", + }, + when: { + "* ", + "Ja ", + }, + then: { + "* ", + "Tad ", + }, + and: { + "* ", + "Un ", + }, + but: { + "* ", + "Bet ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Kad ": messages.StepKeywordType_CONTEXT, + + "Ja ": messages.StepKeywordType_ACTION, + + "Tad ": messages.StepKeywordType_OUTCOME, + + "Un ": messages.StepKeywordType_CONJUNCTION, + + "Bet ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "mk-Cyrl": &Dialect{ + Language: "mk-Cyrl", + Name: "Macedonian", + Native: "Македонски", + Keywords: map[string][]string{ + feature: { + "Функционалност", + "Бизнис потреба", + "Можност", + }, + rule: { + "Rule", + }, + background: { + "Контекст", + "Содржина", + }, + scenario: { + "Пример", + "Сценарио", + "На пример", + }, + scenarioOutline: { + "Преглед на сценарија", + "Скица", + "Концепт", + }, + examples: { + "Примери", + "Сценарија", + }, + given: { + "* ", + "Дадено ", + "Дадена ", + }, + when: { + "* ", + "Кога ", + }, + then: { + "* ", + "Тогаш ", + }, + and: { + "* ", + "И ", + }, + but: { + "* ", + "Но ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Дадено ": messages.StepKeywordType_CONTEXT, + + "Дадена ": messages.StepKeywordType_CONTEXT, + + "Кога ": messages.StepKeywordType_ACTION, + + "Тогаш ": messages.StepKeywordType_OUTCOME, + + "И ": messages.StepKeywordType_CONJUNCTION, + + "Но ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "mk-Latn": &Dialect{ + Language: "mk-Latn", + Name: "Macedonian (Latin)", + Native: "Makedonski (Latinica)", + Keywords: map[string][]string{ + feature: { + "Funkcionalnost", + "Biznis potreba", + "Mozhnost", + }, + rule: { + "Rule", + }, + background: { + "Kontekst", + "Sodrzhina", + }, + scenario: { + "Scenario", + "Na primer", + }, + scenarioOutline: { + "Pregled na scenarija", + "Skica", + "Koncept", + }, + examples: { + "Primeri", + "Scenaria", + }, + given: { + "* ", + "Dadeno ", + "Dadena ", + }, + when: { + "* ", + "Koga ", + }, + then: { + "* ", + "Togash ", + }, + and: { + "* ", + "I ", + }, + but: { + "* ", + "No ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dadeno ": messages.StepKeywordType_CONTEXT, + + "Dadena ": messages.StepKeywordType_CONTEXT, + + "Koga ": messages.StepKeywordType_ACTION, + + "Togash ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "No ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "mn": &Dialect{ + Language: "mn", + Name: "Mongolian", + Native: "монгол", + Keywords: map[string][]string{ + feature: { + "Функц", + "Функционал", + }, + rule: { + "Rule", + }, + background: { + "Агуулга", + }, + scenario: { + "Сценар", + }, + scenarioOutline: { + "Сценарын төлөвлөгөө", + }, + examples: { + "Тухайлбал", + }, + given: { + "* ", + "Өгөгдсөн нь ", + "Анх ", + }, + when: { + "* ", + "Хэрэв ", + }, + then: { + "* ", + "Тэгэхэд ", + "Үүний дараа ", + }, + and: { + "* ", + "Мөн ", + "Тэгээд ", + }, + but: { + "* ", + "Гэхдээ ", + "Харин ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Өгөгдсөн нь ": messages.StepKeywordType_CONTEXT, + + "Анх ": messages.StepKeywordType_CONTEXT, + + "Хэрэв ": messages.StepKeywordType_ACTION, + + "Тэгэхэд ": messages.StepKeywordType_OUTCOME, + + "Үүний дараа ": messages.StepKeywordType_OUTCOME, + + "Мөн ": messages.StepKeywordType_CONJUNCTION, + + "Тэгээд ": messages.StepKeywordType_CONJUNCTION, + + "Гэхдээ ": messages.StepKeywordType_CONJUNCTION, + + "Харин ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ne": &Dialect{ + Language: "ne", + Name: "Nepali", + Native: "नेपाली", + Keywords: map[string][]string{ + feature: { + "सुविधा", + "विशेषता", + }, + rule: { + "नियम", + }, + background: { + "पृष्ठभूमी", + }, + scenario: { + "परिदृश्य", + }, + scenarioOutline: { + "परिदृश्य रूपरेखा", + }, + examples: { + "उदाहरण", + "उदाहरणहरु", + }, + given: { + "* ", + "दिइएको ", + "दिएको ", + "यदि ", + }, + when: { + "* ", + "जब ", + }, + then: { + "* ", + "त्यसपछि ", + "अनी ", + }, + and: { + "* ", + "र ", + "अनि ", + }, + but: { + "* ", + "तर ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "दिइएको ": messages.StepKeywordType_CONTEXT, + + "दिएको ": messages.StepKeywordType_CONTEXT, + + "यदि ": messages.StepKeywordType_CONTEXT, + + "जब ": messages.StepKeywordType_ACTION, + + "त्यसपछि ": messages.StepKeywordType_OUTCOME, + + "अनी ": messages.StepKeywordType_OUTCOME, + + "र ": messages.StepKeywordType_CONJUNCTION, + + "अनि ": messages.StepKeywordType_CONJUNCTION, + + "तर ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "nl": &Dialect{ + Language: "nl", + Name: "Dutch", + Native: "Nederlands", + Keywords: map[string][]string{ + feature: { + "Functionaliteit", + }, + rule: { + "Regel", + }, + background: { + "Achtergrond", + }, + scenario: { + "Voorbeeld", + "Scenario", + }, + scenarioOutline: { + "Abstract Scenario", + }, + examples: { + "Voorbeelden", + }, + given: { + "* ", + "Gegeven ", + "Stel ", + }, + when: { + "* ", + "Als ", + "Wanneer ", + }, + then: { + "* ", + "Dan ", + }, + and: { + "* ", + "En ", + }, + but: { + "* ", + "Maar ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Gegeven ": messages.StepKeywordType_CONTEXT, + + "Stel ": messages.StepKeywordType_CONTEXT, + + "Als ": messages.StepKeywordType_ACTION, + + "Wanneer ": messages.StepKeywordType_ACTION, + + "Dan ": messages.StepKeywordType_OUTCOME, + + "En ": messages.StepKeywordType_CONJUNCTION, + + "Maar ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "no": &Dialect{ + Language: "no", + Name: "Norwegian", + Native: "norsk", + Keywords: map[string][]string{ + feature: { + "Egenskap", + }, + rule: { + "Regel", + }, + background: { + "Bakgrunn", + }, + scenario: { + "Eksempel", + "Scenario", + }, + scenarioOutline: { + "Scenariomal", + "Abstrakt Scenario", + }, + examples: { + "Eksempler", + }, + given: { + "* ", + "Gitt ", + }, + when: { + "* ", + "Når ", + }, + then: { + "* ", + "Så ", + }, + and: { + "* ", + "Og ", + }, + but: { + "* ", + "Men ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Gitt ": messages.StepKeywordType_CONTEXT, + + "Når ": messages.StepKeywordType_ACTION, + + "Så ": messages.StepKeywordType_OUTCOME, + + "Og ": messages.StepKeywordType_CONJUNCTION, + + "Men ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "pa": &Dialect{ + Language: "pa", + Name: "Panjabi", + Native: "ਪੰਜਾਬੀ", + Keywords: map[string][]string{ + feature: { + "ਖਾਸੀਅਤ", + "ਮੁਹਾਂਦਰਾ", + "ਨਕਸ਼ ਨੁਹਾਰ", + }, + rule: { + "Rule", + }, + background: { + "ਪਿਛੋਕੜ", + }, + scenario: { + "ਉਦਾਹਰਨ", + "ਪਟਕਥਾ", + }, + scenarioOutline: { + "ਪਟਕਥਾ ਢਾਂਚਾ", + "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ", + }, + examples: { + "ਉਦਾਹਰਨਾਂ", + }, + given: { + "* ", + "ਜੇਕਰ ", + "ਜਿਵੇਂ ਕਿ ", + }, + when: { + "* ", + "ਜਦੋਂ ", + }, + then: { + "* ", + "ਤਦ ", + }, + and: { + "* ", + "ਅਤੇ ", + }, + but: { + "* ", + "ਪਰ ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "ਜੇਕਰ ": messages.StepKeywordType_CONTEXT, + + "ਜਿਵੇਂ ਕਿ ": messages.StepKeywordType_CONTEXT, + + "ਜਦੋਂ ": messages.StepKeywordType_ACTION, + + "ਤਦ ": messages.StepKeywordType_OUTCOME, + + "ਅਤੇ ": messages.StepKeywordType_CONJUNCTION, + + "ਪਰ ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "pl": &Dialect{ + Language: "pl", + Name: "Polish", + Native: "polski", + Keywords: map[string][]string{ + feature: { + "Właściwość", + "Funkcja", + "Aspekt", + "Potrzeba biznesowa", + }, + rule: { + "Zasada", + "Reguła", + }, + background: { + "Założenia", + }, + scenario: { + "Przykład", + "Scenariusz", + }, + scenarioOutline: { + "Szablon scenariusza", + }, + examples: { + "Przykłady", + }, + given: { + "* ", + "Zakładając ", + "Mając ", + "Zakładając, że ", + }, + when: { + "* ", + "Jeżeli ", + "Jeśli ", + "Gdy ", + "Kiedy ", + }, + then: { + "* ", + "Wtedy ", + }, + and: { + "* ", + "Oraz ", + "I ", + }, + but: { + "* ", + "Ale ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Zakładając ": messages.StepKeywordType_CONTEXT, + + "Mając ": messages.StepKeywordType_CONTEXT, + + "Zakładając, że ": messages.StepKeywordType_CONTEXT, + + "Jeżeli ": messages.StepKeywordType_ACTION, + + "Jeśli ": messages.StepKeywordType_ACTION, + + "Gdy ": messages.StepKeywordType_ACTION, + + "Kiedy ": messages.StepKeywordType_ACTION, + + "Wtedy ": messages.StepKeywordType_OUTCOME, + + "Oraz ": messages.StepKeywordType_CONJUNCTION, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "Ale ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "pt": &Dialect{ + Language: "pt", + Name: "Portuguese", + Native: "português", + Keywords: map[string][]string{ + feature: { + "Funcionalidade", + "Característica", + "Caracteristica", + }, + rule: { + "Regra", + }, + background: { + "Contexto", + "Cenário de Fundo", + "Cenario de Fundo", + "Fundo", + }, + scenario: { + "Exemplo", + "Cenário", + "Cenario", + }, + scenarioOutline: { + "Esquema do Cenário", + "Esquema do Cenario", + "Delineação do Cenário", + "Delineacao do Cenario", + }, + examples: { + "Exemplos", + "Cenários", + "Cenarios", + }, + given: { + "* ", + "Dado ", + "Dada ", + "Dados ", + "Dadas ", + }, + when: { + "* ", + "Quando ", + }, + then: { + "* ", + "Então ", + "Entao ", + }, + and: { + "* ", + "E ", + }, + but: { + "* ", + "Mas ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dado ": messages.StepKeywordType_CONTEXT, + + "Dada ": messages.StepKeywordType_CONTEXT, + + "Dados ": messages.StepKeywordType_CONTEXT, + + "Dadas ": messages.StepKeywordType_CONTEXT, + + "Quando ": messages.StepKeywordType_ACTION, + + "Então ": messages.StepKeywordType_OUTCOME, + + "Entao ": messages.StepKeywordType_OUTCOME, + + "E ": messages.StepKeywordType_CONJUNCTION, + + "Mas ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ro": &Dialect{ + Language: "ro", + Name: "Romanian", + Native: "română", + Keywords: map[string][]string{ + feature: { + "Functionalitate", + "Funcționalitate", + "Funcţionalitate", + }, + rule: { + "Rule", + }, + background: { + "Context", + }, + scenario: { + "Exemplu", + "Scenariu", + }, + scenarioOutline: { + "Structura scenariu", + "Structură scenariu", + }, + examples: { + "Exemple", + }, + given: { + "* ", + "Date fiind ", + "Dat fiind ", + "Dată fiind", + "Dati fiind ", + "Dați fiind ", + "Daţi fiind ", + }, + when: { + "* ", + "Cand ", + "Când ", + }, + then: { + "* ", + "Atunci ", + }, + and: { + "* ", + "Si ", + "Și ", + "Şi ", + }, + but: { + "* ", + "Dar ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Date fiind ": messages.StepKeywordType_CONTEXT, + + "Dat fiind ": messages.StepKeywordType_CONTEXT, + + "Dată fiind": messages.StepKeywordType_CONTEXT, + + "Dati fiind ": messages.StepKeywordType_CONTEXT, + + "Dați fiind ": messages.StepKeywordType_CONTEXT, + + "Daţi fiind ": messages.StepKeywordType_CONTEXT, + + "Cand ": messages.StepKeywordType_ACTION, + + "Când ": messages.StepKeywordType_ACTION, + + "Atunci ": messages.StepKeywordType_OUTCOME, + + "Si ": messages.StepKeywordType_CONJUNCTION, + + "Și ": messages.StepKeywordType_CONJUNCTION, + + "Şi ": messages.StepKeywordType_CONJUNCTION, + + "Dar ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ru": &Dialect{ + Language: "ru", + Name: "Russian", + Native: "русский", + Keywords: map[string][]string{ + feature: { + "Функция", + "Функциональность", + "Функционал", + "Свойство", + "Фича", + }, + rule: { + "Правило", + }, + background: { + "Предыстория", + "Контекст", + }, + scenario: { + "Пример", + "Сценарий", + }, + scenarioOutline: { + "Структура сценария", + "Шаблон сценария", + }, + examples: { + "Примеры", + "Значения", + }, + given: { + "* ", + "Допустим ", + "Дано ", + "Пусть ", + }, + when: { + "* ", + "Когда ", + "Если ", + }, + then: { + "* ", + "То ", + "Затем ", + "Тогда ", + }, + and: { + "* ", + "И ", + "К тому же ", + "Также ", + }, + but: { + "* ", + "Но ", + "А ", + "Иначе ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Допустим ": messages.StepKeywordType_CONTEXT, + + "Дано ": messages.StepKeywordType_CONTEXT, + + "Пусть ": messages.StepKeywordType_CONTEXT, + + "Когда ": messages.StepKeywordType_ACTION, + + "Если ": messages.StepKeywordType_ACTION, + + "То ": messages.StepKeywordType_OUTCOME, + + "Затем ": messages.StepKeywordType_OUTCOME, + + "Тогда ": messages.StepKeywordType_OUTCOME, + + "И ": messages.StepKeywordType_CONJUNCTION, + + "К тому же ": messages.StepKeywordType_CONJUNCTION, + + "Также ": messages.StepKeywordType_CONJUNCTION, + + "Но ": messages.StepKeywordType_CONJUNCTION, + + "А ": messages.StepKeywordType_CONJUNCTION, + + "Иначе ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "sk": &Dialect{ + Language: "sk", + Name: "Slovak", + Native: "Slovensky", + Keywords: map[string][]string{ + feature: { + "Požiadavka", + "Funkcia", + "Vlastnosť", + }, + rule: { + "Rule", + }, + background: { + "Pozadie", + }, + scenario: { + "Príklad", + "Scenár", + }, + scenarioOutline: { + "Náčrt Scenáru", + "Náčrt Scenára", + "Osnova Scenára", + }, + examples: { + "Príklady", + }, + given: { + "* ", + "Pokiaľ ", + "Za predpokladu ", + }, + when: { + "* ", + "Keď ", + "Ak ", + }, + then: { + "* ", + "Tak ", + "Potom ", + }, + and: { + "* ", + "A ", + "A tiež ", + "A taktiež ", + "A zároveň ", + }, + but: { + "* ", + "Ale ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Pokiaľ ": messages.StepKeywordType_CONTEXT, + + "Za predpokladu ": messages.StepKeywordType_CONTEXT, + + "Keď ": messages.StepKeywordType_ACTION, + + "Ak ": messages.StepKeywordType_ACTION, + + "Tak ": messages.StepKeywordType_OUTCOME, + + "Potom ": messages.StepKeywordType_OUTCOME, + + "A ": messages.StepKeywordType_CONJUNCTION, + + "A tiež ": messages.StepKeywordType_CONJUNCTION, + + "A taktiež ": messages.StepKeywordType_CONJUNCTION, + + "A zároveň ": messages.StepKeywordType_CONJUNCTION, + + "Ale ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "sl": &Dialect{ + Language: "sl", + Name: "Slovenian", + Native: "Slovenski", + Keywords: map[string][]string{ + feature: { + "Funkcionalnost", + "Funkcija", + "Možnosti", + "Moznosti", + "Lastnost", + "Značilnost", + }, + rule: { + "Rule", + }, + background: { + "Kontekst", + "Osnova", + "Ozadje", + }, + scenario: { + "Primer", + "Scenarij", + }, + scenarioOutline: { + "Struktura scenarija", + "Skica", + "Koncept", + "Oris scenarija", + "Osnutek", + }, + examples: { + "Primeri", + "Scenariji", + }, + given: { + "Dano ", + "Podano ", + "Zaradi ", + "Privzeto ", + }, + when: { + "Ko ", + "Ce ", + "Če ", + "Kadar ", + }, + then: { + "Nato ", + "Potem ", + "Takrat ", + }, + and: { + "In ", + "Ter ", + }, + but: { + "Toda ", + "Ampak ", + "Vendar ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Dano ": messages.StepKeywordType_CONTEXT, + + "Podano ": messages.StepKeywordType_CONTEXT, + + "Zaradi ": messages.StepKeywordType_CONTEXT, + + "Privzeto ": messages.StepKeywordType_CONTEXT, + + "Ko ": messages.StepKeywordType_ACTION, + + "Ce ": messages.StepKeywordType_ACTION, + + "Če ": messages.StepKeywordType_ACTION, + + "Kadar ": messages.StepKeywordType_ACTION, + + "Nato ": messages.StepKeywordType_OUTCOME, + + "Potem ": messages.StepKeywordType_OUTCOME, + + "Takrat ": messages.StepKeywordType_OUTCOME, + + "In ": messages.StepKeywordType_CONJUNCTION, + + "Ter ": messages.StepKeywordType_CONJUNCTION, + + "Toda ": messages.StepKeywordType_CONJUNCTION, + + "Ampak ": messages.StepKeywordType_CONJUNCTION, + + "Vendar ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "sr-Cyrl": &Dialect{ + Language: "sr-Cyrl", + Name: "Serbian", + Native: "Српски", + Keywords: map[string][]string{ + feature: { + "Функционалност", + "Могућност", + "Особина", + }, + rule: { + "Правило", + }, + background: { + "Контекст", + "Основа", + "Позадина", + }, + scenario: { + "Сценарио", + "Пример", + }, + scenarioOutline: { + "Структура сценарија", + "Скица", + "Концепт", + }, + examples: { + "Примери", + "Сценарији", + }, + given: { + "* ", + "За дато ", + "За дате ", + "За дати ", + }, + when: { + "* ", + "Када ", + "Кад ", + }, + then: { + "* ", + "Онда ", + }, + and: { + "* ", + "И ", + }, + but: { + "* ", + "Али ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "За дато ": messages.StepKeywordType_CONTEXT, + + "За дате ": messages.StepKeywordType_CONTEXT, + + "За дати ": messages.StepKeywordType_CONTEXT, + + "Када ": messages.StepKeywordType_ACTION, + + "Кад ": messages.StepKeywordType_ACTION, + + "Онда ": messages.StepKeywordType_OUTCOME, + + "И ": messages.StepKeywordType_CONJUNCTION, + + "Али ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "sr-Latn": &Dialect{ + Language: "sr-Latn", + Name: "Serbian (Latin)", + Native: "Srpski (Latinica)", + Keywords: map[string][]string{ + feature: { + "Funkcionalnost", + "Mogućnost", + "Mogucnost", + "Osobina", + }, + rule: { + "Pravilo", + }, + background: { + "Kontekst", + "Osnova", + "Pozadina", + }, + scenario: { + "Scenario", + "Primer", + }, + scenarioOutline: { + "Struktura scenarija", + "Skica", + "Koncept", + }, + examples: { + "Primeri", + "Scenariji", + }, + given: { + "* ", + "Za dato ", + "Za date ", + "Za dati ", + }, + when: { + "* ", + "Kada ", + "Kad ", + }, + then: { + "* ", + "Onda ", + }, + and: { + "* ", + "I ", + }, + but: { + "* ", + "Ali ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Za dato ": messages.StepKeywordType_CONTEXT, + + "Za date ": messages.StepKeywordType_CONTEXT, + + "Za dati ": messages.StepKeywordType_CONTEXT, + + "Kada ": messages.StepKeywordType_ACTION, + + "Kad ": messages.StepKeywordType_ACTION, + + "Onda ": messages.StepKeywordType_OUTCOME, + + "I ": messages.StepKeywordType_CONJUNCTION, + + "Ali ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "sv": &Dialect{ + Language: "sv", + Name: "Swedish", + Native: "Svenska", + Keywords: map[string][]string{ + feature: { + "Egenskap", + }, + rule: { + "Regel", + }, + background: { + "Bakgrund", + }, + scenario: { + "Scenario", + }, + scenarioOutline: { + "Abstrakt Scenario", + "Scenariomall", + }, + examples: { + "Exempel", + }, + given: { + "* ", + "Givet ", + }, + when: { + "* ", + "När ", + }, + then: { + "* ", + "Så ", + }, + and: { + "* ", + "Och ", + }, + but: { + "* ", + "Men ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Givet ": messages.StepKeywordType_CONTEXT, + + "När ": messages.StepKeywordType_ACTION, + + "Så ": messages.StepKeywordType_OUTCOME, + + "Och ": messages.StepKeywordType_CONJUNCTION, + + "Men ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ta": &Dialect{ + Language: "ta", + Name: "Tamil", + Native: "தமிழ்", + Keywords: map[string][]string{ + feature: { + "அம்சம்", + "வணிக தேவை", + "திறன்", + }, + rule: { + "Rule", + }, + background: { + "பின்னணி", + }, + scenario: { + "உதாரணமாக", + "காட்சி", + }, + scenarioOutline: { + "காட்சி சுருக்கம்", + "காட்சி வார்ப்புரு", + }, + examples: { + "எடுத்துக்காட்டுகள்", + "காட்சிகள்", + "நிலைமைகளில்", + }, + given: { + "* ", + "கொடுக்கப்பட்ட ", + }, + when: { + "* ", + "எப்போது ", + }, + then: { + "* ", + "அப்பொழுது ", + }, + and: { + "* ", + "மேலும் ", + "மற்றும் ", + }, + but: { + "* ", + "ஆனால் ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "கொடுக்கப்பட்ட ": messages.StepKeywordType_CONTEXT, + + "எப்போது ": messages.StepKeywordType_ACTION, + + "அப்பொழுது ": messages.StepKeywordType_OUTCOME, + + "மேலும் ": messages.StepKeywordType_CONJUNCTION, + + "மற்றும் ": messages.StepKeywordType_CONJUNCTION, + + "ஆனால் ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "th": &Dialect{ + Language: "th", + Name: "Thai", + Native: "ไทย", + Keywords: map[string][]string{ + feature: { + "โครงหลัก", + "ความต้องการทางธุรกิจ", + "ความสามารถ", + }, + rule: { + "Rule", + }, + background: { + "แนวคิด", + }, + scenario: { + "เหตุการณ์", + }, + scenarioOutline: { + "สรุปเหตุการณ์", + "โครงสร้างของเหตุการณ์", + }, + examples: { + "ชุดของตัวอย่าง", + "ชุดของเหตุการณ์", + }, + given: { + "* ", + "กำหนดให้ ", + }, + when: { + "* ", + "เมื่อ ", + }, + then: { + "* ", + "ดังนั้น ", + }, + and: { + "* ", + "และ ", + }, + but: { + "* ", + "แต่ ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "กำหนดให้ ": messages.StepKeywordType_CONTEXT, + + "เมื่อ ": messages.StepKeywordType_ACTION, + + "ดังนั้น ": messages.StepKeywordType_OUTCOME, + + "และ ": messages.StepKeywordType_CONJUNCTION, + + "แต่ ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "te": &Dialect{ + Language: "te", + Name: "Telugu", + Native: "తెలుగు", + Keywords: map[string][]string{ + feature: { + "గుణము", + }, + rule: { + "Rule", + }, + background: { + "నేపథ్యం", + }, + scenario: { + "ఉదాహరణ", + "సన్నివేశం", + }, + scenarioOutline: { + "కథనం", + }, + examples: { + "ఉదాహరణలు", + }, + given: { + "* ", + "చెప్పబడినది ", + }, + when: { + "* ", + "ఈ పరిస్థితిలో ", + }, + then: { + "* ", + "అప్పుడు ", + }, + and: { + "* ", + "మరియు ", + }, + but: { + "* ", + "కాని ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "చెప్పబడినది ": messages.StepKeywordType_CONTEXT, + + "ఈ పరిస్థితిలో ": messages.StepKeywordType_ACTION, + + "అప్పుడు ": messages.StepKeywordType_OUTCOME, + + "మరియు ": messages.StepKeywordType_CONJUNCTION, + + "కాని ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "tlh": &Dialect{ + Language: "tlh", + Name: "Klingon", + Native: "tlhIngan", + Keywords: map[string][]string{ + feature: { + "Qap", + "Qu'meH 'ut", + "perbogh", + "poQbogh malja'", + "laH", + }, + rule: { + "Rule", + }, + background: { + "mo'", + }, + scenario: { + "lut", + }, + scenarioOutline: { + "lut chovnatlh", + }, + examples: { + "ghantoH", + "lutmey", + }, + given: { + "* ", + "ghu' noblu' ", + "DaH ghu' bejlu' ", + }, + when: { + "* ", + "qaSDI' ", + }, + then: { + "* ", + "vaj ", + }, + and: { + "* ", + "'ej ", + "latlh ", + }, + but: { + "* ", + "'ach ", + "'a ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "ghu' noblu' ": messages.StepKeywordType_CONTEXT, + + "DaH ghu' bejlu' ": messages.StepKeywordType_CONTEXT, + + "qaSDI' ": messages.StepKeywordType_ACTION, + + "vaj ": messages.StepKeywordType_OUTCOME, + + "'ej ": messages.StepKeywordType_CONJUNCTION, + + "latlh ": messages.StepKeywordType_CONJUNCTION, + + "'ach ": messages.StepKeywordType_CONJUNCTION, + + "'a ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "tr": &Dialect{ + Language: "tr", + Name: "Turkish", + Native: "Türkçe", + Keywords: map[string][]string{ + feature: { + "Özellik", + "İş Gereksinimi", + "Gereksinim", + "İşlev", + "Kullanıcı Hikayesi", + "Yetenek", + "Teknik Gereksinim", + }, + rule: { + "Kural", + "İş Kuralı", + "Kaide", + "Hüküm", + "Madde", + }, + background: { + "Geçmiş", + "Arka Plan", + "Ön Koşul", + "Önkoşul", + "Önceki Durum", + "Giriş", + "Mukaddime", + "Mevcut Durum", + }, + scenario: { + "Örnek", + "Senaryo", + "Durum", + "Vaka", + }, + scenarioOutline: { + "Senaryo taslağı", + "Senaryo şablonu", + }, + examples: { + "Örnekler", + "Değerler", + }, + given: { + "* ", + "Mevcut ", + "Önceden ", + "Geçmişte ", + "Daha önce ", + "Halihazırda ", + "Zaten ", + "Sistemde ", + "Diyelim ki ", + "Varsayalım ki ", + "Farz edelim ki ", + "Kabul edelim ki ", + "Başlangıçta ", + "Varsayılan olarak ", + "Biliniyor ki ", + }, + when: { + "* ", + "Eğer ", + "Eğer ki ", + "Ne zaman ", + "Ne zaman ki ", + "Şayet ", + }, + then: { + "* ", + "Beklenen ", + "O zaman ", + "Sonuç olarak ", + "Böylece ", + "Bunun üzerine ", + "Bu durumda ", + "O takdirde ", + "Şu halde ", + "Netice itibariyle ", + "Buna binaen ", + }, + and: { + "* ", + "Ve ", + "Hem de ", + "Bir de ", + "Ayrıca ", + "İlaveten ", + "Buna ek olarak ", + }, + but: { + "* ", + "Fakat ", + "Ama ", + "Ancak ", + "Yalnız ", + "Lakin ", + "Meğer ki ", + "Buna mukabil ", + "Aksi halde ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Mevcut ": messages.StepKeywordType_CONTEXT, + + "Önceden ": messages.StepKeywordType_CONTEXT, + + "Geçmişte ": messages.StepKeywordType_CONTEXT, + + "Daha önce ": messages.StepKeywordType_CONTEXT, + + "Halihazırda ": messages.StepKeywordType_CONTEXT, + + "Zaten ": messages.StepKeywordType_CONTEXT, + + "Sistemde ": messages.StepKeywordType_CONTEXT, + + "Diyelim ki ": messages.StepKeywordType_CONTEXT, + + "Varsayalım ki ": messages.StepKeywordType_CONTEXT, + + "Farz edelim ki ": messages.StepKeywordType_CONTEXT, + + "Kabul edelim ki ": messages.StepKeywordType_CONTEXT, + + "Başlangıçta ": messages.StepKeywordType_CONTEXT, + + "Varsayılan olarak ": messages.StepKeywordType_CONTEXT, + + "Biliniyor ki ": messages.StepKeywordType_CONTEXT, + + "Eğer ": messages.StepKeywordType_ACTION, + + "Eğer ki ": messages.StepKeywordType_ACTION, + + "Ne zaman ": messages.StepKeywordType_ACTION, + + "Ne zaman ki ": messages.StepKeywordType_ACTION, + + "Şayet ": messages.StepKeywordType_ACTION, + + "Beklenen ": messages.StepKeywordType_OUTCOME, + + "O zaman ": messages.StepKeywordType_OUTCOME, + + "Sonuç olarak ": messages.StepKeywordType_OUTCOME, + + "Böylece ": messages.StepKeywordType_OUTCOME, + + "Bunun üzerine ": messages.StepKeywordType_OUTCOME, + + "Bu durumda ": messages.StepKeywordType_OUTCOME, + + "O takdirde ": messages.StepKeywordType_OUTCOME, + + "Şu halde ": messages.StepKeywordType_OUTCOME, + + "Netice itibariyle ": messages.StepKeywordType_OUTCOME, + + "Buna binaen ": messages.StepKeywordType_OUTCOME, + + "Ve ": messages.StepKeywordType_CONJUNCTION, + + "Hem de ": messages.StepKeywordType_CONJUNCTION, + + "Bir de ": messages.StepKeywordType_CONJUNCTION, + + "Ayrıca ": messages.StepKeywordType_CONJUNCTION, + + "İlaveten ": messages.StepKeywordType_CONJUNCTION, + + "Buna ek olarak ": messages.StepKeywordType_CONJUNCTION, + + "Fakat ": messages.StepKeywordType_CONJUNCTION, + + "Ama ": messages.StepKeywordType_CONJUNCTION, + + "Ancak ": messages.StepKeywordType_CONJUNCTION, + + "Yalnız ": messages.StepKeywordType_CONJUNCTION, + + "Lakin ": messages.StepKeywordType_CONJUNCTION, + + "Meğer ki ": messages.StepKeywordType_CONJUNCTION, + + "Buna mukabil ": messages.StepKeywordType_CONJUNCTION, + + "Aksi halde ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "tt": &Dialect{ + Language: "tt", + Name: "Tatar", + Native: "Татарча", + Keywords: map[string][]string{ + feature: { + "Мөмкинлек", + "Үзенчәлеклелек", + }, + rule: { + "Rule", + }, + background: { + "Кереш", + }, + scenario: { + "Сценарий", + }, + scenarioOutline: { + "Сценарийның төзелеше", + }, + examples: { + "Үрнәкләр", + "Мисаллар", + }, + given: { + "* ", + "Әйтик ", + }, + when: { + "* ", + "Әгәр ", + }, + then: { + "* ", + "Нәтиҗәдә ", + }, + and: { + "* ", + "Һәм ", + "Вә ", + }, + but: { + "* ", + "Ләкин ", + "Әмма ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Әйтик ": messages.StepKeywordType_CONTEXT, + + "Әгәр ": messages.StepKeywordType_ACTION, + + "Нәтиҗәдә ": messages.StepKeywordType_OUTCOME, + + "Һәм ": messages.StepKeywordType_CONJUNCTION, + + "Вә ": messages.StepKeywordType_CONJUNCTION, + + "Ләкин ": messages.StepKeywordType_CONJUNCTION, + + "Әмма ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "uk": &Dialect{ + Language: "uk", + Name: "Ukrainian", + Native: "Українська", + Keywords: map[string][]string{ + feature: { + "Функціонал", + }, + rule: { + "Rule", + }, + background: { + "Передумова", + }, + scenario: { + "Приклад", + "Сценарій", + }, + scenarioOutline: { + "Структура сценарію", + }, + examples: { + "Приклади", + }, + given: { + "* ", + "Припустимо ", + "Припустимо, що ", + "Нехай ", + "Дано ", + }, + when: { + "* ", + "Якщо ", + "Коли ", + }, + then: { + "* ", + "То ", + "Тоді ", + }, + and: { + "* ", + "І ", + "А також ", + "Та ", + }, + but: { + "* ", + "Але ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Припустимо ": messages.StepKeywordType_CONTEXT, + + "Припустимо, що ": messages.StepKeywordType_CONTEXT, + + "Нехай ": messages.StepKeywordType_CONTEXT, + + "Дано ": messages.StepKeywordType_CONTEXT, + + "Якщо ": messages.StepKeywordType_ACTION, + + "Коли ": messages.StepKeywordType_ACTION, + + "То ": messages.StepKeywordType_OUTCOME, + + "Тоді ": messages.StepKeywordType_OUTCOME, + + "І ": messages.StepKeywordType_CONJUNCTION, + + "А також ": messages.StepKeywordType_CONJUNCTION, + + "Та ": messages.StepKeywordType_CONJUNCTION, + + "Але ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ur": &Dialect{ + Language: "ur", + Name: "Urdu", + Native: "اردو", + Keywords: map[string][]string{ + feature: { + "صلاحیت", + "کاروبار کی ضرورت", + "خصوصیت", + }, + rule: { + "Rule", + }, + background: { + "پس منظر", + }, + scenario: { + "منظرنامہ", + }, + scenarioOutline: { + "منظر نامے کا خاکہ", + }, + examples: { + "مثالیں", + }, + given: { + "* ", + "اگر ", + "بالفرض ", + "فرض کیا ", + }, + when: { + "* ", + "جب ", + }, + then: { + "* ", + "پھر ", + "تب ", + }, + and: { + "* ", + "اور ", + }, + but: { + "* ", + "لیکن ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "اگر ": messages.StepKeywordType_CONTEXT, + + "بالفرض ": messages.StepKeywordType_CONTEXT, + + "فرض کیا ": messages.StepKeywordType_CONTEXT, + + "جب ": messages.StepKeywordType_ACTION, + + "پھر ": messages.StepKeywordType_OUTCOME, + + "تب ": messages.StepKeywordType_OUTCOME, + + "اور ": messages.StepKeywordType_CONJUNCTION, + + "لیکن ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "uz": &Dialect{ + Language: "uz", + Name: "Uzbek", + Native: "Узбекча", + Keywords: map[string][]string{ + feature: { + "Функционал", + }, + rule: { + "Rule", + }, + background: { + "Тарих", + }, + scenario: { + "Сценарий", + }, + scenarioOutline: { + "Сценарий структураси", + }, + examples: { + "Мисоллар", + }, + given: { + "* ", + "Belgilangan ", + }, + when: { + "* ", + "Агар ", + }, + then: { + "* ", + "Унда ", + }, + and: { + "* ", + "Ва ", + }, + but: { + "* ", + "Лекин ", + "Бирок ", + "Аммо ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Belgilangan ": messages.StepKeywordType_CONTEXT, + + "Агар ": messages.StepKeywordType_ACTION, + + "Унда ": messages.StepKeywordType_OUTCOME, + + "Ва ": messages.StepKeywordType_CONJUNCTION, + + "Лекин ": messages.StepKeywordType_CONJUNCTION, + + "Бирок ": messages.StepKeywordType_CONJUNCTION, + + "Аммо ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "vi": &Dialect{ + Language: "vi", + Name: "Vietnamese", + Native: "Tiếng Việt", + Keywords: map[string][]string{ + feature: { + "Tính năng", + }, + rule: { + "Quy tắc", + }, + background: { + "Bối cảnh", + }, + scenario: { + "Tình huống", + "Kịch bản", + }, + scenarioOutline: { + "Khung tình huống", + "Khung kịch bản", + }, + examples: { + "Dữ liệu", + }, + given: { + "* ", + "Biết ", + "Cho ", + }, + when: { + "* ", + "Khi ", + }, + then: { + "* ", + "Thì ", + }, + and: { + "* ", + "Và ", + }, + but: { + "* ", + "Nhưng ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "Biết ": messages.StepKeywordType_CONTEXT, + + "Cho ": messages.StepKeywordType_CONTEXT, + + "Khi ": messages.StepKeywordType_ACTION, + + "Thì ": messages.StepKeywordType_OUTCOME, + + "Và ": messages.StepKeywordType_CONJUNCTION, + + "Nhưng ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "zh-CN": &Dialect{ + Language: "zh-CN", + Name: "Chinese simplified", + Native: "简体中文", + Keywords: map[string][]string{ + feature: { + "功能", + }, + rule: { + "Rule", + "规则", + }, + background: { + "背景", + }, + scenario: { + "场景", + "剧本", + }, + scenarioOutline: { + "场景大纲", + "剧本大纲", + }, + examples: { + "例子", + }, + given: { + "* ", + "假如", + "假设", + "假定", + }, + when: { + "* ", + "当", + }, + then: { + "* ", + "那么", + }, + and: { + "* ", + "而且", + "并且", + "同时", + }, + but: { + "* ", + "但是", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "假如": messages.StepKeywordType_CONTEXT, + + "假设": messages.StepKeywordType_CONTEXT, + + "假定": messages.StepKeywordType_CONTEXT, + + "当": messages.StepKeywordType_ACTION, + + "那么": messages.StepKeywordType_OUTCOME, + + "而且": messages.StepKeywordType_CONJUNCTION, + + "并且": messages.StepKeywordType_CONJUNCTION, + + "同时": messages.StepKeywordType_CONJUNCTION, + + "但是": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "ml": &Dialect{ + Language: "ml", + Name: "Malayalam", + Native: "മലയാളം", + Keywords: map[string][]string{ + feature: { + "സവിശേഷത", + }, + rule: { + "നിയമം", + }, + background: { + "പശ്ചാത്തലം", + }, + scenario: { + "രംഗം", + }, + scenarioOutline: { + "സാഹചര്യത്തിന്റെ രൂപരേഖ", + }, + examples: { + "ഉദാഹരണങ്ങൾ", + }, + given: { + "* ", + "നൽകിയത്", + }, + when: { + "എപ്പോൾ", + }, + then: { + "* ", + "പിന്നെ", + }, + and: { + "* ", + "ഒപ്പം", + }, + but: { + "* ", + "പക്ഷേ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "നൽകിയത്": messages.StepKeywordType_CONTEXT, + + "എപ്പോൾ": messages.StepKeywordType_ACTION, + + "പിന്നെ": messages.StepKeywordType_OUTCOME, + + "ഒപ്പം": messages.StepKeywordType_CONJUNCTION, + + "പക്ഷേ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "zh-TW": &Dialect{ + Language: "zh-TW", + Name: "Chinese traditional", + Native: "繁體中文", + Keywords: map[string][]string{ + feature: { + "功能", + }, + rule: { + "Rule", + }, + background: { + "背景", + }, + scenario: { + "場景", + "劇本", + }, + scenarioOutline: { + "場景大綱", + "劇本大綱", + }, + examples: { + "例子", + }, + given: { + "* ", + "假如", + "假設", + "假定", + }, + when: { + "* ", + "當", + }, + then: { + "* ", + "那麼", + }, + and: { + "* ", + "而且", + "並且", + "同時", + }, + but: { + "* ", + "但是", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "假如": messages.StepKeywordType_CONTEXT, + + "假設": messages.StepKeywordType_CONTEXT, + + "假定": messages.StepKeywordType_CONTEXT, + + "當": messages.StepKeywordType_ACTION, + + "那麼": messages.StepKeywordType_OUTCOME, + + "而且": messages.StepKeywordType_CONJUNCTION, + + "並且": messages.StepKeywordType_CONJUNCTION, + + "同時": messages.StepKeywordType_CONJUNCTION, + + "但是": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "mr": &Dialect{ + Language: "mr", + Name: "Marathi", + Native: "मराठी", + Keywords: map[string][]string{ + feature: { + "वैशिष्ट्य", + "सुविधा", + }, + rule: { + "नियम", + }, + background: { + "पार्श्वभूमी", + }, + scenario: { + "परिदृश्य", + }, + scenarioOutline: { + "परिदृश्य रूपरेखा", + }, + examples: { + "उदाहरण", + }, + given: { + "* ", + "जर", + "दिलेल्या प्रमाणे ", + }, + when: { + "* ", + "जेव्हा ", + }, + then: { + "* ", + "मग ", + "तेव्हा ", + }, + and: { + "* ", + "आणि ", + "तसेच ", + }, + but: { + "* ", + "पण ", + "परंतु ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "जर": messages.StepKeywordType_CONTEXT, + + "दिलेल्या प्रमाणे ": messages.StepKeywordType_CONTEXT, + + "जेव्हा ": messages.StepKeywordType_ACTION, + + "मग ": messages.StepKeywordType_OUTCOME, + + "तेव्हा ": messages.StepKeywordType_OUTCOME, + + "आणि ": messages.StepKeywordType_CONJUNCTION, + + "तसेच ": messages.StepKeywordType_CONJUNCTION, + + "पण ": messages.StepKeywordType_CONJUNCTION, + + "परंतु ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, + "amh": &Dialect{ + Language: "amh", + Name: "Amharic", + Native: "አማርኛ", + Keywords: map[string][]string{ + feature: { + "ስራ", + "የተፈለገው ስራ", + "የሚፈለገው ድርጊት", + }, + rule: { + "ህግ", + }, + background: { + "ቅድመ ሁኔታ", + "መነሻ", + "መነሻ ሀሳብ", + }, + scenario: { + "ምሳሌ", + "ሁናቴ", + }, + scenarioOutline: { + "ሁናቴ ዝርዝር", + "ሁናቴ አብነት", + }, + examples: { + "ምሳሌዎች", + "ሁናቴዎች", + }, + given: { + "* ", + "የተሰጠ ", + }, + when: { + "* ", + "መቼ ", + }, + then: { + "* ", + "ከዚያ ", + }, + and: { + "* ", + "እና ", + }, + but: { + "* ", + "ግን ", + }, + }, + KeywordTypes: map[string]messages.StepKeywordType{ + "የተሰጠ ": messages.StepKeywordType_CONTEXT, + + "መቼ ": messages.StepKeywordType_ACTION, + + "ከዚያ ": messages.StepKeywordType_OUTCOME, + + "እና ": messages.StepKeywordType_CONJUNCTION, + + "ግን ": messages.StepKeywordType_CONJUNCTION, + + "* ": messages.StepKeywordType_UNKNOWN, + }, + }, +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go.jq b/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go.jq new file mode 100644 index 0000000000..722844d2e9 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/dialects_builtin.go.jq @@ -0,0 +1,114 @@ +. as $root +| ( + [ to_entries[] + | [ + "\t",(.key|@json),": &Dialect{\n", + "\t\tLanguage: ", (.key|@json), ",\n", + "\t\tName: ", (.value.name|@json),",\n", + "\t\tNative: ",(.value.native|@json),",\n", + "\t\tKeywords: map[string][]string{\n" + ] + ( + [ .value + | {"feature","rule","background","scenario","scenarioOutline","examples","given","when","then","and","but"} + | to_entries[] + | "\t\t\t"+(.key), ": {\n", + ([ .value[] | "\t\t\t\t", @json, ",\n" ]|add), + "\t\t\t},\n" + ] + ) + [ + "\t\t},\n", + "\t\tKeywordTypes: map[string]messages.StepKeywordType{\n" + ] + ( + [ .value.given + | ( + [ .[] | select(. != "* ") | + "\t\t\t", + @json, + ": messages.StepKeywordType_CONTEXT", + ",\n\n" + ] | add + ), + "" + ] + + + [ .value.when + | ( + [ .[] | select(. != "* ") | + "\t\t\t", + @json, + ": messages.StepKeywordType_ACTION", + ",\n\n" + ] | add + ), + "" + ] + + + [ .value.then + | ( + [ .[] | select(. != "* ") | + "\t\t\t", + @json, + ": messages.StepKeywordType_OUTCOME", + ",\n\n" + ] | add + ), + "" + ] + + + [ .value.and + | ( + [ .[] | select(. != "* ") | + "\t\t\t", + @json, + ": messages.StepKeywordType_CONJUNCTION", + ",\n\n" + ] | add + ), + "" + ] + + + [ .value.but + | ( + [ .[] | select(. != "* ") | + "\t\t\t", + @json, + ": messages.StepKeywordType_CONJUNCTION", + ",\n\n" + ] | add + ), + "" + ] + + [ + "\t\t\t\"* \": messages.StepKeywordType_UNKNOWN,\n" + ] + ) + [ + "\t\t},\n", + "\t},\n" + ] + | add + ] + | add + ) +| "// Code generated from dialects_builtin.go.jq (make dialects_builtin.go); DO NOT EDIT.\n\n" # Standard header defined at https://golang.org/s/generatedcode ++ "package gherkin\n\n" ++ "import messages \"github.com/cucumber/messages/go/v34\"\n\n" ++ "// Builtin dialects for " + ([ $root | to_entries[] | .key+" ("+.value.name+")" ] | join(", ")) + "\n" ++ "func DialectsBuiltin() DialectProvider {\n" ++ "\treturn builtinDialects\n" ++ "}\n\n" ++ "const (\n" ++ " feature = \"feature\"\n" ++ " rule = \"rule\"\n" ++ " background = \"background\"\n" ++ " scenario = \"scenario\"\n" ++ " scenarioOutline = \"scenarioOutline\"\n" ++ " examples = \"examples\"\n" ++ " given = \"given\"\n" ++ " when = \"when\"\n" ++ " then = \"then\"\n" ++ " and = \"and\"\n" ++ " but = \"but\"\n" ++ ")\n\n" ++ "var builtinDialects = gherkinDialectMap{\n" ++ . ++ "}" diff --git a/vendor/github.com/cucumber/gherkin/go/v42/gherkin.go b/vendor/github.com/cucumber/gherkin/go/v42/gherkin.go new file mode 100644 index 0000000000..a5fdfc356f --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/gherkin.go @@ -0,0 +1,144 @@ +package gherkin + +import ( + "bufio" + "fmt" + "io" + "strings" + + messages "github.com/cucumber/messages/go/v34" +) + +type Parser interface { + StopAtFirstError(b bool) + Parse(s Scanner, m Matcher) (err error) +} + +/* +The Scanner reads a gherkin doc (typically read from a .feature file) and creates a token for +each line. The tokens are passed to the parser, which outputs an AST (Abstract Syntax Tree). + +If the scanner sees a # language header, it will reconfigure itself dynamically to look for +Gherkin keywords for the associated language. The keywords are defined in gherkin-languages.json. +*/ +type Scanner interface { + Scan() (line *Line, atEof bool, err error) +} + +type Builder interface { + Build(*Token) (bool, error) + StartRule(RuleType) (bool, error) + EndRule(RuleType) (bool, error) + Reset() +} + +type Token struct { + Type TokenType + Keyword string + KeywordType messages.StepKeywordType + Text string + Items []*LineSpan + GherkinDialect string + Indent string + Location *Location +} + +func (t *Token) IsEOF() bool { + return t.Type == TokenTypeEOF +} +func (t *Token) String() string { + return fmt.Sprintf("%v: %s/%s", t.Type, t.Keyword, t.Text) +} + +type LineSpan struct { + Column int + Text string +} + +func (l *LineSpan) String() string { + return fmt.Sprintf("%d:%s", l.Column, l.Text) +} + +type parser struct { + builder Builder + stopAtFirstError bool +} + +func NewParser(b Builder) Parser { + return &parser{ + builder: b, + } +} + +func (p *parser) StopAtFirstError(b bool) { + p.stopAtFirstError = b +} + +func NewScanner(r io.Reader) Scanner { + return &scanner{ + s: bufio.NewScanner(r), + line: 0, + } +} + +type scanner struct { + s *bufio.Scanner + line int +} + +func (t *scanner) Scan() (line *Line, atEof bool, err error) { + scanning := t.s.Scan() + if !scanning { + err = t.s.Err() + if err == nil { + atEof = true + } + } + if err == nil { + t.line += 1 + str := t.s.Text() + line = &Line{str, t.line, strings.TrimLeft(str, " \t"), atEof} + } + return +} + +type Line struct { + LineText string + LineNumber int + TrimmedLineText string + AtEof bool +} + +func (g *Line) Indent() int { + return len(g.LineText) - len(g.TrimmedLineText) +} + +func (g *Line) IsEmpty() bool { + return len(g.TrimmedLineText) == 0 +} + +func (g *Line) IsEof() bool { + return g.AtEof +} + +func (g *Line) StartsWith(prefix string) bool { + return strings.HasPrefix(g.TrimmedLineText, prefix) +} + +func ParseGherkinDocument(in io.Reader, newId func() string) (gherkinDocument *messages.GherkinDocument, err error) { + return ParseGherkinDocumentForLanguage(in, DefaultDialect, newId) +} + +func ParseGherkinDocumentForLanguage(in io.Reader, language string, newId func() string) (gherkinDocument *messages.GherkinDocument, err error) { + + builder := NewAstBuilder(newId) + parser := NewParser(builder) + parser.StopAtFirstError(false) + matcher := NewLanguageMatcher(DialectsBuiltin(), language) + + scanner := NewScanner(in) + + err = parser.Parse(scanner, matcher) + + return builder.GetGherkinDocument(), err +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/matcher.go b/vendor/github.com/cucumber/gherkin/go/v42/matcher.go new file mode 100644 index 0000000000..2c94bcd9a2 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/matcher.go @@ -0,0 +1,305 @@ +package gherkin + +import ( + "regexp" + "strings" + "unicode" + "unicode/utf8" +) + +const ( + DefaultDialect = "en" + CommentPrefix = "#" + TagPrefix = "@" + TitleKeywordSeparator = ":" + TableCellSeparator = '|' + EscapeChar = '\\' + EscapedNewline = 'n' + DocstringSeparator = "\"\"\"" + DocstringAlternativeSeparator = "```" +) + +var ( + defaultLanguagePattern = regexp.MustCompile("^\\s*#\\s*language\\s*:\\s*([a-zA-Z\\-_]+)\\s*$") + commentDelimiterPattern = regexp.MustCompile(`\s+` + CommentPrefix) +) + +type matcher struct { + gdp DialectProvider + defaultLang string + lang string + dialect *Dialect + activeDocStringSeparator string + indentToRemove int + languagePattern *regexp.Regexp +} + +func NewMatcher(gdp DialectProvider) Matcher { + return &matcher{ + gdp: gdp, + defaultLang: DefaultDialect, + lang: DefaultDialect, + dialect: gdp.GetDialect(DefaultDialect), + languagePattern: defaultLanguagePattern, + } +} + +func NewLanguageMatcher(gdp DialectProvider, language string) Matcher { + return &matcher{ + gdp: gdp, + defaultLang: language, + lang: language, + dialect: gdp.GetDialect(language), + languagePattern: defaultLanguagePattern, + } +} + +func (m *matcher) Reset() { + m.indentToRemove = 0 + m.activeDocStringSeparator = "" + if m.lang != "en" { + m.dialect = m.gdp.GetDialect(m.defaultLang) + m.lang = "en" + } +} + +func (m *matcher) newTokenAtLocation(line, index int) (token *Token) { + column := index + 1 + token = new(Token) + token.GherkinDialect = m.lang + token.Location = &Location{line, column} + return +} + +func (m *matcher) MatchEOF(line *Line) (ok bool, token *Token, err error) { + if line.IsEof() { + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeEOF + } + return +} + +func (m *matcher) MatchEmpty(line *Line) (ok bool, token *Token, err error) { + if line.IsEmpty() { + token, ok = m.newTokenAtLocation(line.LineNumber, 0), true + token.Type = TokenTypeEmpty + } + return +} + +func (m *matcher) MatchComment(line *Line) (ok bool, token *Token, err error) { + if line.StartsWith(CommentPrefix) { + token, ok = m.newTokenAtLocation(line.LineNumber, 0), true + token.Type = TokenTypeComment + token.Text = line.LineText + } + return +} + +func (m *matcher) MatchTagLine(line *Line) (ok bool, token *Token, err error) { + if !line.StartsWith(TagPrefix) { + return + } + uncommentedLine := commentDelimiterPattern.Split(line.TrimmedLineText, 2)[0] + var tags []*LineSpan + var column = line.Indent() + 1 + + splits := strings.Split(uncommentedLine, TagPrefix) + for i := range splits { + txt := strings.TrimRightFunc(splits[i], func(r rune) bool { + return unicode.IsSpace(r) + }) + if len(txt) == 0 { + continue + } + if strings.ContainsAny(txt, "\t\n\f\r ") { + location := &Location{line.LineNumber, column} + msg := "A tag may not contain whitespace" + err = &parseError{msg, location} + break + } + tags = append(tags, &LineSpan{column, TagPrefix + txt}) + column = column + utf8.RuneCountInString(splits[i]) + 1 + } + + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeTagLine + token.Items = tags + + return +} + +func (m *matcher) matchTitleLine(line *Line, tokenType TokenType, keywords []string) (ok bool, token *Token, err error) { + for i := range keywords { + keyword := keywords[i] + if line.StartsWith(keyword + TitleKeywordSeparator) { + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = tokenType + token.Keyword = keyword + token.Text = strings.Trim(line.TrimmedLineText[len(keyword)+1:], " \t") + return + } + } + return +} + +func (m *matcher) MatchFeatureLine(line *Line) (ok bool, token *Token, err error) { + return m.matchTitleLine(line, TokenTypeFeatureLine, m.dialect.FeatureKeywords()) +} +func (m *matcher) MatchRuleLine(line *Line) (ok bool, token *Token, err error) { + return m.matchTitleLine(line, TokenTypeRuleLine, m.dialect.RuleKeywords()) +} +func (m *matcher) MatchBackgroundLine(line *Line) (ok bool, token *Token, err error) { + return m.matchTitleLine(line, TokenTypeBackgroundLine, m.dialect.BackgroundKeywords()) +} +func (m *matcher) MatchScenarioLine(line *Line) (ok bool, token *Token, err error) { + ok, token, err = m.matchTitleLine(line, TokenTypeScenarioLine, m.dialect.ScenarioKeywords()) + if ok || (err != nil) { + return ok, token, err + } + ok, token, err = m.matchTitleLine(line, TokenTypeScenarioLine, m.dialect.ScenarioOutlineKeywords()) + return ok, token, err +} +func (m *matcher) MatchExamplesLine(line *Line) (ok bool, token *Token, err error) { + return m.matchTitleLine(line, TokenTypeExamplesLine, m.dialect.ExamplesKeywords()) +} +func (m *matcher) MatchStepLine(line *Line) (ok bool, token *Token, err error) { + keywords := m.dialect.StepKeywords() + for i := range keywords { + keyword := keywords[i] + if line.StartsWith(keyword) { + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeStepLine + token.Keyword = keyword + token.KeywordType = m.dialect.StepKeywordType(keyword) + token.Text = strings.Trim(line.TrimmedLineText[len(keyword):], " \t") + return + } + } + return +} + +func (m *matcher) MatchDocStringSeparator(line *Line) (ok bool, token *Token, err error) { + if m.activeDocStringSeparator != "" { + if line.StartsWith(m.activeDocStringSeparator) { + // close + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeDocStringSeparator + token.Keyword = m.activeDocStringSeparator + + m.indentToRemove = 0 + m.activeDocStringSeparator = "" + } + return + } + if line.StartsWith(DocstringSeparator) { + m.activeDocStringSeparator = DocstringSeparator + } else if line.StartsWith(DocstringAlternativeSeparator) { + m.activeDocStringSeparator = DocstringAlternativeSeparator + } + if m.activeDocStringSeparator != "" { + // open + mediaType := line.TrimmedLineText[len(m.activeDocStringSeparator):] + m.indentToRemove = line.Indent() + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeDocStringSeparator + token.Keyword = m.activeDocStringSeparator + token.Text = mediaType + } + return +} + +func isSpaceAndNotNewLine(r rune) bool { + return unicode.IsSpace(r) && r != '\n' +} + +func (m *matcher) MatchTableRow(line *Line) (ok bool, token *Token, err error) { + var firstChar, firstPos = utf8.DecodeRuneInString(line.TrimmedLineText) + if firstChar == TableCellSeparator { + var cells []*LineSpan + var cell []rune + var startCol = line.Indent() + 2 // column where the current cell started + // start after the first separator, it's not included in the cell + for i, w, col := firstPos, 0, startCol; i < len(line.TrimmedLineText); i += w { + var char rune + char, w = utf8.DecodeRuneInString(line.TrimmedLineText[i:]) + if char == TableCellSeparator { + // append current cell + txt := string(cell) + + txtTrimmedLeadingSpace := strings.TrimLeftFunc(txt, isSpaceAndNotNewLine) + ind := utf8.RuneCountInString(txt) - utf8.RuneCountInString(txtTrimmedLeadingSpace) + txtTrimmed := strings.TrimRightFunc(txtTrimmedLeadingSpace, isSpaceAndNotNewLine) + cells = append(cells, &LineSpan{startCol + ind, txtTrimmed}) + // start building next + cell = make([]rune, 0) + startCol = col + 1 + } else if char == EscapeChar { + // skip this character but count the column + i += w + col++ + char, w = utf8.DecodeRuneInString(line.TrimmedLineText[i:]) + if char == EscapedNewline { + cell = append(cell, '\n') + } else { + if char != TableCellSeparator && char != EscapeChar { + cell = append(cell, EscapeChar) + } + cell = append(cell, char) + } + } else { + cell = append(cell, char) + } + col++ + } + + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeTableRow + token.Items = cells + } + return +} + +func (m *matcher) MatchLanguage(line *Line) (ok bool, token *Token, err error) { + matches := m.languagePattern.FindStringSubmatch(line.TrimmedLineText) + if len(matches) > 0 { + lang := matches[1] + token, ok = m.newTokenAtLocation(line.LineNumber, line.Indent()), true + token.Type = TokenTypeLanguage + token.Text = lang + + dialect := m.gdp.GetDialect(lang) + if dialect == nil { + err = &parseError{"Language not supported: " + lang, token.Location} + } else { + m.lang = lang + m.dialect = dialect + } + } + return +} + +func (m *matcher) MatchOther(line *Line) (ok bool, token *Token, err error) { + token, ok = m.newTokenAtLocation(line.LineNumber, 0), true + token.Type = TokenTypeOther + + element := line.LineText + txt := strings.TrimLeft(element, " ") + + if len(element)-len(txt) > m.indentToRemove { + token.Text = m.unescapeDocString(element[m.indentToRemove:]) + } else { + token.Text = m.unescapeDocString(txt) + } + return +} + +func (m *matcher) unescapeDocString(text string) string { + if m.activeDocStringSeparator == DocstringSeparator { + return strings.Replace(text, "\\\"\\\"\\\"", DocstringSeparator, -1) + } + if m.activeDocStringSeparator == DocstringAlternativeSeparator { + return strings.Replace(text, "\\`\\`\\`", DocstringAlternativeSeparator, -1) + } + return text +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/messages.go b/vendor/github.com/cucumber/gherkin/go/v42/messages.go new file mode 100644 index 0000000000..dc60ee82e9 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/messages.go @@ -0,0 +1,120 @@ +package gherkin + +import ( + "encoding/json" + "fmt" + "github.com/cucumber/messages/go/v34" + "io" + "io/ioutil" + "strings" +) + +func Messages( + paths []string, + decoder *json.Decoder, + language string, + includeSource bool, + includeGherkinDocument bool, + includePickles bool, + encoder *json.Encoder, + newId func() string, +) ([]messages.Envelope, error) { + var result []messages.Envelope + var err error + + handleMessage := func(result []messages.Envelope, message *messages.Envelope) ([]messages.Envelope, error) { + if encoder != nil { + err = encoder.Encode(message) + return result, err + } else { + result = append(result, *message) + } + + return result, err + } + + processSource := func(source *messages.Source) error { + if includeSource { + result, err = handleMessage(result, &messages.Envelope{ + Source: source, + }) + } + doc, err := ParseGherkinDocumentForLanguage(strings.NewReader(source.Data), language, newId) + if errs, ok := err.(parseErrors); ok { + // expected parse errors + for _, err := range errs { + if pe, ok := err.(*parseError); ok { + result, err = handleMessage(result, pe.asMessage(source.Uri)) + } else { + return fmt.Errorf("parse feature file: %s, unexpected error: %+v\n", source.Uri, err) + } + } + return nil + } + + if includeGherkinDocument { + doc.Uri = source.Uri + result, err = handleMessage(result, &messages.Envelope{ + GherkinDocument: doc, + }) + } + + if includePickles { + for _, pickle := range Pickles(*doc, source.Uri, newId) { + result, err = handleMessage(result, &messages.Envelope{ + Pickle: pickle, + }) + } + } + return nil + } + + if len(paths) == 0 { + for { + envelope := &messages.Envelope{} + err := decoder.Decode(envelope) + //marshal, err := json.Marshal(envelope) + //fmt.Println(string(marshal)) + if err == io.EOF { + break + } + + if envelope.Source != nil { + err = processSource(envelope.Source) + if err != nil { + return result, err + } + } + } + } else { + for _, path := range paths { + in, err := ioutil.ReadFile(path) + if err != nil { + return result, fmt.Errorf("read feature file: %s - %+v", path, err) + } + source := &messages.Source{ + Uri: path, + Data: string(in), + MediaType: "text/x.cucumber.gherkin+plain", + } + processSource(source) + } + } + + return result, err +} + +func (a *parseError) asMessage(uri string) *messages.Envelope { + return &messages.Envelope{ + ParseError: &messages.ParseError{ + Message: a.Error(), + Source: &messages.SourceReference{ + Uri: uri, + Location: &messages.Location{ + Line: int64(a.loc.Line), + Column: int64(a.loc.Column), + }, + }, + }, + } +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/parser.go b/vendor/github.com/cucumber/gherkin/go/v42/parser.go new file mode 100644 index 0000000000..86e7f556fe --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/parser.go @@ -0,0 +1,4929 @@ +// +// This file is generated. Do not edit! Edit parser.go.razor instead. + +package gherkin + +import ( + "fmt" + "strings" +) + +type TokenType int + +const ( + TokenTypeNone TokenType = iota + TokenTypeEOF + TokenTypeEmpty + TokenTypeComment + TokenTypeTagLine + TokenTypeFeatureLine + TokenTypeRuleLine + TokenTypeBackgroundLine + TokenTypeScenarioLine + TokenTypeExamplesLine + TokenTypeStepLine + TokenTypeDocStringSeparator + TokenTypeTableRow + TokenTypeLanguage + TokenTypeOther +) + +func tokenTypeForRule(rt RuleType) TokenType { + return TokenTypeNone +} + +func (t TokenType) Name() string { + switch t { + case TokenTypeEOF: + return "EOF" + case TokenTypeEmpty: + return "Empty" + case TokenTypeComment: + return "Comment" + case TokenTypeTagLine: + return "TagLine" + case TokenTypeFeatureLine: + return "FeatureLine" + case TokenTypeRuleLine: + return "RuleLine" + case TokenTypeBackgroundLine: + return "BackgroundLine" + case TokenTypeScenarioLine: + return "ScenarioLine" + case TokenTypeExamplesLine: + return "ExamplesLine" + case TokenTypeStepLine: + return "StepLine" + case TokenTypeDocStringSeparator: + return "DocStringSeparator" + case TokenTypeTableRow: + return "TableRow" + case TokenTypeLanguage: + return "Language" + case TokenTypeOther: + return "Other" + } + return "" +} + +func (t TokenType) RuleType() RuleType { + switch t { + case TokenTypeEOF: + return RuleTypeEOF + case TokenTypeEmpty: + return RuleTypeEmpty + case TokenTypeComment: + return RuleTypeComment + case TokenTypeTagLine: + return RuleTypeTagLine + case TokenTypeFeatureLine: + return RuleTypeFeatureLine + case TokenTypeRuleLine: + return RuleTypeRuleLine + case TokenTypeBackgroundLine: + return RuleTypeBackgroundLine + case TokenTypeScenarioLine: + return RuleTypeScenarioLine + case TokenTypeExamplesLine: + return RuleTypeExamplesLine + case TokenTypeStepLine: + return RuleTypeStepLine + case TokenTypeDocStringSeparator: + return RuleTypeDocStringSeparator + case TokenTypeTableRow: + return RuleTypeTableRow + case TokenTypeLanguage: + return RuleTypeLanguage + case TokenTypeOther: + return RuleTypeOther + } + return RuleTypeNone +} + +type RuleType int + +const ( + RuleTypeNone RuleType = iota + RuleTypeEOF + RuleTypeEmpty + RuleTypeComment + RuleTypeTagLine + RuleTypeFeatureLine + RuleTypeRuleLine + RuleTypeBackgroundLine + RuleTypeScenarioLine + RuleTypeExamplesLine + RuleTypeStepLine + RuleTypeDocStringSeparator + RuleTypeTableRow + RuleTypeLanguage + RuleTypeOther + RuleTypeGherkinDocument + RuleTypeFeature + RuleTypeFeatureHeader + RuleTypeRule + RuleTypeRuleHeader + RuleTypeBackground + RuleTypeScenarioDefinition + RuleTypeScenario + RuleTypeExamplesDefinition + RuleTypeExamples + RuleTypeExamplesTable + RuleTypeStep + RuleTypeStepArg + RuleTypeDataTableAndMaybeDocString + RuleTypeDocStringAndMaybeDataTable + RuleTypeDataTable + RuleTypeDocString + RuleTypeTags + RuleTypeDescriptionHelper + RuleTypeDescription +) + +func (t RuleType) IsEOF() bool { + return t == RuleTypeEOF +} +func (t RuleType) Name() string { + switch t { + case RuleTypeEOF: + return "#EOF" + case RuleTypeEmpty: + return "#Empty" + case RuleTypeComment: + return "#Comment" + case RuleTypeTagLine: + return "#TagLine" + case RuleTypeFeatureLine: + return "#FeatureLine" + case RuleTypeRuleLine: + return "#RuleLine" + case RuleTypeBackgroundLine: + return "#BackgroundLine" + case RuleTypeScenarioLine: + return "#ScenarioLine" + case RuleTypeExamplesLine: + return "#ExamplesLine" + case RuleTypeStepLine: + return "#StepLine" + case RuleTypeDocStringSeparator: + return "#DocStringSeparator" + case RuleTypeTableRow: + return "#TableRow" + case RuleTypeLanguage: + return "#Language" + case RuleTypeOther: + return "#Other" + case RuleTypeGherkinDocument: + return "GherkinDocument" + case RuleTypeFeature: + return "Feature" + case RuleTypeFeatureHeader: + return "FeatureHeader" + case RuleTypeRule: + return "Rule" + case RuleTypeRuleHeader: + return "RuleHeader" + case RuleTypeBackground: + return "Background" + case RuleTypeScenarioDefinition: + return "ScenarioDefinition" + case RuleTypeScenario: + return "Scenario" + case RuleTypeExamplesDefinition: + return "ExamplesDefinition" + case RuleTypeExamples: + return "Examples" + case RuleTypeExamplesTable: + return "ExamplesTable" + case RuleTypeStep: + return "Step" + case RuleTypeStepArg: + return "StepArg" + case RuleTypeDataTableAndMaybeDocString: + return "DataTableAndMaybeDocString" + case RuleTypeDocStringAndMaybeDataTable: + return "DocStringAndMaybeDataTable" + case RuleTypeDataTable: + return "DataTable" + case RuleTypeDocString: + return "DocString" + case RuleTypeTags: + return "Tags" + case RuleTypeDescriptionHelper: + return "DescriptionHelper" + case RuleTypeDescription: + return "Description" + } + return "" +} + +type Location struct { + Line int + Column int +} + +type parseError struct { + msg string + loc *Location +} + +func (a *parseError) Error() string { + return fmt.Sprintf("(%d:%d): %s", a.loc.Line, a.loc.Column, a.msg) +} + +type parseErrors []error + +func (pe parseErrors) Error() string { + var ret = []string{"Parser errors:"} + for i := range pe { + ret = append(ret, pe[i].Error()) + } + return strings.Join(ret, "\n") +} + +func (p *parser) Parse(s Scanner, m Matcher) (err error) { + p.builder.Reset() + m.Reset() + ctxt := &parseContext{p, s, p.builder, m, nil, nil} + var state int + ctxt.startRule(RuleTypeGherkinDocument) + for { + gl, eof, err := ctxt.scan() + if err != nil { + ctxt.addError(err) + if p.stopAtFirstError { + break + } + } + state, err = ctxt.match(state, gl) + if err != nil { + ctxt.addError(err) + if p.stopAtFirstError { + break + } + } + if eof { + // done! \o/ + break + } + } + ctxt.endRule(RuleTypeGherkinDocument) + if len(ctxt.errors) > 0 { + return ctxt.errors + } + return +} + +type parseContext struct { + p *parser + s Scanner + b Builder + m Matcher + queue []*scanResult + errors parseErrors +} + +func (ctxt *parseContext) addError(e error) { + ctxt.errors = append(ctxt.errors, e) + // if (p.errors.length > 10) + // throw Errors.CompositeParserException.create(p.errors); +} + +type scanResult struct { + line *Line + atEof bool + err error +} + +func (ctxt *parseContext) scan() (*Line, bool, error) { + l := len(ctxt.queue) + if l > 0 { + x := ctxt.queue[0] + ctxt.queue = ctxt.queue[1:] + return x.line, x.atEof, x.err + } + return ctxt.s.Scan() +} + +func (ctxt *parseContext) startRule(r RuleType) (bool, error) { + ok, err := ctxt.b.StartRule(r) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) endRule(r RuleType) (bool, error) { + ok, err := ctxt.b.EndRule(r) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) build(t *Token) (bool, error) { + ok, err := ctxt.b.Build(t) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) match(state int, line *Line) (newState int, err error) { + switch state { + case 0: + return ctxt.matchAt0(line) + case 1: + return ctxt.matchAt1(line) + case 2: + return ctxt.matchAt2(line) + case 3: + return ctxt.matchAt3(line) + case 4: + return ctxt.matchAt4(line) + case 5: + return ctxt.matchAt5(line) + case 6: + return ctxt.matchAt6(line) + case 7: + return ctxt.matchAt7(line) + case 8: + return ctxt.matchAt8(line) + case 9: + return ctxt.matchAt9(line) + case 10: + return ctxt.matchAt10(line) + case 11: + return ctxt.matchAt11(line) + case 12: + return ctxt.matchAt12(line) + case 13: + return ctxt.matchAt13(line) + case 14: + return ctxt.matchAt14(line) + case 15: + return ctxt.matchAt15(line) + case 16: + return ctxt.matchAt16(line) + case 17: + return ctxt.matchAt17(line) + case 18: + return ctxt.matchAt18(line) + case 19: + return ctxt.matchAt19(line) + case 20: + return ctxt.matchAt20(line) + case 21: + return ctxt.matchAt21(line) + case 22: + return ctxt.matchAt22(line) + case 23: + return ctxt.matchAt23(line) + case 24: + return ctxt.matchAt24(line) + case 25: + return ctxt.matchAt25(line) + case 26: + return ctxt.matchAt26(line) + case 27: + return ctxt.matchAt27(line) + case 28: + return ctxt.matchAt28(line) + case 29: + return ctxt.matchAt29(line) + case 30: + return ctxt.matchAt30(line) + case 31: + return ctxt.matchAt31(line) + case 32: + return ctxt.matchAt32(line) + case 33: + return ctxt.matchAt33(line) + case 34: + return ctxt.matchAt34(line) + case 35: + return ctxt.matchAt35(line) + case 36: + return ctxt.matchAt36(line) + case 37: + return ctxt.matchAt37(line) + case 38: + return ctxt.matchAt38(line) + case 39: + return ctxt.matchAt39(line) + case 40: + return ctxt.matchAt40(line) + case 41: + return ctxt.matchAt41(line) + case 43: + return ctxt.matchAt43(line) + case 44: + return ctxt.matchAt44(line) + case 45: + return ctxt.matchAt45(line) + case 46: + return ctxt.matchAt46(line) + case 47: + return ctxt.matchAt47(line) + case 48: + return ctxt.matchAt48(line) + case 49: + return ctxt.matchAt49(line) + case 50: + return ctxt.matchAt50(line) + case 51: + return ctxt.matchAt51(line) + case 52: + return ctxt.matchAt52(line) + case 53: + return ctxt.matchAt53(line) + case 54: + return ctxt.matchAt54(line) + default: + return state, fmt.Errorf("Unknown state: %+v", state) + } +} + +// Start +func (ctxt *parseContext) matchAt0(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchLanguage(line); ok { + ctxt.startRule(RuleTypeFeature) + ctxt.startRule(RuleTypeFeatureHeader) + ctxt.build(token) + return 1, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.startRule(RuleTypeFeature) + ctxt.startRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 2, err + } + if ok, token, err := ctxt.matchFeatureLine(line); ok { + ctxt.startRule(RuleTypeFeature) + ctxt.startRule(RuleTypeFeatureHeader) + ctxt.build(token) + return 3, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 0, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 0, err + } + + // var stateComment = "State: 0 - Start" + var expectedTokens = []string{"#EOF", "#Language", "#TagLine", "#FeatureLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 0, err +} + +// GherkinDocument:0>Feature:0>FeatureHeader:0>#Language:0 +func (ctxt *parseContext) matchAt1(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 2, err + } + if ok, token, err := ctxt.matchFeatureLine(line); ok { + ctxt.build(token) + return 3, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 1, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 1, err + } + + // var stateComment = "State: 1 - GherkinDocument:0>Feature:0>FeatureHeader:0>#Language:0" + var expectedTokens = []string{"#TagLine", "#FeatureLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 1, err +} + +// GherkinDocument:0>Feature:0>FeatureHeader:1>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt2(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 2, err + } + if ok, token, err := ctxt.matchFeatureLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.build(token) + return 3, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 2, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 2, err + } + + // var stateComment = "State: 2 - GherkinDocument:0>Feature:0>FeatureHeader:1>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#FeatureLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 2, err +} + +// GherkinDocument:0>Feature:0>FeatureHeader:2>#FeatureLine:0 +func (ctxt *parseContext) matchAt3(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 3, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 4, err + } + if ok, token, err := ctxt.matchBackgroundLine(line); ok { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeBackground) + ctxt.build(token) + return 5, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 4, err + } + + // var stateComment = "State: 3 - GherkinDocument:0>Feature:0>FeatureHeader:2>#FeatureLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#BackgroundLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 3, err +} + +// GherkinDocument:0>Feature:0>FeatureHeader:3>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt4(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 4, err + } + if ok, token, err := ctxt.matchBackgroundLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeBackground) + ctxt.build(token) + return 5, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeFeatureHeader) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 4, err + } + + // var stateComment = "State: 4 - GherkinDocument:0>Feature:0>FeatureHeader:3>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#BackgroundLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 4, err +} + +// GherkinDocument:0>Feature:1>Background:0>#BackgroundLine:0 +func (ctxt *parseContext) matchAt5(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 5, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 6, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 6, err + } + + // var stateComment = "State: 5 - GherkinDocument:0>Feature:1>Background:0>#BackgroundLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 5, err +} + +// GherkinDocument:0>Feature:1>Background:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt6(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 6, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 6, err + } + + // var stateComment = "State: 6 - GherkinDocument:0>Feature:1>Background:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 6, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:0>#StepLine:0 +func (ctxt *parseContext) matchAt7(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 8, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 52, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 7, err + } + + // var stateComment = "State: 7 - GherkinDocument:0>Feature:1>Background:2>Step:0>#StepLine:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 7, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt8(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 8, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 9, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 8, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 8, err + } + + // var stateComment = "State: 8 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 8, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt9(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 10, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 9, err + } + + // var stateComment = "State: 9 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 9, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt10(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 10, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 10, err + } + + // var stateComment = "State: 10 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 10, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:0>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt11(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 11, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 11, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 11, err + } + + // var stateComment = "State: 11 - GherkinDocument:0>Feature:2>ScenarioDefinition:0>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#ScenarioLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 11, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:0>#ScenarioLine:0 +func (ctxt *parseContext) matchAt12(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 13, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 13, err + } + + // var stateComment = "State: 12 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:0>#ScenarioLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 12, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt13(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 13, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 13, err + } + + // var stateComment = "State: 13 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 13, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:0>#StepLine:0 +func (ctxt *parseContext) matchAt14(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 15, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 49, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 14, err + } + + // var stateComment = "State: 14 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:0>#StepLine:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 14, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt15(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 15, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 16, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 15, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 15, err + } + + // var stateComment = "State: 15 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 15, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt16(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 17, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 16, err + } + + // var stateComment = "State: 16 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 16, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt17(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 17, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 17, err + } + + // var stateComment = "State: 17 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 17, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:0>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt18(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 18, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 18, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 18, err + } + + // var stateComment = "State: 18 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:0>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#ExamplesLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 18, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:0>#ExamplesLine:0 +func (ctxt *parseContext) matchAt19(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 20, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeExamplesTable) + ctxt.build(token) + return 21, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 20, err + } + + // var stateComment = "State: 19 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:0>#ExamplesLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 19, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt20(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 20, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesTable) + ctxt.build(token) + return 21, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 20, err + } + + // var stateComment = "State: 20 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 20, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:2>ExamplesTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt21(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 21, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 21, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 21, err + } + + // var stateComment = "State: 21 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:2>ExamplesTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 21, err +} + +// GherkinDocument:0>Feature:3>Rule:0>RuleHeader:0>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt22(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 22, err + } + + // var stateComment = "State: 22 - GherkinDocument:0>Feature:3>Rule:0>RuleHeader:0>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 22, err +} + +// GherkinDocument:0>Feature:3>Rule:0>RuleHeader:1>#RuleLine:0 +func (ctxt *parseContext) matchAt23(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 24, err + } + if ok, token, err := ctxt.matchBackgroundLine(line); ok { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeBackground) + ctxt.build(token) + return 25, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 24, err + } + + // var stateComment = "State: 23 - GherkinDocument:0>Feature:3>Rule:0>RuleHeader:1>#RuleLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#BackgroundLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 23, err +} + +// GherkinDocument:0>Feature:3>Rule:0>RuleHeader:2>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt24(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 24, err + } + if ok, token, err := ctxt.matchBackgroundLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeBackground) + ctxt.build(token) + return 25, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeRuleHeader) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 24, err + } + + // var stateComment = "State: 24 - GherkinDocument:0>Feature:3>Rule:0>RuleHeader:2>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#BackgroundLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 24, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:0>#BackgroundLine:0 +func (ctxt *parseContext) matchAt25(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 25, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 26, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 26, err + } + + // var stateComment = "State: 25 - GherkinDocument:0>Feature:3>Rule:1>Background:0>#BackgroundLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 25, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt26(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 26, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 26, err + } + + // var stateComment = "State: 26 - GherkinDocument:0>Feature:3>Rule:1>Background:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 26, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:0>#StepLine:0 +func (ctxt *parseContext) matchAt27(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 28, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 46, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 27, err + } + + // var stateComment = "State: 27 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:0>#StepLine:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 27, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt28(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 28, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 29, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 28, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 28, err + } + + // var stateComment = "State: 28 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 28, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt29(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 30, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 29, err + } + + // var stateComment = "State: 29 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 29, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt30(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 30, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 30, err + } + + // var stateComment = "State: 30 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 30, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:0>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt31(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 31, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 31, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 31, err + } + + // var stateComment = "State: 31 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:0>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#ScenarioLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 31, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:0>#ScenarioLine:0 +func (ctxt *parseContext) matchAt32(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 33, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 33, err + } + + // var stateComment = "State: 32 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:0>#ScenarioLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 32, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt33(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 33, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 33, err + } + + // var stateComment = "State: 33 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 33, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:0>#StepLine:0 +func (ctxt *parseContext) matchAt34(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 35, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 43, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 34, err + } + + // var stateComment = "State: 34 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:0>#StepLine:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 34, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt35(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 35, err + } + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.startRule(RuleTypeDocString) + ctxt.build(token) + return 36, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 35, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 35, err + } + + // var stateComment = "State: 35 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:0>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#DocStringSeparator", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 35, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt36(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 37, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 36, err + } + + // var stateComment = "State: 36 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 36, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt37(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 37, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 37, err + } + + // var stateComment = "State: 37 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:0>DataTableAndMaybeDocString:1>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 37, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:0>Tags:0>#TagLine:0 +func (ctxt *parseContext) matchAt38(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.build(token) + return 38, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeTags) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 38, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 38, err + } + + // var stateComment = "State: 38 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:0>Tags:0>#TagLine:0" + var expectedTokens = []string{"#TagLine", "#ExamplesLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 38, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:0>#ExamplesLine:0 +func (ctxt *parseContext) matchAt39(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 40, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.startRule(RuleTypeExamplesTable) + ctxt.build(token) + return 41, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.startRule(RuleTypeDescription) + ctxt.build(token) + return 40, err + } + + // var stateComment = "State: 39 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:0>#ExamplesLine:0" + var expectedTokens = []string{"#EOF", "#Empty", "#Comment", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 39, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0 +func (ctxt *parseContext) matchAt40(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 40, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.startRule(RuleTypeExamplesTable) + ctxt.build(token) + return 41, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDescription) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 40, err + } + + // var stateComment = "State: 40 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:1>DescriptionHelper:1>Description:0>__alt1:0>#Other:0" + var expectedTokens = []string{"#EOF", "#Comment", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 40, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:2>ExamplesTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt41(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 41, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeExamplesTable) + ctxt.endRule(RuleTypeExamples) + ctxt.endRule(RuleTypeExamplesDefinition) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 41, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 41, err + } + + // var stateComment = "State: 41 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:3>ExamplesDefinition:1>Examples:2>ExamplesTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 41, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt43(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 44, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 43, err + } + + // var stateComment = "State: 43 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 43, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt44(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 45, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 44, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 44, err + } + + // var stateComment = "State: 44 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 44, err +} + +// GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt45(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 45, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 34, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 38, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 39, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 45, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 45, err + } + + // var stateComment = "State: 45 - GherkinDocument:0>Feature:3>Rule:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 45, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt46(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 47, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 46, err + } + + // var stateComment = "State: 46 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 46, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt47(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 48, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 47, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 47, err + } + + // var stateComment = "State: 47 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 47, err +} + +// GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt48(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 48, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 27, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 31, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 32, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeRule) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 48, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 48, err + } + + // var stateComment = "State: 48 - GherkinDocument:0>Feature:3>Rule:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 48, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt49(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 50, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 49, err + } + + // var stateComment = "State: 49 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 49, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt50(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 51, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 50, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 50, err + } + + // var stateComment = "State: 50 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 50, err +} + +// GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt51(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 51, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 14, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead1(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 18, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchExamplesLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeExamplesDefinition) + ctxt.startRule(RuleTypeExamples) + ctxt.build(token) + return 19, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeScenario) + ctxt.endRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 51, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 51, err + } + + // var stateComment = "State: 51 - GherkinDocument:0>Feature:2>ScenarioDefinition:1>Scenario:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ExamplesLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 51, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt52(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchDocStringSeparator(line); ok { + ctxt.build(token) + return 53, err + } + if ok, token, err := ctxt.matchOther(line); ok { + ctxt.build(token) + return 52, err + } + + // var stateComment = "State: 52 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:0>#DocStringSeparator:0" + var expectedTokens = []string{"#DocStringSeparator", "#Other"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 52, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0 +func (ctxt *parseContext) matchAt53(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.startRule(RuleTypeDataTable) + ctxt.build(token) + return 54, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDocString) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 53, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 53, err + } + + // var stateComment = "State: 53 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:0>DocString:2>#DocStringSeparator:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 53, err +} + +// GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0 +func (ctxt *parseContext) matchAt54(line *Line) (newState int, err error) { + if ok, token, err := ctxt.matchEOF(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.endRule(RuleTypeFeature) + ctxt.build(token) + return 42, err + } + if ok, token, err := ctxt.matchTableRow(line); ok { + ctxt.build(token) + return 54, err + } + if ok, token, err := ctxt.matchStepLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.startRule(RuleTypeStep) + ctxt.build(token) + return 7, err + } + if ok, token, err := ctxt.matchTagLine(line); ok { + if ctxt.lookahead0(line) { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 11, err + } + } + if ok, token, err := ctxt.matchTagLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.startRule(RuleTypeTags) + ctxt.build(token) + return 22, err + } + if ok, token, err := ctxt.matchScenarioLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeScenarioDefinition) + ctxt.startRule(RuleTypeScenario) + ctxt.build(token) + return 12, err + } + if ok, token, err := ctxt.matchRuleLine(line); ok { + ctxt.endRule(RuleTypeDataTable) + ctxt.endRule(RuleTypeStep) + ctxt.endRule(RuleTypeBackground) + ctxt.startRule(RuleTypeRule) + ctxt.startRule(RuleTypeRuleHeader) + ctxt.build(token) + return 23, err + } + if ok, token, err := ctxt.matchComment(line); ok { + ctxt.build(token) + return 54, err + } + if ok, token, err := ctxt.matchEmpty(line); ok { + ctxt.build(token) + return 54, err + } + + // var stateComment = "State: 54 - GherkinDocument:0>Feature:1>Background:2>Step:1>StepArg:0>__alt0:1>DocStringAndMaybeDataTable:1>DataTable:0>#TableRow:0" + var expectedTokens = []string{"#EOF", "#TableRow", "#StepLine", "#TagLine", "#ScenarioLine", "#RuleLine", "#Comment", "#Empty"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return 54, err +} + +type Matcher interface { + MatchEOF(line *Line) (bool, *Token, error) + MatchEmpty(line *Line) (bool, *Token, error) + MatchComment(line *Line) (bool, *Token, error) + MatchTagLine(line *Line) (bool, *Token, error) + MatchFeatureLine(line *Line) (bool, *Token, error) + MatchRuleLine(line *Line) (bool, *Token, error) + MatchBackgroundLine(line *Line) (bool, *Token, error) + MatchScenarioLine(line *Line) (bool, *Token, error) + MatchExamplesLine(line *Line) (bool, *Token, error) + MatchStepLine(line *Line) (bool, *Token, error) + MatchDocStringSeparator(line *Line) (bool, *Token, error) + MatchTableRow(line *Line) (bool, *Token, error) + MatchLanguage(line *Line) (bool, *Token, error) + MatchOther(line *Line) (bool, *Token, error) + Reset() +} + +func (ctxt *parseContext) isMatchEOF(line *Line) bool { + ok, _, _ := ctxt.matchEOF(line) + return ok +} +func (ctxt *parseContext) matchEOF(line *Line) (bool, *Token, error) { + return ctxt.m.MatchEOF(line) +} + +func (ctxt *parseContext) isMatchEmpty(line *Line) bool { + ok, _, _ := ctxt.matchEmpty(line) + return ok +} +func (ctxt *parseContext) matchEmpty(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchEmpty(line) +} + +func (ctxt *parseContext) isMatchComment(line *Line) bool { + ok, _, _ := ctxt.matchComment(line) + return ok +} +func (ctxt *parseContext) matchComment(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchComment(line) +} + +func (ctxt *parseContext) isMatchTagLine(line *Line) bool { + ok, _, _ := ctxt.matchTagLine(line) + return ok +} +func (ctxt *parseContext) matchTagLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchTagLine(line) +} + +func (ctxt *parseContext) isMatchFeatureLine(line *Line) bool { + ok, _, _ := ctxt.matchFeatureLine(line) + return ok +} +func (ctxt *parseContext) matchFeatureLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchFeatureLine(line) +} + +func (ctxt *parseContext) isMatchRuleLine(line *Line) bool { + ok, _, _ := ctxt.matchRuleLine(line) + return ok +} +func (ctxt *parseContext) matchRuleLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchRuleLine(line) +} + +func (ctxt *parseContext) isMatchBackgroundLine(line *Line) bool { + ok, _, _ := ctxt.matchBackgroundLine(line) + return ok +} +func (ctxt *parseContext) matchBackgroundLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchBackgroundLine(line) +} + +func (ctxt *parseContext) isMatchScenarioLine(line *Line) bool { + ok, _, _ := ctxt.matchScenarioLine(line) + return ok +} +func (ctxt *parseContext) matchScenarioLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchScenarioLine(line) +} + +func (ctxt *parseContext) isMatchExamplesLine(line *Line) bool { + ok, _, _ := ctxt.matchExamplesLine(line) + return ok +} +func (ctxt *parseContext) matchExamplesLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchExamplesLine(line) +} + +func (ctxt *parseContext) isMatchStepLine(line *Line) bool { + ok, _, _ := ctxt.matchStepLine(line) + return ok +} +func (ctxt *parseContext) matchStepLine(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchStepLine(line) +} + +func (ctxt *parseContext) isMatchDocStringSeparator(line *Line) bool { + ok, _, _ := ctxt.matchDocStringSeparator(line) + return ok +} +func (ctxt *parseContext) matchDocStringSeparator(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchDocStringSeparator(line) +} + +func (ctxt *parseContext) isMatchTableRow(line *Line) bool { + ok, _, _ := ctxt.matchTableRow(line) + return ok +} +func (ctxt *parseContext) matchTableRow(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchTableRow(line) +} + +func (ctxt *parseContext) isMatchLanguage(line *Line) bool { + ok, _, _ := ctxt.matchLanguage(line) + return ok +} +func (ctxt *parseContext) matchLanguage(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchLanguage(line) +} + +func (ctxt *parseContext) isMatchOther(line *Line) bool { + ok, _, _ := ctxt.matchOther(line) + return ok +} +func (ctxt *parseContext) matchOther(line *Line) (bool, *Token, error) { + if line.IsEof() { + return false, nil, nil + } + return ctxt.m.MatchOther(line) +} + +func (ctxt *parseContext) lookahead0(initialLine *Line) bool { + var queue []*scanResult + var match bool + + for { + line, atEof, err := ctxt.scan() + queue = append(queue, &scanResult{line, atEof, err}) + + if false || ctxt.isMatchScenarioLine(line) { + match = true + break + } + if !(false || ctxt.isMatchEmpty(line) || ctxt.isMatchComment(line) || ctxt.isMatchTagLine(line)) { + break + } + if atEof { + break + } + } + + ctxt.queue = append(ctxt.queue, queue...) + + return match +} + +func (ctxt *parseContext) lookahead1(initialLine *Line) bool { + var queue []*scanResult + var match bool + + for { + line, atEof, err := ctxt.scan() + queue = append(queue, &scanResult{line, atEof, err}) + + if false || ctxt.isMatchExamplesLine(line) { + match = true + break + } + if !(false || ctxt.isMatchEmpty(line) || ctxt.isMatchComment(line) || ctxt.isMatchTagLine(line)) { + break + } + if atEof { + break + } + } + + ctxt.queue = append(ctxt.queue, queue...) + + return match +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/parser.go.razor b/vendor/github.com/cucumber/gherkin/go/v42/parser.go.razor new file mode 100644 index 0000000000..2e772d8a95 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/parser.go.razor @@ -0,0 +1,313 @@ +@using Berp; +@helper CallProduction(ProductionRule production) +{ + switch(production.Type) + { + case ProductionRuleType.Start: + @:ctxt.startRule(@Raw("RuleType" + production.RuleName.Replace("#", ""))) + break; + case ProductionRuleType.End: + @:ctxt.endRule(@Raw("RuleType" + production.RuleName.Replace("#", ""))) + break; + case ProductionRuleType.Process: + @:ctxt.build(token) + break; + } +} +@helper HandleParserError(IEnumerable expectedTokens, State state) +{ + // var stateComment = "State: @state.Id - @Raw(state.Comment)" + var expectedTokens = []string{"@Raw(string.Join("\", \"", expectedTokens))"} + if line.IsEof() { + err = &parseError{ + msg: fmt.Sprintf("unexpected end of file, expected: %s", strings.Join(expectedTokens, ", ")), + loc: &Location{Line: line.LineNumber, Column: 0}, + } + } else { + err = &parseError{ + msg: fmt.Sprintf("expected: %s, got '%s'", strings.Join(expectedTokens, ", "), line.LineText), + loc: &Location{Line: line.LineNumber, Column: line.Indent() + 1}, + } + } + // if (ctxt.p.stopAtFirstError) throw error; + //ctxt.addError(err) + return @state.Id, err +} +@helper MatchToken(TokenType tokenType) +{ctxt.match@(tokenType)(line)} +@helper IsMatchToken(TokenType tokenType) +{ctxt.isMatch@(tokenType)(line)} +@helper TokenConst(Rule rule) +{@Raw("rule" + rule.Name.Replace("#", "Int"))} +// +// This file is generated. Do not edit! Edit parser.go.razor instead. + +package gherkin + +import ( + "fmt" + "strings" +) + +type TokenType int + +const ( + TokenTypeNone TokenType = iota + @foreach(var rule in Model.RuleSet.TokenRules) +{ @Raw("TokenType" + rule.Name.Replace("#", "")) +} +) + +func tokenTypeForRule(rt RuleType) TokenType { + return TokenTypeNone +} + +func (t TokenType) Name() string { + switch t { + @foreach(var rule in Model.RuleSet.TokenRules) +{ case @Raw("TokenType" + rule.Name.Replace("#", "")): + return "@Raw(rule.Name.Replace("#", ""))" +} + } + return "" +} + +func (t TokenType) RuleType() RuleType { + switch t { + @foreach(var rule in Model.RuleSet.TokenRules) +{ case @Raw("TokenType" + rule.Name.Replace("#", "")): + return @Raw("RuleType" + rule.Name.Replace("#", "")) +} + } + return RuleTypeNone +} + +type RuleType int + +const ( + RuleTypeNone RuleType = iota + @foreach(var rule in Model.RuleSet.Where(r => !r.TempRule)) +{ @Raw("RuleType" + rule.Name.Replace("#", "")) +} +) + +func (t RuleType) IsEOF() bool { + return t == RuleTypeEOF +} +func (t RuleType) Name() string { + switch t { + @foreach(var rule in Model.RuleSet.Where(r => !r.TempRule)) +{ case @Raw("RuleType" + rule.Name.Replace("#", "")): + return "@Raw(rule.Name)" +} + } + return "" +} + +type Location struct { + Line int + Column int +} + +type parseError struct { + msg string + loc *Location +} + +func (a *parseError) Error() string { + return fmt.Sprintf("(%d:%d): %s", a.loc.Line, a.loc.Column, a.msg) +} + +type parseErrors []error + +func (pe parseErrors) Error() string { + var ret = []string{"Parser errors:"} + for i := range pe { + ret = append(ret, pe[i].Error()) + } + return strings.Join(ret, "\n") +} + +func (p *parser) Parse(s Scanner, m Matcher) (err error) { + p.builder.Reset() + m.Reset() + ctxt := &parseContext{p, s, p.builder, m, nil, nil} + var state int + ctxt.startRule(@Raw("RuleType" + @Model.RuleSet.StartRule.Name)) + for { + gl, eof, err := ctxt.scan() + if err != nil { + ctxt.addError(err) + if p.stopAtFirstError { + break + } + } + state, err = ctxt.match(state, gl) + if err != nil { + ctxt.addError(err) + if p.stopAtFirstError { + break + } + } + if eof { + // done! \o/ + break + } + } + ctxt.endRule(@Raw("RuleType" + @Model.RuleSet.StartRule.Name)) + if len(ctxt.errors) > 0 { + return ctxt.errors + } + return +} + +type parseContext struct { + p *parser + s Scanner + b Builder + m Matcher + queue []*scanResult + errors parseErrors +} + +func (ctxt *parseContext) addError(e error) { + ctxt.errors = append(ctxt.errors, e) + // if (p.errors.length > 10) + // throw Errors.CompositeParserException.create(p.errors); +} + +type scanResult struct { + line *Line + atEof bool + err error +} + +func (ctxt *parseContext) scan() (*Line, bool, error) { + l := len(ctxt.queue) + if l > 0 { + x := ctxt.queue[0] + ctxt.queue = ctxt.queue[1:] + return x.line, x.atEof, x.err + } + return ctxt.s.Scan() +} + +func (ctxt *parseContext) startRule(r RuleType) (bool, error) { + ok, err := ctxt.b.StartRule(r) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) endRule(r RuleType) (bool, error) { + ok, err := ctxt.b.EndRule(r) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) build(t *Token) (bool, error) { + ok, err := ctxt.b.Build(t) + if err != nil { + ctxt.addError(err) + } + return ok, err +} + +func (ctxt *parseContext) match(state int, line *Line) (newState int, err error) { + switch state { + @foreach(var state in Model.States.Values.Where(s => !s.IsEndState)) + { + @:case @state.Id: + @:return ctxt.matchAt@(state.Id)(line) + } + default: + return state, fmt.Errorf("Unknown state: %+v", state) + } +} +@foreach(var state in Model.States.Values.Where(s => !s.IsEndState)) +{ + +// @Raw(state.Comment) +func (ctxt *parseContext) matchAt@(state.Id)(line *Line) (newState int, err error) { + @foreach(var transition in state.Transitions) + { + @:if ok, token, err := @MatchToken(transition.TokenType); ok { + if (transition.LookAheadHint != null) + { + @:if ctxt.lookahead@(transition.LookAheadHint.Id)(line) { + foreach(var production in transition.Productions) + { + @CallProduction(production) + } + @:return @transition.TargetState, err + @:} + } else { + foreach(var production in transition.Productions) + { + @CallProduction(production) + } + @:return @transition.TargetState, err + } + @:} + } + @HandleParserError(state.Transitions.Select(t => "#" + t.TokenType.ToString()).Distinct(), state) +} + +} + +type Matcher interface { + @foreach(var rule in Model.RuleSet.TokenRules) + { Match@(rule.Name.Replace("#", ""))(line *Line) (bool, *Token, error) +} + Reset() +} +@foreach(var rule in Model.RuleSet.TokenRules) +{ + +func (ctxt *parseContext) isMatch@(rule.Name.Replace("#", ""))(line *Line) bool { + ok, _, _ := ctxt.match@(rule.Name.Replace("#", ""))(line) + return ok +} +func (ctxt *parseContext) match@(rule.Name.Replace("#", ""))(line *Line) (bool, *Token, error) { + @if (rule.Name != "#EOF") + { + @:if line.IsEof() { + @: return false, nil, nil + @:} + } + return ctxt.m.Match@(rule.Name.Replace("#", ""))(line) +} + +} +@foreach(var lookAheadHint in Model.RuleSet.LookAheadHints) +{ + +func (ctxt *parseContext) lookahead@(lookAheadHint.Id)(initialLine *Line) bool { + var queue []*scanResult + var match bool + + for { + line, atEof, err := ctxt.scan() + queue = append(queue, &scanResult{line, atEof, err}) + + if @{false}@foreach(var tokenType in lookAheadHint.ExpectedTokens) { || @IsMatchToken(tokenType)} { + match = true + break + } + if !(@{false}@foreach(var tokenType in lookAheadHint.Skip) { || @IsMatchToken(tokenType)}) { + break + } + if atEof { + break + } + } + + ctxt.queue = append(ctxt.queue, queue...) + + return match +} + +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/pickles.go b/vendor/github.com/cucumber/gherkin/go/v42/pickles.go new file mode 100644 index 0000000000..ed38d0f7b0 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/pickles.go @@ -0,0 +1,291 @@ +package gherkin + +import ( + "strings" + + "github.com/cucumber/messages/go/v34" +) + +func Pickles(gherkinDocument messages.GherkinDocument, uri string, newId func() string) []*messages.Pickle { + pickles := make([]*messages.Pickle, 0) + if gherkinDocument.Feature == nil { + return pickles + } + language := gherkinDocument.Feature.Language + + pickles = compileFeature(pickles, *gherkinDocument.Feature, uri, language, newId) + return pickles +} + +func compileFeature(pickles []*messages.Pickle, feature messages.Feature, uri string, language string, newId func() string) []*messages.Pickle { + featureBackgroundSteps := make([]*messages.Step, 0) + featureTags := feature.Tags + for _, child := range feature.Children { + if child.Background != nil { + featureBackgroundSteps = append(featureBackgroundSteps, child.Background.Steps...) + } + if child.Rule != nil { + pickles = compileRule(pickles, child.Rule, featureTags, featureBackgroundSteps, uri, language, newId) + } + if child.Scenario != nil { + if len(child.Scenario.Examples) == 0 { + pickles = compileScenario(pickles, featureBackgroundSteps, child.Scenario, featureTags, uri, language, newId) + } else { + pickles = compileScenarioOutline(pickles, child.Scenario, featureTags, featureBackgroundSteps, uri, language, newId) + } + } + } + return pickles +} + +func compileRule( + pickles []*messages.Pickle, + rule *messages.Rule, + featureTags []*messages.Tag, + featureBackgroundSteps []*messages.Step, + uri string, + language string, + newId func() string, +) []*messages.Pickle { + ruleBackgroundSteps := make([]*messages.Step, 0) + ruleBackgroundSteps = append(ruleBackgroundSteps, featureBackgroundSteps...) + tags := append(featureTags, rule.Tags...) + + for _, child := range rule.Children { + if child.Background != nil { + ruleBackgroundSteps = append(ruleBackgroundSteps, child.Background.Steps...) + } + if child.Scenario != nil { + if len(child.Scenario.Examples) == 0 { + pickles = compileScenario(pickles, ruleBackgroundSteps, child.Scenario, tags, uri, language, newId) + } else { + pickles = compileScenarioOutline(pickles, child.Scenario, tags, ruleBackgroundSteps, uri, language, newId) + } + } + } + return pickles + +} + +func compileScenarioOutline( + pickles []*messages.Pickle, + scenario *messages.Scenario, + inheritedTags []*messages.Tag, + backgroundSteps []*messages.Step, + uri string, + language string, + newId func() string, +) []*messages.Pickle { + for _, examples := range scenario.Examples { + if examples.TableHeader == nil { + continue + } + variableCells := examples.TableHeader.Cells + for _, valuesRow := range examples.TableBody { + valueCells := valuesRow.Cells + + computedPickleSteps := make([]*messages.PickleStep, 0) + pickleBackgroundSteps := make([]*messages.PickleStep, 0) + + if len(scenario.Steps) > 0 { + pickleBackgroundSteps = pickleSteps(backgroundSteps, newId) + } + + // translate computedPickleSteps based on valuesRow + previous := messages.PickleStepType_UNKNOWN + for _, step := range scenario.Steps { + text := step.Text + for i, variableCell := range variableCells { + text = strings.Replace(text, "<"+variableCell.Value+">", valueCells[i].Value, -1) + } + + pickleStep := pickleStep(step, variableCells, valuesRow, newId, previous) + previous = pickleStep.Type + computedPickleSteps = append(computedPickleSteps, pickleStep) + } + + // translate pickle name + name := scenario.Name + for i, key := range variableCells { + name = strings.Replace(name, "<"+key.Value+">", valueCells[i].Value, -1) + } + + if len(computedPickleSteps) > 0 { + computedPickleSteps = append(pickleBackgroundSteps, computedPickleSteps...) + } + + id := newId() + tags := pickleTags(append(inheritedTags, append(scenario.Tags, examples.Tags...)...)) + + pickles = append(pickles, &messages.Pickle{ + Id: id, + Uri: uri, + Location: valuesRow.Location, + Steps: computedPickleSteps, + Tags: tags, + Name: name, + Language: language, + AstNodeIds: []string{scenario.Id, valuesRow.Id}, + }) + } + } + return pickles +} + +func compileScenario( + pickles []*messages.Pickle, + backgroundSteps []*messages.Step, + scenario *messages.Scenario, + inheritedTags []*messages.Tag, + uri string, + language string, + newId func() string, +) []*messages.Pickle { + steps := make([]*messages.PickleStep, 0) + if len(scenario.Steps) > 0 { + pickleBackgroundSteps := pickleSteps(backgroundSteps, newId) + steps = append(pickleBackgroundSteps, pickleSteps(scenario.Steps, newId)...) + } + tags := pickleTags(append(inheritedTags, scenario.Tags...)) + id := newId() + pickles = append(pickles, &messages.Pickle{ + Id: id, + Uri: uri, + Location: scenario.Location, + Steps: steps, + Tags: tags, + Name: scenario.Name, + Language: language, + AstNodeIds: []string{scenario.Id}, + }) + return pickles +} + +func pickleDataTable(table *messages.DataTable, variableCells []*messages.TableCell, valueCells []*messages.TableCell) *messages.PickleTable { + pickleTableRows := make([]*messages.PickleTableRow, len(table.Rows)) + for i, row := range table.Rows { + pickleTableCells := make([]*messages.PickleTableCell, len(row.Cells)) + for j, cell := range row.Cells { + pickleTableCells[j] = &messages.PickleTableCell{ + Value: interpolate(cell.Value, variableCells, valueCells), + } + } + pickleTableRows[i] = &messages.PickleTableRow{Cells: pickleTableCells} + } + return &messages.PickleTable{ + Rows: pickleTableRows, + } +} + +func pickleDocString(docString *messages.DocString, variableCells []*messages.TableCell, valueCells []*messages.TableCell) *messages.PickleDocString { + return &messages.PickleDocString{ + MediaType: interpolate(docString.MediaType, variableCells, valueCells), + Content: interpolate(docString.Content, variableCells, valueCells), + } +} + +func pickleTags(tags []*messages.Tag) []*messages.PickleTag { + ptags := make([]*messages.PickleTag, len(tags)) + for i, tag := range tags { + ptags[i] = &messages.PickleTag{ + Name: tag.Name, + AstNodeId: tag.Id, + } + } + return ptags +} + +func pickleSteps(steps []*messages.Step, newId func() string) []*messages.PickleStep { + pickleSteps := make([]*messages.PickleStep, len(steps)) + previous := messages.PickleStepType_UNKNOWN + for i, step := range steps { + pickleStep := pickleStep(step, nil, nil, newId, previous) + previous = pickleStep.Type + pickleSteps[i] = pickleStep + } + return pickleSteps +} + +func pickleStep( + step *messages.Step, + variableCells []*messages.TableCell, + valuesRow *messages.TableRow, + newId func() string, + previous messages.PickleStepType, +) *messages.PickleStep { + + var valueCells []*messages.TableCell + if valuesRow != nil { + valueCells = valuesRow.Cells + } + + pickleStep := &messages.PickleStep{ + Id: newId(), + Text: interpolate(step.Text, variableCells, valueCells), + Type: mapType(step.KeywordType, previous), + AstNodeIds: []string{step.Id}, + } + if valuesRow != nil { + pickleStep.AstNodeIds = append(pickleStep.AstNodeIds, valuesRow.Id) + } + pickleStep.Argument = pickleStepArgument(step, variableCells, valueCells) + return pickleStep +} + +func pickleStepArgument(step *messages.Step, variableCells []*messages.TableCell, valueCells []*messages.TableCell) *messages.PickleStepArgument { + dataTable := step.DataTable + docString := step.DocString + + if dataTable != nil && docString != nil { + pickleStepArgument := &messages.PickleStepArgument{ + DocString: pickleDocString(docString, variableCells, valueCells), + DataTable: pickleDataTable(dataTable, variableCells, valueCells), + } + if docString.Location.Line > dataTable.Location.Line { + pickleStepArgument.DataTable.ArgumentIndex = int64(1) + pickleStepArgument.DocString.ArgumentIndex = int64(2) + } else { + pickleStepArgument.DataTable.ArgumentIndex = int64(2) + pickleStepArgument.DocString.ArgumentIndex = int64(1) + } + return pickleStepArgument + } else if dataTable != nil { + return &messages.PickleStepArgument{ + DataTable: pickleDataTable(dataTable, variableCells, valueCells), + } + } else if docString != nil { + return &messages.PickleStepArgument{ + DocString: pickleDocString(docString, variableCells, valueCells), + } + } + return nil +} + +func mapType(keywordType messages.StepKeywordType, previous messages.PickleStepType) messages.PickleStepType { + switch keywordType { + case messages.StepKeywordType_UNKNOWN: + return messages.PickleStepType_UNKNOWN + case messages.StepKeywordType_CONTEXT: + return messages.PickleStepType_CONTEXT + case messages.StepKeywordType_ACTION: + return messages.PickleStepType_ACTION + case messages.StepKeywordType_OUTCOME: + return messages.PickleStepType_OUTCOME + case messages.StepKeywordType_CONJUNCTION: + return previous + default: + panic("Bad enum value for StepKeywordType") + } +} + +func interpolate(s string, variableCells []*messages.TableCell, valueCells []*messages.TableCell) string { + if variableCells == nil || valueCells == nil { + return s + } + + for i, variableCell := range variableCells { + s = strings.Replace(s, "<"+variableCell.Value+">", valueCells[i].Value, -1) + } + + return s +} diff --git a/vendor/github.com/cucumber/gherkin/go/v42/test.feature b/vendor/github.com/cucumber/gherkin/go/v42/test.feature new file mode 100644 index 0000000000..dff77a22b7 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/test.feature @@ -0,0 +1,151 @@ +Feature: + + Scenario: scenario 1 + Given text + + Scenario: scenario 2 + Given text + + Scenario: scenario 3 + Given text + + Scenario: scenario 4 + Given text + + Scenario: scenario 5 + Given text + + Scenario: scenario 6 + Given text + + Scenario: scenario 7 + Given text + + Scenario: scenario 8 + Given text + + Scenario: scenario 9 + Given text + + Scenario: scenario 10 + Given text + + Scenario: scenario 11 + Given text + + Scenario: scenario 12 + Given text + + Scenario: scenario 13 + Given text + + Scenario: scenario 14 + Given text + + Scenario: scenario 15 + Given text + + Scenario: scenario 16 + Given text + + Scenario: scenario 17 + Given text + + Scenario: scenario 18 + Given text + + Scenario: scenario 19 + Given text + + Scenario: scenario 20 + Given text + + Scenario: scenario 21 + Given text + + Scenario: scenario 22 + Given text + + Scenario: scenario 23 + Given text + + Scenario: scenario 24 + Given text + + Scenario: scenario 25 + Given text + + Scenario: scenario 26 + Given text + + Scenario: scenario 27 + Given text + + Scenario: scenario 28 + Given text + + Scenario: scenario 29 + Given text + + Scenario: scenario 30 + Given text + + Scenario: scenario 31 + Given text + + Scenario: scenario 32 + Given text + + Scenario: scenario 33 + Given text + + Scenario: scenario 34 + Given text + + Scenario: scenario 35 + Given text + + Scenario: scenario 36 + Given text + + Scenario: scenario 37 + Given text + + Scenario: scenario 38 + Given text + + Scenario: scenario 39 + Given text + + Scenario: scenario 40 + Given text + + Scenario: scenario 41 + Given text + + Scenario: scenario 42 + Given text + + Scenario: scenario 43 + Given text + + Scenario: scenario 44 + Given text + + Scenario: scenario 45 + Given text + + Scenario: scenario 46 + Given text + + Scenario: scenario 47 + Given text + + Scenario: scenario 48 + Given text + + Scenario: scenario 49 + Given text + + Scenario: scenario 50 + Given text diff --git a/vendor/github.com/cucumber/gherkin/go/v42/test.sh b/vendor/github.com/cucumber/gherkin/go/v42/test.sh new file mode 100644 index 0000000000..97debf6479 --- /dev/null +++ b/vendor/github.com/cucumber/gherkin/go/v42/test.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +./bin/gherkin --no-ast --no-pickles test.feature | ./bin/gherkin --no-source --no-ast --json diff --git a/vendor/github.com/cucumber/godog/CHANGELOG.md b/vendor/github.com/cucumber/godog/CHANGELOG.md index 21a323e0ab..2cb9b01db6 100644 --- a/vendor/github.com/cucumber/godog/CHANGELOG.md +++ b/vendor/github.com/cucumber/godog/CHANGELOG.md @@ -8,6 +8,15 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ## Unreleased +## [v0.16.0] + +### Changed +- Upgrade `cucumber/messages` to v34 and `cucumber/gherkin` to v42 - ([764](https://github.com/cucumber/godog/pull/764) - [vearutop](https://github.com/vearutop)) +- Require Go 1.18, tidy example module - ([741](https://github.com/cucumber/godog/pull/741) - [vearutop](https://github.com/vearutop)) + +### Fixed +- fix(hooks): wrap errors to preserve sentinel values - ([760](https://github.com/cucumber/godog/pull/760) - [victoriacheng15](https://github.com/victoriacheng15)) + ## [v0.15.1] ### Added @@ -27,6 +36,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt - fix: change bang to being in README by @nahomEagleLion in https://github.com/cucumber/godog/pull/687 - Mark junit test cases as skipped if no pickle step results available by @mrsheepuk in https://github.com/cucumber/godog/pull/597 - Print step declaration line instead of handler declaration line by @SpencerC in https://github.com/cucumber/godog/pull/668 +- fix(tags): the , operator was not working as an OR operator in the tags by @kcross-ctoken in https://github.com/cucumber/godog/pull/740 ## [v0.15.0] @@ -261,6 +271,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ### Changed - Changed code references to DATA-DOG/godog to cucumber/godog to help get things building correctly. ([mxygem](https://github.com/mxygem)) +[v0.16.0]: https://github.com/cucumber/godog/compare/v0.15.1...v0.16.0 [v0.15.1]: https://github.com/cucumber/godog/compare/v0.15.0...v0.15.1 [v0.15.0]: https://github.com/cucumber/godog/compare/v0.14.1...v0.15.0 [v0.14.1]: https://github.com/cucumber/godog/compare/v0.14.0...v0.14.1 diff --git a/vendor/github.com/cucumber/godog/LICENSE b/vendor/github.com/cucumber/godog/LICENSE index 97dcbd65f4..d620a7bec0 100644 --- a/vendor/github.com/cucumber/godog/LICENSE +++ b/vendor/github.com/cucumber/godog/LICENSE @@ -1,4 +1,4 @@ -The MIT License (MIT) +MIT License Copyright (c) SmartBear diff --git a/vendor/github.com/cucumber/godog/README.md b/vendor/github.com/cucumber/godog/README.md index dceacf1673..720fd12dc3 100644 --- a/vendor/github.com/cucumber/godog/README.md +++ b/vendor/github.com/cucumber/godog/README.md @@ -1,9 +1,10 @@ + + [![#StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine) [![Build Status](https://github.com/cucumber/godog/workflows/test/badge.svg)](https://github.com/cucumber/godog/actions?query=branch%main+workflow%3Atest) [![PkgGoDev](https://pkg.go.dev/badge/github.com/cucumber/godog)](https://pkg.go.dev/github.com/cucumber/godog) [![codecov](https://codecov.io/gh/cucumber/godog/branch/master/graph/badge.svg)](https://codecov.io/gh/cucumber/godog) -[![pull requests](https://oselvar.com/api/badge?label=pull%20requests&csvUrl=https%3A%2F%2Fraw.githubusercontent.com%2Fcucumber%2Foselvar-github-metrics%2Fmain%2Fdata%2Fcucumber%2Fgodog%2FpullRequests.csv)](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/godog) -[![issues](https://oselvar.com/api/badge?label=issues&csvUrl=https%3A%2F%2Fraw.githubusercontent.com%2Fcucumber%2Foselvar-github-metrics%2Fmain%2Fdata%2Fcucumber%2Fgodog%2Fissues.csv)](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/godog) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/cucumber/godog/badge)](https://scorecard.dev/viewer/?uri=github.com/cucumber/godog) # Godog diff --git a/vendor/github.com/cucumber/godog/flags.go b/vendor/github.com/cucumber/godog/flags.go index 45efbfec74..e6a99c3d20 100644 --- a/vendor/github.com/cucumber/godog/flags.go +++ b/vendor/github.com/cucumber/godog/flags.go @@ -208,7 +208,7 @@ func usage(set *flag.FlagSet, w io.Writer) func() { // --- GENERAL --- fmt.Fprintln(w, colors.Yellow("Usage:")) - fmt.Fprintf(w, s(2)+"go test [options]\n\n") + fmt.Fprint(w, s(2)+"go test [options]\n\n") // --- OPTIONS --- fmt.Fprintln(w, colors.Yellow("Options:")) diff --git a/vendor/github.com/cucumber/godog/formatters/fmt.go b/vendor/github.com/cucumber/godog/formatters/fmt.go index 973cf11b83..3a7171ad02 100644 --- a/vendor/github.com/cucumber/godog/formatters/fmt.go +++ b/vendor/github.com/cucumber/godog/formatters/fmt.go @@ -4,7 +4,7 @@ import ( "io" "regexp" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) type registeredFormatter struct { diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt.go index 5530c0c243..264df4c8fd 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/colors" "github.com/cucumber/godog/internal/models" diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go index 607a1c0656..77b0ea826f 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_base.go @@ -11,7 +11,7 @@ import ( "sync" "unicode" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/colors" "github.com/cucumber/godog/formatters" @@ -204,6 +204,22 @@ func (f *Base) Summary() { } } +func asciiTitle(s string) string { + var b strings.Builder + b.Grow(len(s)) + + newWord := true + for i := 0; i < len(s); i++ { + c := s[i] + if ('a' <= c && c <= 'z') && newWord { + c -= 'a' - 'A' + } + b.WriteByte(c) + newWord = !('0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z') + } + return b.String() +} + // Snippets returns code suggestions for undefined steps. func (f *Base) Snippets() string { undefinedStepResults := f.Storage.MustGetPickleStepResultsByStatus(undefined) @@ -236,7 +252,7 @@ func (f *Base) Snippets() string { for i, w := range strings.Split(name, " ") { switch { case i != 0: - w = strings.Title(w) + w = asciiTitle(w) case len(w) > 0: w = string(unicode.ToLower(rune(w[0]))) + w[1:] } diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go index 31380c9757..628e4dbfc4 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_cucumber.go @@ -21,7 +21,7 @@ import ( "github.com/cucumber/godog/formatters" "github.com/cucumber/godog/internal/models" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) func init() { diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go index c5ffcb50e1..bfecb4caba 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_events.go @@ -7,7 +7,7 @@ import ( "github.com/cucumber/godog/formatters" "github.com/cucumber/godog/internal/utils" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) const nanoSec = 1000000 diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_flushwrap.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_flushwrap.go index 129b062100..93cd63938c 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_flushwrap.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_flushwrap.go @@ -4,7 +4,7 @@ import ( "sync" "github.com/cucumber/godog/formatters" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) // WrapOnFlush wrap a `formatters.Formatter` in a `formatters.FlushFormatter`, which only diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go index 001c998096..d929fdd519 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_multi.go @@ -5,7 +5,7 @@ import ( "github.com/cucumber/godog/formatters" "github.com/cucumber/godog/internal/storage" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) // MultiFormatter passes test progress to multiple formatters. diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go index 76d733793c..f27533c823 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_pretty.go @@ -8,7 +8,7 @@ import ( "strings" "unicode/utf8" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/colors" "github.com/cucumber/godog/formatters" diff --git a/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go b/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go index 9722ef7a5c..c6ec25861d 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/fmt_progress.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/cucumber/godog/formatters" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) func init() { @@ -42,7 +42,7 @@ func (f *Progress) Summary() { left := math.Mod(float64(*f.Steps), float64(f.StepsPerRow)) if left != 0 { if *f.Steps > f.StepsPerRow { - fmt.Fprintf(f.out, s(f.StepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.Steps)) + fmt.Fprint(f.out, s(f.StepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.Steps)) } else { fmt.Fprintf(f.out, " %d\n", *f.Steps) } diff --git a/vendor/github.com/cucumber/godog/internal/formatters/undefined_snippets_gen.go b/vendor/github.com/cucumber/godog/internal/formatters/undefined_snippets_gen.go index ff6cd79ef7..e639abd807 100644 --- a/vendor/github.com/cucumber/godog/internal/formatters/undefined_snippets_gen.go +++ b/vendor/github.com/cucumber/godog/internal/formatters/undefined_snippets_gen.go @@ -7,7 +7,7 @@ import ( "strings" "text/template" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) // some snippet formatting regexps diff --git a/vendor/github.com/cucumber/godog/internal/models/feature.go b/vendor/github.com/cucumber/godog/internal/models/feature.go index 9d9d84da70..bc68d46b5a 100644 --- a/vendor/github.com/cucumber/godog/internal/models/feature.go +++ b/vendor/github.com/cucumber/godog/internal/models/feature.go @@ -1,7 +1,7 @@ package models import ( - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) // Feature is an internal object to group together diff --git a/vendor/github.com/cucumber/godog/internal/models/stepdef.go b/vendor/github.com/cucumber/godog/internal/models/stepdef.go index 7c2e973ac4..7e6c83ed9e 100644 --- a/vendor/github.com/cucumber/godog/internal/models/stepdef.go +++ b/vendor/github.com/cucumber/godog/internal/models/stepdef.go @@ -7,7 +7,7 @@ import ( "reflect" "strconv" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/formatters" ) diff --git a/vendor/github.com/cucumber/godog/internal/parser/parser.go b/vendor/github.com/cucumber/godog/internal/parser/parser.go index f607000aa2..7f0da672c5 100644 --- a/vendor/github.com/cucumber/godog/internal/parser/parser.go +++ b/vendor/github.com/cucumber/godog/internal/parser/parser.go @@ -10,8 +10,8 @@ import ( "strconv" "strings" - gherkin "github.com/cucumber/gherkin/go/v26" - messages "github.com/cucumber/messages/go/v21" + gherkin "github.com/cucumber/gherkin/go/v42" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/internal/flags" "github.com/cucumber/godog/internal/models" diff --git a/vendor/github.com/cucumber/godog/internal/storage/storage.go b/vendor/github.com/cucumber/godog/internal/storage/storage.go index 72b7e86f7f..474cfc880e 100644 --- a/vendor/github.com/cucumber/godog/internal/storage/storage.go +++ b/vendor/github.com/cucumber/godog/internal/storage/storage.go @@ -4,7 +4,7 @@ import ( "fmt" "sync" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/hashicorp/go-memdb" "github.com/cucumber/godog/internal/models" diff --git a/vendor/github.com/cucumber/godog/internal/tags/tag_filter.go b/vendor/github.com/cucumber/godog/internal/tags/tag_filter.go index 72b4512b4f..0672edc2db 100644 --- a/vendor/github.com/cucumber/godog/internal/tags/tag_filter.go +++ b/vendor/github.com/cucumber/godog/internal/tags/tag_filter.go @@ -3,7 +3,7 @@ package tags import ( "strings" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" ) // ApplyTagFilter will apply a filter string on the @@ -25,28 +25,28 @@ func ApplyTagFilter(filter string, pickles []*messages.Pickle) []*messages.Pickl } // Based on http://behat.readthedocs.org/en/v2.5/guides/6.cli.html#gherkin-filters -func match(filter string, tags []*messages.PickleTag) (ok bool) { - ok = true - - for _, andTags := range strings.Split(filter, "&&") { - var okComma bool - - for _, tag := range strings.Split(andTags, ",") { - tag = strings.TrimSpace(tag) - tag = strings.Replace(tag, "@", "", -1) +func match(filters string, tags []*messages.PickleTag) (ok bool) { + ok = false + for _, filter := range strings.Split(filters, ",") { + ok = matchAnd(filter, tags) || ok + } - okComma = contains(tags, tag) || okComma + return +} - if tag[0] == '~' { - tag = tag[1:] - okComma = !contains(tags, tag) || okComma - } +func matchAnd(filter string, tags []*messages.PickleTag) bool { + and := len(filter) > 0 + for _, tag := range strings.Split(filter, "&&") { + tag = strings.TrimSpace(tag) + tag = strings.Replace(tag, "@", "", -1) + if tag[0] == '~' { + tag = tag[1:] + and = !contains(tags, tag) && and + } else { + and = contains(tags, tag) && and } - - ok = ok && okComma } - - return + return and } func contains(tags []*messages.PickleTag, tag string) bool { diff --git a/vendor/github.com/cucumber/godog/run.go b/vendor/github.com/cucumber/godog/run.go index 1231d02861..6b383492de 100644 --- a/vendor/github.com/cucumber/godog/run.go +++ b/vendor/github.com/cucumber/godog/run.go @@ -16,7 +16,7 @@ import ( "sync" "testing" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/colors" "github.com/cucumber/godog/formatters" diff --git a/vendor/github.com/cucumber/godog/suite.go b/vendor/github.com/cucumber/godog/suite.go index 6ca1bf53d5..616419e35c 100644 --- a/vendor/github.com/cucumber/godog/suite.go +++ b/vendor/github.com/cucumber/godog/suite.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/formatters" "github.com/cucumber/godog/internal/models" @@ -304,7 +304,7 @@ func (s *suite) runBeforeStepHooks(ctx context.Context, step *Step, err error) ( if err == nil { err = herr } else { - err = fmt.Errorf("%v, %w", herr, err) + err = mergeErrors(herr, err) } } @@ -329,7 +329,7 @@ func (s *suite) runAfterStepHooks(ctx context.Context, step *Step, status StepRe if err == nil { err = herr } else { - err = fmt.Errorf("%v, %w", herr, err) + err = mergeErrors(herr, err) } } @@ -351,7 +351,7 @@ func (s *suite) runBeforeScenarioHooks(ctx context.Context, pickle *messages.Pic if err == nil { err = herr } else { - err = fmt.Errorf("%v, %w", herr, err) + err = mergeErrors(herr, err) } } @@ -389,7 +389,7 @@ func (s *suite) runAfterScenarioHooks(ctx context.Context, pickle *messages.Pick err = fmt.Errorf("step error: %w", err) isStepErr = false } - err = fmt.Errorf("%v, %w", herr, err) + err = mergeErrors(herr, err) } } @@ -649,3 +649,34 @@ func (s *suite) runPickle(pickle *messages.Pickle) (err error) { return err } + +type joinedError struct { + err1 error + err2 error +} + +func (e *joinedError) Error() string { + return fmt.Sprintf("%v, %v", e.err1, e.err2) +} + +func (e *joinedError) Unwrap() []error { + return []error{e.err1, e.err2} +} + +func (e *joinedError) Is(target error) bool { + return errors.Is(e.err1, target) || errors.Is(e.err2, target) +} + +func (e *joinedError) As(target interface{}) bool { + return errors.As(e.err1, target) || errors.As(e.err2, target) +} + +func mergeErrors(err1, err2 error) error { + if err1 == nil { + return err2 + } + if err2 == nil { + return err1 + } + return &joinedError{err1: err1, err2: err2} +} diff --git a/vendor/github.com/cucumber/godog/test_context.go b/vendor/github.com/cucumber/godog/test_context.go index add9f47b07..9e974fbcd0 100644 --- a/vendor/github.com/cucumber/godog/test_context.go +++ b/vendor/github.com/cucumber/godog/test_context.go @@ -7,7 +7,7 @@ import ( "regexp" "runtime" - messages "github.com/cucumber/messages/go/v21" + messages "github.com/cucumber/messages/go/v34" "github.com/cucumber/godog/formatters" "github.com/cucumber/godog/internal/builder" @@ -237,6 +237,7 @@ func (ctx ScenarioContext) AfterStep(fn func(st *Step, err error)) { // // The stepFunc may accept one or several arguments of type: // - int, int8, int16, int32, int64 +// - uint, uint8, uint16, uint32, uint64 // - float32, float64 // - string // - []byte diff --git a/vendor/github.com/cucumber/godog/testingt.go b/vendor/github.com/cucumber/godog/testingt.go index 25981b89aa..40d81e0072 100644 --- a/vendor/github.com/cucumber/godog/testingt.go +++ b/vendor/github.com/cucumber/godog/testingt.go @@ -2,6 +2,7 @@ package godog import ( "context" + "errors" "fmt" "strings" "testing" @@ -183,9 +184,9 @@ func (dt *testingT) isFailed() error { } switch len(dt.failMessages) { case 0: - return fmt.Errorf("fail called on TestingT") + return errors.New("fail called on TestingT") case 1: - return fmt.Errorf(dt.failMessages[0]) + return errors.New(dt.failMessages[0]) default: return fmt.Errorf("checks failed:\n* %s", strings.Join(dt.failMessages, "\n* ")) } diff --git a/vendor/github.com/cucumber/messages/go/v34/.gitignore b/vendor/github.com/cucumber/messages/go/v34/.gitignore new file mode 100644 index 0000000000..7b0ee7aeb6 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/.gitignore @@ -0,0 +1,17 @@ +.built +.compared +.deps +.dist +.dist-compressed +.go-get +.gofmt +.linted +.tested* +acceptance/ +bin/ +dist/ +dist_compressed/ +*.bin +*.iml +# upx dist/cucumber-gherkin-openbsd-386 fails with a core dump +core.*.!usr!bin!upx-ucl diff --git a/vendor/github.com/cucumber/messages/go/v34/LICENSE b/vendor/github.com/cucumber/messages/go/v34/LICENSE new file mode 100644 index 0000000000..520b896f74 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Cucumber Ltd and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cucumber/messages/go/v34/Makefile b/vendor/github.com/cucumber/messages/go/v34/Makefile new file mode 100644 index 0000000000..35a777a414 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/Makefile @@ -0,0 +1,19 @@ +schemas = $(shell find ../jsonschema/src -name "*.schema.json") + +.DEFAULT_GOAL = help + +help: ## Show this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +generate: require messages.go ## Generate go code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation + +require: ## Check requirements for the code generation (ruby and go are required) + @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) + @go version >/dev/null 2>&1 || (echo "ERROR: go is required."; exit 1) + +clean: ## Remove automatically generated files and related artifacts + rm -f messages.go + +messages.go: $(schemas) ../codegen/codegen.rb ../codegen/templates/go.go.erb ../codegen/templates/go.enum.go.erb + ruby ../codegen/codegen.rb Generator::Go go.go.erb > $@ + ruby ../codegen/codegen.rb Generator::Go go.enum.go.erb >> $@ diff --git a/vendor/github.com/cucumber/messages/go/v34/id_generator.go b/vendor/github.com/cucumber/messages/go/v34/id_generator.go new file mode 100644 index 0000000000..e884e7fe68 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/id_generator.go @@ -0,0 +1,29 @@ +package messages + +import ( + "strconv" + + "github.com/google/uuid" +) + +type IdGenerator interface { + newId() func() string +} + +type Incrementing struct { + next int +} + +func (self *Incrementing) NewId() string { + result := strconv.Itoa(self.next) + self.next++ + return result +} + +type UUID struct { + next int +} + +func (i UUID) NewId() string { + return uuid.New().String() +} diff --git a/vendor/github.com/cucumber/messages/go/v34/messages.go b/vendor/github.com/cucumber/messages/go/v34/messages.go new file mode 100644 index 0000000000..52ab6d4317 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/messages.go @@ -0,0 +1,590 @@ +package messages + +type Attachment struct { + Body string `json:"body"` + ContentEncoding AttachmentContentEncoding `json:"contentEncoding"` + FileName string `json:"fileName,omitempty"` + MediaType string `json:"mediaType"` + Source *Source `json:"source,omitempty"` + TestCaseStartedId string `json:"testCaseStartedId,omitempty"` + TestStepId string `json:"testStepId,omitempty"` + Url string `json:"url,omitempty"` + TestRunStartedId string `json:"testRunStartedId,omitempty"` + TestRunHookStartedId string `json:"testRunHookStartedId,omitempty"` + Timestamp *Timestamp `json:"timestamp,omitempty"` +} + +type Duration struct { + Seconds int64 `json:"seconds"` + Nanos int64 `json:"nanos"` +} + +type Envelope struct { + Attachment *Attachment `json:"attachment,omitempty"` + ExternalAttachment *ExternalAttachment `json:"externalAttachment,omitempty"` + GherkinDocument *GherkinDocument `json:"gherkinDocument,omitempty"` + Hook *Hook `json:"hook,omitempty"` + Meta *Meta `json:"meta,omitempty"` + ParameterType *ParameterType `json:"parameterType,omitempty"` + ParseError *ParseError `json:"parseError,omitempty"` + Pickle *Pickle `json:"pickle,omitempty"` + Suggestion *Suggestion `json:"suggestion,omitempty"` + Source *Source `json:"source,omitempty"` + StepDefinition *StepDefinition `json:"stepDefinition,omitempty"` + TestCase *TestCase `json:"testCase,omitempty"` + TestCaseFinished *TestCaseFinished `json:"testCaseFinished,omitempty"` + TestCaseStarted *TestCaseStarted `json:"testCaseStarted,omitempty"` + TestRunFinished *TestRunFinished `json:"testRunFinished,omitempty"` + TestRunStarted *TestRunStarted `json:"testRunStarted,omitempty"` + TestStepFinished *TestStepFinished `json:"testStepFinished,omitempty"` + TestStepStarted *TestStepStarted `json:"testStepStarted,omitempty"` + TestRunHookStarted *TestRunHookStarted `json:"testRunHookStarted,omitempty"` + TestRunHookFinished *TestRunHookFinished `json:"testRunHookFinished,omitempty"` + UndefinedParameterType *UndefinedParameterType `json:"undefinedParameterType,omitempty"` +} + +type Exception struct { + Type string `json:"type"` + Message string `json:"message,omitempty"` + StackTrace string `json:"stackTrace,omitempty"` +} + +type ExternalAttachment struct { + Url string `json:"url"` + MediaType string `json:"mediaType"` + TestCaseStartedId string `json:"testCaseStartedId,omitempty"` + TestStepId string `json:"testStepId,omitempty"` + TestRunHookStartedId string `json:"testRunHookStartedId,omitempty"` + Timestamp *Timestamp `json:"timestamp,omitempty"` +} + +type GherkinDocument struct { + Uri string `json:"uri,omitempty"` + Feature *Feature `json:"feature,omitempty"` + Comments []*Comment `json:"comments"` +} + +type Background struct { + Location *Location `json:"location"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Description string `json:"description"` + Steps []*Step `json:"steps"` + Id string `json:"id"` +} + +type Comment struct { + Location *Location `json:"location"` + Text string `json:"text"` +} + +type DataTable struct { + Location *Location `json:"location"` + Rows []*TableRow `json:"rows"` +} + +type DocString struct { + Location *Location `json:"location"` + MediaType string `json:"mediaType,omitempty"` + Content string `json:"content"` + Delimiter string `json:"delimiter"` +} + +type Examples struct { + Location *Location `json:"location"` + Tags []*Tag `json:"tags"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Description string `json:"description"` + TableHeader *TableRow `json:"tableHeader,omitempty"` + TableBody []*TableRow `json:"tableBody"` + Id string `json:"id"` +} + +type Feature struct { + Location *Location `json:"location"` + Tags []*Tag `json:"tags"` + Language string `json:"language"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Description string `json:"description"` + Children []*FeatureChild `json:"children"` +} + +type FeatureChild struct { + Rule *Rule `json:"rule,omitempty"` + Background *Background `json:"background,omitempty"` + Scenario *Scenario `json:"scenario,omitempty"` +} + +type Rule struct { + Location *Location `json:"location"` + Tags []*Tag `json:"tags"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Description string `json:"description"` + Children []*RuleChild `json:"children"` + Id string `json:"id"` +} + +type RuleChild struct { + Background *Background `json:"background,omitempty"` + Scenario *Scenario `json:"scenario,omitempty"` +} + +type Scenario struct { + Location *Location `json:"location"` + Tags []*Tag `json:"tags"` + Keyword string `json:"keyword"` + Name string `json:"name"` + Description string `json:"description"` + Steps []*Step `json:"steps"` + Examples []*Examples `json:"examples"` + Id string `json:"id"` +} + +type Step struct { + Location *Location `json:"location"` + Keyword string `json:"keyword"` + KeywordType StepKeywordType `json:"keywordType,omitempty"` + Text string `json:"text"` + DocString *DocString `json:"docString,omitempty"` + DataTable *DataTable `json:"dataTable,omitempty"` + Id string `json:"id"` +} + +type TableCell struct { + Location *Location `json:"location"` + Value string `json:"value"` +} + +type TableRow struct { + Location *Location `json:"location"` + Cells []*TableCell `json:"cells"` + Id string `json:"id"` +} + +type Tag struct { + Location *Location `json:"location"` + Name string `json:"name"` + Id string `json:"id"` +} + +type Hook struct { + Id string `json:"id"` + Name string `json:"name,omitempty"` + SourceReference *SourceReference `json:"sourceReference"` + TagExpression string `json:"tagExpression,omitempty"` + Type HookType `json:"type,omitempty"` +} + +type Location struct { + Line int64 `json:"line"` + Column int64 `json:"column,omitempty"` +} + +type Meta struct { + ProtocolVersion string `json:"protocolVersion"` + Implementation *Product `json:"implementation"` + Runtime *Product `json:"runtime"` + Os *Product `json:"os"` + Cpu *Product `json:"cpu"` + Ci *Ci `json:"ci,omitempty"` +} + +type Ci struct { + Name string `json:"name"` + Url string `json:"url,omitempty"` + BuildNumber string `json:"buildNumber,omitempty"` + Git *Git `json:"git,omitempty"` +} + +type Git struct { + Remote string `json:"remote"` + Revision string `json:"revision"` + Branch string `json:"branch,omitempty"` + Tag string `json:"tag,omitempty"` +} + +type Product struct { + Name string `json:"name"` + Version string `json:"version,omitempty"` +} + +type ParameterType struct { + Name string `json:"name"` + RegularExpressions []string `json:"regularExpressions"` + PreferForRegularExpressionMatch bool `json:"preferForRegularExpressionMatch"` + UseForSnippets bool `json:"useForSnippets"` + Id string `json:"id"` + SourceReference *SourceReference `json:"sourceReference,omitempty"` +} + +type ParseError struct { + Source *SourceReference `json:"source"` + Message string `json:"message"` +} + +type Pickle struct { + Id string `json:"id"` + Uri string `json:"uri"` + Location *Location `json:"location,omitempty"` + Name string `json:"name"` + Language string `json:"language"` + Steps []*PickleStep `json:"steps"` + Tags []*PickleTag `json:"tags"` + AstNodeIds []string `json:"astNodeIds"` +} + +type PickleDocString struct { + ArgumentIndex int64 `json:"argumentIndex,omitempty"` + MediaType string `json:"mediaType,omitempty"` + Content string `json:"content"` +} + +type PickleStep struct { + Argument *PickleStepArgument `json:"argument,omitempty"` + AstNodeIds []string `json:"astNodeIds"` + Id string `json:"id"` + Type PickleStepType `json:"type,omitempty"` + Text string `json:"text"` +} + +type PickleStepArgument struct { + DocString *PickleDocString `json:"docString,omitempty"` + DataTable *PickleTable `json:"dataTable,omitempty"` +} + +type PickleTable struct { + ArgumentIndex int64 `json:"argumentIndex,omitempty"` + Rows []*PickleTableRow `json:"rows"` +} + +type PickleTableCell struct { + Value string `json:"value"` +} + +type PickleTableRow struct { + Cells []*PickleTableCell `json:"cells"` +} + +type PickleTag struct { + Name string `json:"name"` + AstNodeId string `json:"astNodeId"` +} + +type Source struct { + Uri string `json:"uri"` + Data string `json:"data"` + MediaType SourceMediaType `json:"mediaType"` +} + +type SourceReference struct { + Uri string `json:"uri,omitempty"` + JavaMethod *JavaMethod `json:"javaMethod,omitempty"` + JavaStackTraceElement *JavaStackTraceElement `json:"javaStackTraceElement,omitempty"` + Location *Location `json:"location,omitempty"` +} + +type JavaMethod struct { + ClassName string `json:"className"` + MethodName string `json:"methodName"` + MethodParameterTypes []string `json:"methodParameterTypes"` +} + +type JavaStackTraceElement struct { + ClassName string `json:"className"` + FileName string `json:"fileName"` + MethodName string `json:"methodName"` +} + +type StepDefinition struct { + Id string `json:"id"` + Pattern *StepDefinitionPattern `json:"pattern"` + SourceReference *SourceReference `json:"sourceReference"` +} + +type StepDefinitionPattern struct { + Source string `json:"source"` + Type StepDefinitionPatternType `json:"type"` +} + +type Suggestion struct { + Id string `json:"id"` + PickleStepId string `json:"pickleStepId"` + Snippets []*Snippet `json:"snippets"` +} + +type Snippet struct { + Language string `json:"language"` + Code string `json:"code"` +} + +type TestCase struct { + Id string `json:"id"` + PickleId string `json:"pickleId"` + TestSteps []*TestStep `json:"testSteps"` + TestRunStartedId string `json:"testRunStartedId,omitempty"` +} + +type Group struct { + Children []*Group `json:"children,omitempty"` + Start int64 `json:"start,omitempty"` + Value string `json:"value,omitempty"` +} + +type StepMatchArgument struct { + Group *Group `json:"group"` + ParameterTypeName string `json:"parameterTypeName,omitempty"` +} + +type StepMatchArgumentsList struct { + StepMatchArguments []*StepMatchArgument `json:"stepMatchArguments"` +} + +type TestStep struct { + HookId string `json:"hookId,omitempty"` + Id string `json:"id"` + PickleStepId string `json:"pickleStepId,omitempty"` + StepDefinitionIds []string `json:"stepDefinitionIds,omitempty"` + StepMatchArgumentsLists []*StepMatchArgumentsList `json:"stepMatchArgumentsLists,omitempty"` +} + +type TestCaseFinished struct { + TestCaseStartedId string `json:"testCaseStartedId"` + Timestamp *Timestamp `json:"timestamp"` + WillBeRetried bool `json:"willBeRetried"` +} + +type TestCaseStarted struct { + Attempt int64 `json:"attempt"` + Id string `json:"id"` + TestCaseId string `json:"testCaseId"` + WorkerId string `json:"workerId,omitempty"` + Timestamp *Timestamp `json:"timestamp"` +} + +type TestRunFinished struct { + Message string `json:"message,omitempty"` + Success bool `json:"success"` + Timestamp *Timestamp `json:"timestamp"` + Exception *Exception `json:"exception,omitempty"` + TestRunStartedId string `json:"testRunStartedId,omitempty"` +} + +type TestRunHookFinished struct { + TestRunHookStartedId string `json:"testRunHookStartedId"` + Result *TestStepResult `json:"result"` + Timestamp *Timestamp `json:"timestamp"` +} + +type TestRunHookStarted struct { + Id string `json:"id"` + TestRunStartedId string `json:"testRunStartedId"` + HookId string `json:"hookId"` + WorkerId string `json:"workerId,omitempty"` + Timestamp *Timestamp `json:"timestamp"` +} + +type TestRunStarted struct { + Timestamp *Timestamp `json:"timestamp"` + Id string `json:"id,omitempty"` +} + +type TestStepFinished struct { + TestCaseStartedId string `json:"testCaseStartedId"` + TestStepId string `json:"testStepId"` + TestStepResult *TestStepResult `json:"testStepResult"` + Timestamp *Timestamp `json:"timestamp"` +} + +type TestStepResult struct { + Duration *Duration `json:"duration"` + Message string `json:"message,omitempty"` + Status TestStepResultStatus `json:"status"` + Exception *Exception `json:"exception,omitempty"` +} + +type TestStepStarted struct { + TestCaseStartedId string `json:"testCaseStartedId"` + TestStepId string `json:"testStepId"` + Timestamp *Timestamp `json:"timestamp"` +} + +type Timestamp struct { + Seconds int64 `json:"seconds"` + Nanos int64 `json:"nanos"` +} + +type UndefinedParameterType struct { + Expression string `json:"expression"` + Name string `json:"name"` +} + +type AttachmentContentEncoding string + +const ( + AttachmentContentEncoding_IDENTITY AttachmentContentEncoding = "IDENTITY" + AttachmentContentEncoding_BASE64 AttachmentContentEncoding = "BASE64" +) + +func (e AttachmentContentEncoding) String() string { + switch e { + case AttachmentContentEncoding_IDENTITY: + return "IDENTITY" + case AttachmentContentEncoding_BASE64: + return "BASE64" + default: + panic("Bad enum value for AttachmentContentEncoding") + } +} + +type HookType string + +const ( + HookType_BEFORE_TEST_RUN HookType = "BEFORE_TEST_RUN" + HookType_AFTER_TEST_RUN HookType = "AFTER_TEST_RUN" + HookType_BEFORE_TEST_CASE HookType = "BEFORE_TEST_CASE" + HookType_AFTER_TEST_CASE HookType = "AFTER_TEST_CASE" + HookType_BEFORE_TEST_STEP HookType = "BEFORE_TEST_STEP" + HookType_AFTER_TEST_STEP HookType = "AFTER_TEST_STEP" +) + +func (e HookType) String() string { + switch e { + case HookType_BEFORE_TEST_RUN: + return "BEFORE_TEST_RUN" + case HookType_AFTER_TEST_RUN: + return "AFTER_TEST_RUN" + case HookType_BEFORE_TEST_CASE: + return "BEFORE_TEST_CASE" + case HookType_AFTER_TEST_CASE: + return "AFTER_TEST_CASE" + case HookType_BEFORE_TEST_STEP: + return "BEFORE_TEST_STEP" + case HookType_AFTER_TEST_STEP: + return "AFTER_TEST_STEP" + default: + panic("Bad enum value for HookType") + } +} + +type PickleStepType string + +const ( + PickleStepType_UNKNOWN PickleStepType = "Unknown" + PickleStepType_CONTEXT PickleStepType = "Context" + PickleStepType_ACTION PickleStepType = "Action" + PickleStepType_OUTCOME PickleStepType = "Outcome" +) + +func (e PickleStepType) String() string { + switch e { + case PickleStepType_UNKNOWN: + return "Unknown" + case PickleStepType_CONTEXT: + return "Context" + case PickleStepType_ACTION: + return "Action" + case PickleStepType_OUTCOME: + return "Outcome" + default: + panic("Bad enum value for PickleStepType") + } +} + +type SourceMediaType string + +const ( + SourceMediaType_TEXT_X_CUCUMBER_GHERKIN_PLAIN SourceMediaType = "text/x.cucumber.gherkin+plain" + SourceMediaType_TEXT_X_CUCUMBER_GHERKIN_MARKDOWN SourceMediaType = "text/x.cucumber.gherkin+markdown" +) + +func (e SourceMediaType) String() string { + switch e { + case SourceMediaType_TEXT_X_CUCUMBER_GHERKIN_PLAIN: + return "text/x.cucumber.gherkin+plain" + case SourceMediaType_TEXT_X_CUCUMBER_GHERKIN_MARKDOWN: + return "text/x.cucumber.gherkin+markdown" + default: + panic("Bad enum value for SourceMediaType") + } +} + +type StepDefinitionPatternType string + +const ( + StepDefinitionPatternType_CUCUMBER_EXPRESSION StepDefinitionPatternType = "CUCUMBER_EXPRESSION" + StepDefinitionPatternType_REGULAR_EXPRESSION StepDefinitionPatternType = "REGULAR_EXPRESSION" +) + +func (e StepDefinitionPatternType) String() string { + switch e { + case StepDefinitionPatternType_CUCUMBER_EXPRESSION: + return "CUCUMBER_EXPRESSION" + case StepDefinitionPatternType_REGULAR_EXPRESSION: + return "REGULAR_EXPRESSION" + default: + panic("Bad enum value for StepDefinitionPatternType") + } +} + +type StepKeywordType string + +const ( + StepKeywordType_UNKNOWN StepKeywordType = "Unknown" + StepKeywordType_CONTEXT StepKeywordType = "Context" + StepKeywordType_ACTION StepKeywordType = "Action" + StepKeywordType_OUTCOME StepKeywordType = "Outcome" + StepKeywordType_CONJUNCTION StepKeywordType = "Conjunction" +) + +func (e StepKeywordType) String() string { + switch e { + case StepKeywordType_UNKNOWN: + return "Unknown" + case StepKeywordType_CONTEXT: + return "Context" + case StepKeywordType_ACTION: + return "Action" + case StepKeywordType_OUTCOME: + return "Outcome" + case StepKeywordType_CONJUNCTION: + return "Conjunction" + default: + panic("Bad enum value for StepKeywordType") + } +} + +type TestStepResultStatus string + +const ( + TestStepResultStatus_UNKNOWN TestStepResultStatus = "UNKNOWN" + TestStepResultStatus_PASSED TestStepResultStatus = "PASSED" + TestStepResultStatus_SKIPPED TestStepResultStatus = "SKIPPED" + TestStepResultStatus_PENDING TestStepResultStatus = "PENDING" + TestStepResultStatus_UNDEFINED TestStepResultStatus = "UNDEFINED" + TestStepResultStatus_AMBIGUOUS TestStepResultStatus = "AMBIGUOUS" + TestStepResultStatus_FAILED TestStepResultStatus = "FAILED" +) + +func (e TestStepResultStatus) String() string { + switch e { + case TestStepResultStatus_UNKNOWN: + return "UNKNOWN" + case TestStepResultStatus_PASSED: + return "PASSED" + case TestStepResultStatus_SKIPPED: + return "SKIPPED" + case TestStepResultStatus_PENDING: + return "PENDING" + case TestStepResultStatus_UNDEFINED: + return "UNDEFINED" + case TestStepResultStatus_AMBIGUOUS: + return "AMBIGUOUS" + case TestStepResultStatus_FAILED: + return "FAILED" + default: + panic("Bad enum value for TestStepResultStatus") + } +} diff --git a/vendor/github.com/cucumber/messages/go/v34/time_conversion.go b/vendor/github.com/cucumber/messages/go/v34/time_conversion.go new file mode 100644 index 0000000000..3a387931e7 --- /dev/null +++ b/vendor/github.com/cucumber/messages/go/v34/time_conversion.go @@ -0,0 +1,34 @@ +package messages + +import "time" + +const nanosPerSecond = 1000000000 + +func DurationToGoDuration(duration Duration) time.Duration { + secondNanos := duration.Seconds * nanosPerSecond + return time.Duration(secondNanos + int64(duration.Nanos)) +} + +func GoDurationToDuration(goDuration time.Duration) Duration { + seconds := int64(goDuration / nanosPerSecond) + nanos := int64(goDuration % nanosPerSecond) + return Duration{ + Seconds: seconds, + Nanos: nanos, + } +} + +func TimestampToGoTime(timestamp Timestamp) time.Time { + return time.Unix(timestamp.Seconds, timestamp.Nanos) +} + +func GoTimeToTimestamp(t time.Time) Timestamp { + unixNanos := t.UnixNano() + seconds := unixNanos / nanosPerSecond + nanos := unixNanos % nanosPerSecond + + return Timestamp{ + Seconds: seconds, + Nanos: nanos, + } +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go index ade2c63c90..a9b105e177 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go +++ b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go @@ -102,11 +102,19 @@ func (dk *defaultKeychain) ResolveContext(_ context.Context, target Resource) (A if !foundDockerConfig && os.Getenv("DOCKER_CONFIG") != "" { foundDockerConfig = fileExists(filepath.Join(os.Getenv("DOCKER_CONFIG"), "config.json")) } + configDir := os.Getenv("XDG_CONFIG_HOME") + if configDir == "" && home != "" { + configDir = filepath.Join(home, ".config") + } + podmanAuth := filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json") + if (os.Getenv("XDG_RUNTIME_DIR") == "" || !fileExists(podmanAuth)) && configDir != "" { + podmanAuth = filepath.Join(configDir, "containers/auth.json") + } // If either of those locations are found, load it using Docker's // config.Load, which may fail if the config can't be parsed. // // If neither was found, look for Podman's auth at - // $REGISTRY_AUTH_FILE or $XDG_RUNTIME_DIR/containers/auth.json + // $REGISTRY_AUTH_FILE or containers/auth.json under XDG runtime/config dirs // and attempt to load it as a Docker config. // // If neither are found, fallback to Anonymous. @@ -126,7 +134,7 @@ func (dk *defaultKeychain) ResolveContext(_ context.Context, target Resource) (A if err != nil { return nil, err } - } else if path := filepath.Clean(filepath.Join(os.Getenv("XDG_RUNTIME_DIR"), "containers/auth.json")); fileExists(path) { + } else if path := filepath.Clean(podmanAuth); fileExists(path) { f, err := os.Open(path) if err != nil { return nil, err diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/doc.go b/vendor/github.com/google/go-containerregistry/pkg/name/doc.go index b294794dc1..b67ad0ffcb 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/doc.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/doc.go @@ -17,9 +17,11 @@ // What's in a name? For image references, not nearly enough! // // Image references look a lot like URLs, but they differ in that they don't -// contain the scheme (http or https), they can end with a :tag or a @digest -// (the latter being validated), and they perform defaulting for missing -// components. +// contain the scheme (http or https), they can end with a :tag, an @digest +// (the latter being validated), or both. When a reference includes both a tag +// and a digest, it is treated as a digest reference: the digest is the +// identifier used for verification, while the tag is retained only in the +// original string form. // // Since image references don't contain the scheme, we do our best to infer // if we use http or https from the given hostname. We allow http fallback for diff --git a/vendor/github.com/google/go-containerregistry/pkg/name/ref.go b/vendor/github.com/google/go-containerregistry/pkg/name/ref.go index 0a04867723..539d0ff318 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/name/ref.go +++ b/vendor/github.com/google/go-containerregistry/pkg/name/ref.go @@ -37,6 +37,7 @@ type Reference interface { } // ParseReference parses the string as a reference, either by tag or digest. +// References that include both a tag and digest parse as Digest references. func ParseReference(s string, opts ...Option) (Reference, error) { if t, err := NewTag(s, opts...); err == nil { return t, nil diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go index 09458e96cb..596c78cb26 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go @@ -22,7 +22,7 @@ import ( "fmt" "io" "maps" - "path/filepath" + "path" "strings" "time" @@ -37,6 +37,11 @@ import ( const whiteoutPrefix = ".wh." +// opaqueWhiteout marks a directory as opaque: all entries from lower layers under +// its parent directory are hidden. It shares the whiteoutPrefix, so it must be +// matched exactly and handled before the generic per-file whiteout logic. +const opaqueWhiteout = ".wh..wh..opq" + // Addendum contains layers and history to be appended // to a base image type Addendum struct { @@ -267,6 +272,9 @@ func extract(img v1.Image, w io.Writer) error { defer tarWriter.Close() fileMap := map[string]bool{} + // opaqueDirs holds directories opaqued by an upper layer; entries under them + // from lower (later-iterated) layers are hidden. + opaqueDirs := map[string]bool{} layers, err := img.Layers() if err != nil { @@ -277,14 +285,18 @@ func extract(img v1.Image, w io.Writer) error { // whiteout layers more efficient, since we can just keep track of the removed // files as we see .wh. layers and ignore those in previous layers. for i := len(layers) - 1; i >= 0; i-- { - if err := extractLayer(tarWriter, fileMap, layers[i]); err != nil { + if err := extractLayer(tarWriter, fileMap, opaqueDirs, layers[i]); err != nil { return err } } return nil } -func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer) error { +func extractLayer(tarWriter *tar.Writer, fileMap, opaqueDirs map[string]bool, layer v1.Layer) error { + // Opaque markers in this layer hide only lower layers, so stage them and + // promote to opaqueDirs after the whole layer is processed. + layerOpaque := map[string]bool{} + layerReader, err := layer.Uncompressed() if err != nil { return fmt.Errorf("reading layer contents: %w", err) @@ -303,7 +315,10 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer // Some tools prepend everything with "./", so if we don't Clean the // name, we may have duplicate entries, which angers tar-split. - header.Name = filepath.Clean(header.Name) + header.Name = path.Clean(header.Name) + if unsafeArchivePath(header.Name) { + return fmt.Errorf("unsafe tar path %q", header.Name) + } // Reject relative symlinks and hardlinks whose targets escape the // image rootfs. Relative targets are resolved against the symlink's @@ -313,11 +328,8 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer // Absolute targets are left as-is; see #2238 for ongoing discussion // on whether they should be pruned. if header.Typeflag == tar.TypeSymlink || header.Typeflag == tar.TypeLink { - if !filepath.IsAbs(header.Linkname) { - resolved := filepath.Clean(filepath.Join(filepath.Dir(header.Name), header.Linkname)) //nolint:gosec // G305: path is only used for validation, not file I/O - if strings.HasPrefix(resolved, "..") { - continue - } + if unsafeRelativeLink(header.Name, header.Linkname) { + continue } } @@ -326,8 +338,16 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer // prefers USTAR over PAX header.Format = tar.FormatPAX - basename := filepath.Base(header.Name) - dirname := filepath.Dir(header.Name) + basename := path.Base(header.Name) + dirname := path.Dir(header.Name) + + // An opaque marker hides all lower-layer entries under dirname. It shares + // the whiteout prefix, so handle it before the generic per-file logic. + if basename == opaqueWhiteout { + layerOpaque[dirname] = true + continue + } + tombstone := strings.HasPrefix(basename, whiteoutPrefix) if tombstone { basename = basename[len(whiteoutPrefix):] @@ -339,7 +359,7 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer if header.Typeflag == tar.TypeDir { name = header.Name } else { - name = filepath.Join(dirname, basename) + name = path.Join(dirname, basename) } if _, ok := fileMap[name]; ok && !tombstone { @@ -351,6 +371,11 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer continue } + // check for a parent directory opaqued by an upper layer + if inOpaqueDir(opaqueDirs, name) { + continue + } + // mark file as handled. non-directory implicitly tombstones // any entries with a matching (or child) name fileMap[name] = tombstone || (header.Typeflag != tar.TypeDir) @@ -366,6 +391,11 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer } } + // Opaque dirs found in this layer now hide entries in lower layers. + for d := range layerOpaque { + opaqueDirs[d] = true + } + // Drain any bytes the tar.Reader did not consume (trailing data after the // end-of-archive marker) so the underlying verifying reader reaches io.EOF // and the layer's digest is verified. Without this, a layer whose contents @@ -377,9 +407,23 @@ func extractLayer(tarWriter *tar.Writer, fileMap map[string]bool, layer v1.Layer return nil } +func inOpaqueDir(opaqueDirs map[string]bool, file string) bool { + for file != "" { + dirname := path.Dir(file) + if file == dirname { + break + } + if opaqueDirs[dirname] { + return true + } + file = dirname + } + return false +} + func inWhiteoutDir(fileMap map[string]bool, file string) bool { for file != "" { - dirname := filepath.Dir(file) + dirname := path.Dir(file) if file == dirname { break } @@ -391,6 +435,39 @@ func inWhiteoutDir(fileMap map[string]bool, file string) bool { return false } +func unsafeArchivePath(name string) bool { + clean := cleanArchivePath(name) + if clean == ".." || strings.HasPrefix(clean, "../") { + return true + } + if strings.HasPrefix(name, "\\") { + return true + } + return hasWindowsDrivePrefix(clean) +} + +func unsafeRelativeLink(name, linkname string) bool { + clean := cleanArchivePath(linkname) + if path.IsAbs(clean) { + return false + } + if hasWindowsDrivePrefix(clean) { + return true + } + resolved := path.Clean(path.Join(path.Dir(name), clean)) //nolint:gosec // G305: path is only used for validation, not file I/O + return strings.HasPrefix(resolved, "..") +} + +func cleanArchivePath(name string) string { + return path.Clean(strings.ReplaceAll(name, "\\", "/")) +} + +func hasWindowsDrivePrefix(name string) bool { + return len(name) >= 2 && + (('A' <= name[0] && name[0] <= 'Z') || ('a' <= name[0] && name[0] <= 'z')) && + name[1] == ':' +} + // Time sets all timestamps in an image to the given timestamp. func Time(img v1.Image, t time.Time) (v1.Image, error) { newImage := empty.Image diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/rebase.go b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/rebase.go index c606e0b76e..a7ac8ff535 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/rebase.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/mutate/rebase.go @@ -97,13 +97,21 @@ func Rebase(orig, oldBase, newBase v1.Image) (v1.Image, error) { return nil, fmt.Errorf("could not get new base layers for new base: %w", err) } // Add new base layers. - rebasedImage, err = Append(rebasedImage, createAddendums(0, 0, newConfig.History, newBaseLayers)...) + newBaseAdds, err := createAddendums(0, 0, newConfig.History, newBaseLayers) + if err != nil { + return nil, fmt.Errorf("failed to process new base image: %w", err) + } + rebasedImage, err = Append(rebasedImage, newBaseAdds...) if err != nil { return nil, fmt.Errorf("failed to append new base image: %w", err) } // Add original layers above the old base. - rebasedImage, err = Append(rebasedImage, createAddendums(len(oldConfig.History), len(oldBaseLayers)+1, origConfig.History, origLayers)...) + origAdds, err := createAddendums(len(oldConfig.History), len(oldBaseLayers)+1, origConfig.History, origLayers) + if err != nil { + return nil, fmt.Errorf("failed to process original image: %w", err) + } + rebasedImage, err = Append(rebasedImage, origAdds...) if err != nil { return nil, fmt.Errorf("failed to append original image: %w", err) } @@ -113,7 +121,7 @@ func Rebase(orig, oldBase, newBase v1.Image) (v1.Image, error) { // createAddendums makes a list of addendums from a history and layers starting from a specific history and layer // indexes. -func createAddendums(startHistory, startLayer int, history []v1.History, layers []v1.Layer) []Addendum { +func createAddendums(startHistory, startLayer int, history []v1.History, layers []v1.Layer) ([]Addendum, error) { var adds []Addendum // History should be a superset of layers; empty layers (e.g. ENV statements) only exist in history. // They cannot be iterated identically but must be walked independently, only advancing the iterator for layers @@ -123,6 +131,9 @@ func createAddendums(startHistory, startLayer int, history []v1.History, layers var layer v1.Layer emptyLayer := history[historyIndex].EmptyLayer if !emptyLayer { + if layerIndex >= len(layers) { + return nil, fmt.Errorf("malformed image: config history references at least %d non-empty layer(s), but only %d layer(s) are present", layerIndex+1, len(layers)) + } layer = layers[layerIndex] layerIndex++ } @@ -136,9 +147,9 @@ func createAddendums(startHistory, startLayer int, history []v1.History, layers // In the event history was malformed or non-existent, append the remaining layers. for i := layerIndex; i < len(layers); i++ { if i >= startLayer { - adds = append(adds, Addendum{Layer: layers[layerIndex]}) + adds = append(adds, Addendum{Layer: layers[i]}) } } - return adds + return adds, nil } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go index b4395c2391..ac879a6737 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go @@ -68,5 +68,5 @@ func (w *writer) cancelUpload(loc string) { if err != nil { return } - _, _ = w.client.Do(req) + _, _ = w.getClient().Do(req) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/limiter.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/limiter.go index 54ec3b28dc..153d7cf02f 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/limiter.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/limiter.go @@ -48,6 +48,14 @@ type limitedReadCloser struct { once sync.Once } +func (l *limitedReadCloser) Read(p []byte) (int, error) { + n, err := l.ReadCloser.Read(p) + if err != nil { + l.once.Do(l.release) + } + return n, err +} + func (l *limitedReadCloser) Close() error { err := l.ReadCloser.Close() l.once.Do(l.release) diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go index 3d8bb8ddfd..749db0b68a 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go @@ -46,6 +46,7 @@ type options struct { retryPredicate retry.Predicate retryStatusCodes []int limiter *pullLimiter + referrersTagFallback bool // Only these options can overwrite Reuse()d options. platform v1.Platform @@ -108,6 +109,8 @@ const ( // ECR returns an error if n > 1000: // https://github.com/google/go-containerregistry/issues/1091 defaultPageSize = 1000 + + defaultReferrersTagFallback = true ) // DefaultTransport is based on http.DefaultTransport with modifications @@ -129,14 +132,15 @@ var DefaultTransport http.RoundTripper = &http.Transport{ func makeOptions(opts ...Option) (*options, error) { o := &options{ - transport: DefaultTransport, - platform: defaultPlatform, - context: context.Background(), - jobs: defaultJobs, - pageSize: defaultPageSize, - retryPredicate: defaultRetryPredicate, - retryBackoff: defaultRetryBackoff, - retryStatusCodes: defaultRetryStatusCodes, + transport: DefaultTransport, + platform: defaultPlatform, + context: context.Background(), + jobs: defaultJobs, + pageSize: defaultPageSize, + retryPredicate: defaultRetryPredicate, + retryBackoff: defaultRetryBackoff, + retryStatusCodes: defaultRetryStatusCodes, + referrersTagFallback: defaultReferrersTagFallback, } for _, option := range opts { @@ -328,6 +332,24 @@ func WithRetryStatusCodes(codes ...int) Option { } } +// WithReferrersTagFallback toggles the referrers tag fallback scheme, see: +// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema +// +// When enabled, pushing a manifest with a subject to a registry that doesn't +// support the Referrers API maintains an image index of referrers under a +// fallback tag, and listing referrers reads from that tag. When disabled, +// the Referrers API is required: pushing a manifest with a subject and +// listing referrers both fail against a registry that doesn't support it, +// rather than falling back to the tag scheme. +// +// The default is true. +func WithReferrersTagFallback(enabled bool) Option { + return func(o *options) error { + o.referrersTagFallback = enabled + return nil + } +} + // WithFilter sets the filter querystring for HTTP operations. func WithFilter(key string, value string) Option { return func(o *options) error { diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go index 7da8017eec..bcb0d7350f 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go @@ -218,5 +218,5 @@ func (p *Puller) referrers(ctx context.Context, d name.Digest, filter map[string if err != nil { return nil, err } - return f.fetchReferrers(ctx, filter, d) + return f.fetchReferrers(ctx, filter, d, p.o.referrersTagFallback) } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go index 5675c97c8f..3a1d16f544 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go @@ -410,7 +410,7 @@ func (rw *repoWriter) writeChild(ctx context.Context, child partial.Describable, func (rw *repoWriter) manifestExists(ctx context.Context, ref name.Reference, t Taggable) (bool, error) { f := &fetcher{ target: ref.Context(), - client: rw.w.client, + client: rw.w.getClient(), } m, err := taggableToManifest(t) diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/referrers.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/referrers.go index c23e1d83b6..5a111d7fcf 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/referrers.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/referrers.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "errors" + "fmt" "net/http" "strings" @@ -46,7 +47,7 @@ func fallbackTag(d name.Digest) name.Tag { return d.Context().Tag(strings.Replace(d.DigestStr(), ":", "-", 1)) } -func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest) (v1.ImageIndex, error) { +func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest, tagFallback bool) (v1.ImageIndex, error) { // Check the Referrers API endpoint first. u := f.url("referrers", d.DigestStr()) req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) @@ -72,6 +73,9 @@ func (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, return nil, err } } else { + if !tagFallback { + return nil, fmt.Errorf("registry %s does not support the Referrers API and the referrers tag fallback is disabled", d.Context().RegistryStr()) + } // The registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme. b, _, err = f.fetchManifest(ctx, fallbackTag(d), []types.MediaType{types.OCIImageIndex}) var terr *transport.Error diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go index cbc2b1d4f9..f576ccd300 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go @@ -221,6 +221,16 @@ func (bt *bearerTransport) RoundTrip(in *http.Request) (*http.Response, error) { // close out old response, since we will not return it. res.Body.Close() + // For cross-host challenges (the request was redirected to another host), + // never mutate bt's shared state: accumulating this host's scope into + // bt.scopes or refreshing bt's token from bt.realm would pollute future + // same-host requests with a scope/token that belongs to a request we + // only ever intended to send to the redirected host. Instead, attempt a + // fresh per-host token exchange scoped entirely to this one request. + if !matchesHost(bt.registry.RegistryStr(), in, bt.scheme) { + return bt.handleCrossHostChallenge(in, challenges) + } + newScopes := []string{} bt.mx.Lock() got := stringSet(bt.scopes) @@ -247,18 +257,7 @@ func (bt *bearerTransport) RoundTrip(in *http.Request) (*http.Response, error) { if err = bt.refresh(in.Context()); err != nil { return nil, err } - // Re-attach the freshly fetched token, but only when the request is - // still talking to the registry we authenticated against. matchesHost - // guards against forwarding the Authorization header across an - // http.Client-level redirect to a different host: a malicious or - // compromised registry can 302 the request to an attacker-controlled - // host, answer the follow-up with a Bearer challenge, and harvest the - // token if we re-attach it unconditionally. For a cross-host request - // fall back to sendRequest(), which omits the credential, rather than - // leaking it to a host we never logged in to. - if !matchesHost(bt.registry.RegistryStr(), in, bt.scheme) { - return sendRequest() - } + bt.mx.RLock() tok := bt.bearer.RegistryToken bt.mx.RUnlock() @@ -269,6 +268,65 @@ func (bt *bearerTransport) RoundTrip(in *http.Request) (*http.Response, error) { return res, err } +// handleCrossHostChallenge performs a per-host bearer token exchange when +// the request has been redirected to a host different from bt.registry. It +// parses the redirected host's own WWW-Authenticate Bearer challenge, fetches +// a token from that host's realm using anonymous auth (the original registry's +// credentials are never forwarded cross-host), and applies the token only to +// this request. +// +// If no usable Bearer challenge is present, or the token exchange fails, the +// request is retried without an Authorization header. +func (bt *bearerTransport) handleCrossHostChallenge(in *http.Request, challenges []authchallenge.Challenge) (*http.Response, error) { + for _, wac := range challenges { + if strings.ToLower(wac.Scheme) != "bearer" { + continue + } + if _, ok := wac.Parameters["realm"]; !ok { + continue + } + + redirectedReg, err := name.NewRegistry(in.URL.Host, name.WeakValidation) + if err != nil { + logs.Warn.Printf("cross-host redirect: invalid host %q: %v", in.URL.Host, err) + continue + } + + // Build a transport.Challenge from the redirected host's WWW-Authenticate + // parameters. fromChallenge validates the realm URL (SSRF guard). + pr := &Challenge{ + Scheme: wac.Scheme, + Parameters: wac.Parameters, + Insecure: in.URL.Scheme == "http", + } + scope := wac.Parameters["scope"] + // TODO: use a keychain to resolve credentials for the redirected host so + // that token endpoints requiring auth are also supported. For now, anonymous + // auth covers the common case where the redirected host's token endpoint is + // public. See https://github.com/google/go-containerregistry/issues/2359. + tmpBt, err := fromChallenge(redirectedReg, authn.Anonymous, bt.inner, pr, scope) + if err != nil { + logs.Warn.Printf("cross-host bearer challenge setup for %q failed: %v", in.URL.Host, err) + continue + } + + if err := tmpBt.refresh(in.Context()); err != nil { + logs.Warn.Printf("cross-host bearer exchange for %q failed: %v", in.URL.Host, err) + continue + } + + tmpBt.mx.RLock() + tok := tmpBt.bearer.RegistryToken + tmpBt.mx.RUnlock() + + in.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tok)) + return bt.inner.RoundTrip(in) + } + + // No usable bearer challenge; retry without credentials. + return bt.inner.RoundTrip(in) +} + // It's unclear which authentication flow to use based purely on the protocol, // so we rely on heuristics and fallbacks to support as many registries as possible. // The basic token exchange is attempted first, falling back to the oauth flow. diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go index 4ff30a8cb1..01e9c767bb 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go @@ -61,12 +61,21 @@ type writer struct { backoff Backoff predicate retry.Predicate + referrersTagFallback bool + scopeLock sync.Mutex // Keep track of scopes that we have already requested. scopeSet map[string]struct{} scopes []string } +// getClient returns the HTTP client, blocking on scope updates. +func (w *writer) getClient() *http.Client { + w.scopeLock.Lock() + defer w.scopeLock.Unlock() + return w.client +} + // makeDeleteClient returns an HTTP client whose token includes the "delete" // action so that registries requiring an explicit delete permission grant // access for manifest deletion. @@ -106,15 +115,16 @@ func makeWriter(ctx context.Context, repo name.Repository, ls []v1.Layer, o *opt scopeSet[scope] = struct{}{} } return &writer{ - repo: repo, - client: &http.Client{Transport: tr}, - auth: auth, - transport: o.transport, - progress: o.progress, - backoff: o.retryBackoff, - predicate: o.retryPredicate, - scopes: scopes, - scopeSet: scopeSet, + repo: repo, + client: &http.Client{Transport: tr}, + auth: auth, + transport: o.transport, + progress: o.progress, + backoff: o.retryBackoff, + predicate: o.retryPredicate, + referrersTagFallback: o.referrersTagFallback, + scopes: scopes, + scopeSet: scopeSet, }, nil } @@ -205,7 +215,7 @@ func (w *writer) checkExistingBlob(ctx context.Context, h v1.Hash) (bool, error) return false, err } - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { return false, err } @@ -243,7 +253,7 @@ func (w *writer) initiateUpload(ctx context.Context, from, mount, origin string) return "", false, err } req.Header.Set("Content-Type", "application/json") - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { if from != "" { // https://github.com/google/go-containerregistry/issues/1679 @@ -323,7 +333,7 @@ func (w *writer) streamBlob(ctx context.Context, layer v1.Layer, streamLocation } req.Header.Set("Content-Type", "application/octet-stream") - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { return "", err } @@ -355,7 +365,7 @@ func (w *writer) commitBlob(ctx context.Context, location, digest string) error } req.Header.Set("Content-Type", "application/octet-stream") - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { return err } @@ -514,7 +524,7 @@ func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, ad return err } req.Header.Set("Accept", string(types.OCIImageIndex)) - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { return err } @@ -527,6 +537,9 @@ func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, ad // The registry supports Referrers API. The registry is responsible for updating the referrers list. return nil } + if !w.referrersTagFallback { + return fmt.Errorf("registry %s does not support the Referrers API and the referrers tag fallback is disabled", w.repo.RegistryStr()) + } // The registry doesn't support Referrers API, we need to update the manifest tagged with the fallback tag. // Make the request to GET the current manifest. @@ -537,7 +550,7 @@ func (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, ad return err } req.Header.Set("Accept", string(types.OCIImageIndex)) - resp, err = w.client.Do(req.WithContext(ctx)) + resp, err = w.getClient().Do(req.WithContext(ctx)) if err != nil { return err } @@ -624,7 +637,7 @@ func (w *writer) commitManifest(ctx context.Context, t Taggable, ref name.Refere } req.Header.Set("Content-Type", string(desc.MediaType)) - resp, err := w.client.Do(req.WithContext(ctx)) + resp, err := w.getClient().Do(req.WithContext(ctx)) if err != nil { return err } diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go index 9b0350b121..76b61c687c 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go @@ -304,6 +304,9 @@ func (i *uncompressedImage) LayerByDiffID(h v1.Hash) (partial.UncompressedLayer, } for idx, diffID := range cfg.RootFS.DiffIDs { if diffID == h { + if idx >= len(i.imgDescriptor.Layers) { + return nil, fmt.Errorf("config has %d rootfs.diff_id(s) but tarball manifest only references %d layer(s); the config may not describe a runnable image", len(cfg.RootFS.DiffIDs), len(i.imgDescriptor.Layers)) + } // Technically the media type should be 'application/tar' but given that our // v1.Layer doesn't force consumers to care about whether the layer is compressed // we should be fine returning the DockerLayer media type diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/write.go b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/write.go index 062268a5b9..4b1bfd0a61 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/write.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/tarball/write.go @@ -28,6 +28,7 @@ import ( "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/partial" + "github.com/google/go-containerregistry/pkg/v1/types" ) // WriteToFile writes in the compressed format to a tarball, on disk. @@ -184,7 +185,7 @@ func writeImagesToTar(imageToTags map[v1.Image][]string, m []byte, size int64, w // gunzip expects certain file extensions: // https://www.gnu.org/software/gzip/manual/html_node/Overview.html - layerFiles[i] = fmt.Sprintf("%s.tar.gz", hex) + layerFiles[i] = hex + layerExtension(l) if _, ok := seenLayerDigests[hex]; ok { continue @@ -244,7 +245,7 @@ func calculateManifest(imageToTags map[v1.Image][]string) (m Manifest, err error // gunzip expects certain file extensions: // https://www.gnu.org/software/gzip/manual/html_node/Overview.html - layerFiles[i] = fmt.Sprintf("%s.tar.gz", hex) + layerFiles[i] = hex + layerExtension(l) // Add to LayerSources if it's a foreign layer. desc, err := partial.BlobDescriptor(img, d) @@ -463,3 +464,16 @@ func calculateSingleFileInTarSize(in int64) (out int64) { out += 512 return out } + +func layerExtension(l v1.Layer) string { + mt, _ := l.MediaType() + switch mt { + case types.OCILayerZStd: + return ".tar.zst" + case types.OCIUncompressedLayer, types.OCIUncompressedRestrictedLayer, types.DockerUncompressedLayer: + return ".tar" + default: + // historically, only gzip compressed tar was supported, so this is the fallback + return ".tar.gz" + } +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index 2d6ef64be1..7035d656d9 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -1,222 +1,49 @@ //go:build amd64 && !appengine && !noasm && gc -// This file contains the specialisation of Decoder.Decompress4X -// and Decoder.Decompress1X that use an asm implementation of thir main loops. +// amd64 stubs and dispatch for the asm loops used by decompress_asm.go. package huff0 import ( - "errors" - "fmt" - "github.com/klauspost/compress/internal/cpuinfo" ) -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress4x_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog > 8. // //go:noescape func decompress4x_main_loop_amd64(ctx *decompress4xContext) -// decompress4x_8b_loop_x86 is an x86 assembler implementation +// decompress4x_8b_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. // //go:noescape func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) -// fallback8BitSize is the size where using Go version is faster. -const fallback8BitSize = 800 - -type decompress4xContext struct { - pbr *[4]bitReaderShifted - peekBits uint8 - out *byte - dstEvery int - tbl *dEntrySingle - decoded int - limit *byte -} - -// Decompress4X will decompress a 4X encoded stream. -// The length of the supplied input must match the end of a block exactly. -// The *capacity* of the dst slice must match the destination size of -// the uncompressed data exactly. -func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if len(src) < 6+(4*1) { - return nil, errors.New("input too small") - } - - use8BitTables := d.actualTableLog <= 8 - if cap(dst) < fallback8BitSize && use8BitTables { - return d.decompress4X8bit(dst, src) - } - - var br [4]bitReaderShifted - // Decode "jump table" - start := 6 - for i := range 3 { - length := int(src[i*2]) | (int(src[i*2+1]) << 8) - if start+length >= len(src) { - return nil, errors.New("truncated input (or invalid offset)") - } - err := br[i].init(src[start : start+length]) - if err != nil { - return nil, err - } - start += length - } - err := br[3].init(src[start:]) - if err != nil { - return nil, err - } - - // destination, offset to match first output - dstSize := cap(dst) - dst = dst[:dstSize] - out := dst - dstEvery := (dstSize + 3) / 4 - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - single := d.dt.single[:tlSize] - - var decoded int - - if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { - ctx := decompress4xContext{ - pbr: &br, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - out: &out[0], - dstEvery: dstEvery, - tbl: &single[0], - limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. - } - if use8BitTables { - decompress4x_8b_main_loop_amd64(&ctx) - } else { - decompress4x_main_loop_amd64(&ctx) - } - - decoded = ctx.decoded - out = out[decoded/4:] - } - - // Decode remaining. - remainBytes := dstEvery - (decoded / 4) - for i := range br { - offset := dstEvery * i - endsAt := min(offset+remainBytes, len(out)) - br := &br[i] - bitsLeft := br.remaining() - for bitsLeft > 0 { - br.fill() - if offset >= endsAt { - return nil, errors.New("corruption detected: stream overrun 4") - } - - // Read value and increment offset. - val := br.peekBitsFast(d.actualTableLog) - v := single[val&tlMask].entry - nBits := uint8(v) - br.advance(nBits) - bitsLeft -= uint(nBits) - out[offset] = uint8(v >> 8) - offset++ - } - if offset != endsAt { - return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) - } - decoded += offset - dstEvery*i - err = br.close() - if err != nil { - return nil, err - } - } - if dstSize != decoded { - return nil, errors.New("corruption detected: short output block") - } - return dst, nil -} - -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress1x_main_loop_amd64 is an x86 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_amd64(ctx *decompress1xContext) -// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// decompress1x_main_loop_bmi2 is an x86 with BMI2 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_bmi2(ctx *decompress1xContext) -type decompress1xContext struct { - pbr *bitReaderShifted - peekBits uint8 - out *byte - outCap int - tbl *dEntrySingle - decoded int +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_amd64(ctx) } -// Error reported by asm implementations -const error_max_decoded_size_exeeded = -1 - -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:maxDecodedSize] - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - - if maxDecodedSize >= 4 { - ctx := decompress1xContext{ - pbr: &br, - out: &dst[0], - outCap: maxDecodedSize, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - tbl: &d.dt.single[0], - } - - if cpuinfo.HasBMI2() { - decompress1x_main_loop_bmi2(&ctx) - } else { - decompress1x_main_loop_amd64(&ctx) - } - if ctx.decoded == error_max_decoded_size_exeeded { - return nil, ErrMaxDecodedSizeExceeded - } - - dst = dst[:ctx.decoded] - } +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_amd64(ctx) +} - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if len(dst) >= maxDecodedSize { - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(ctx) + } else { + decompress1x_main_loop_amd64(ctx) } - return dst, br.close() } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index c4c7ab2d1f..c5d4a710a0 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. -//go:build amd64 && !appengine && !noasm && gc +//go:build !appengine && !noasm && gc // func decompress4x_main_loop_amd64(ctx *decompress4xContext) TEXT ·decompress4x_main_loop_amd64(SB), $0-8 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go new file mode 100644 index 0000000000..8ba3c810e6 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go @@ -0,0 +1,37 @@ +//go:build arm64 && !appengine && !noasm && gc + +// arm64 stubs and dispatch for the asm loops used by decompress_asm.go. +// The asm (decompress_arm64.s) is generated by the avo arm64 lowering +// printer from the same source as the amd64 asm; see _generate/gen.go. +package huff0 + +// decompress4x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog > 8. +// +//go:noescape +func decompress4x_main_loop_arm64(ctx *decompress4xContext) + +// decompress4x_8b_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog <= 8 which decodes 4 entries +// per loop. +// +//go:noescape +func decompress4x_8b_main_loop_arm64(ctx *decompress4xContext) + +// decompress1x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_arm64(ctx *decompress1xContext) + +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_arm64(ctx) +} + +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_arm64(ctx) +} + +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + decompress1x_main_loop_arm64(ctx) +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s new file mode 100644 index 0000000000..e16012721a --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s @@ -0,0 +1,851 @@ +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && !appengine && !noasm && gc + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R0 + MOVBU 8(R0), R6 + MOVD 16(R0), R3 + MOVD 48(R0), R5 + MOVD 24(R0), R7 + MOVD 32(R0), R8 + MOVD (R0), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD (R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 24(R9) + ORR R12, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 48(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 72(R9) + ORR R12, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 96(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 120(R9) + ORR R12, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 144(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 168(R9) + ORR R12, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x02, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R1 + MOVBU 8(R1), R6 + MOVD 16(R1), R3 + MOVD 48(R1), R5 + MOVD 24(R1), R7 + MOVD 32(R1), R8 + MOVD (R1), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD (R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 24(R9) + ORR R13, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVW R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 48(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 72(R9) + ORR R13, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 96(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 120(R9) + ORR R13, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 144(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 168(R9) + ORR R13, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x04, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_arm64(SB), $0-8 + MOVD ctx+0(FP), R1 + MOVD 16(R1), R2 + MOVD 24(R1), R3 + CMP $0x04, R3 + BLO error_max_decoded_size_exceeded + ADD R3, R2, R3 + MOVD (R1), R5 + MOVD (R5), R7 + MOVD 24(R5), R8 + MOVD 32(R5), R9 + MOVBU 40(R5), R10 + MOVD 32(R1), R5 + MOVBU 8(R1), R6 + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + ADD $4, R2, R1 + CMP R3, R1 + BGE error_max_decoded_size_exceeded + + // Decode 4 values + CMP $0x20, R10 + BLT bitReader_fillFast_1_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_1_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + CMP $0x20, R10 + BLT bitReader_fillFast_2_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_2_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + + // Store the decoded values + MOVW R0, (R2) + ADD $0x04, R2, R2 + +loop_condition: + CMP $0x08, R8 + BGE main_loop + + // Update ctx structure + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R2, R2 + MOVD R2, 40(R0) + MOVD (R0), R0 + MOVD R8, 24(R0) + MOVD R9, 32(R0) + MOVB R10, 40(R0) + RET + + // Report error +error_max_decoded_size_exceeded: + MOVD ctx+0(FP), R0 + MOVD $-1, R1 + MOVD R1, 40(R0) + RET + +// skipped decompress1x_main_loop_bmi2 (generic twin preferred on arm64) diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_asm.go b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go new file mode 100644 index 0000000000..4854dd4365 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go @@ -0,0 +1,193 @@ +//go:build (amd64 || arm64) && !appengine && !noasm && gc + +// This file contains the specialisation of Decoder.Decompress4X +// and Decoder.Decompress1X that use an asm implementation of their main loops. +// The asm function stubs and any per-arch dispatch live in decompress_amd64.go +// and decompress_arm64.go. +package huff0 + +import ( + "errors" + "fmt" +) + +// fallback8BitSize is the size where using Go version is faster. +const fallback8BitSize = 800 + +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + +// Decompress4X will decompress a 4X encoded stream. +// The length of the supplied input must match the end of a block exactly. +// The *capacity* of the dst slice must match the destination size of +// the uncompressed data exactly. +func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if len(src) < 6+(4*1) { + return nil, errors.New("input too small") + } + + use8BitTables := d.actualTableLog <= 8 + if cap(dst) < fallback8BitSize && use8BitTables { + return d.decompress4X8bit(dst, src) + } + + var br [4]bitReaderShifted + // Decode "jump table" + start := 6 + for i := range 3 { + length := int(src[i*2]) | (int(src[i*2+1]) << 8) + if start+length >= len(src) { + return nil, errors.New("truncated input (or invalid offset)") + } + err := br[i].init(src[start : start+length]) + if err != nil { + return nil, err + } + start += length + } + err := br[3].init(src[start:]) + if err != nil { + return nil, err + } + + // destination, offset to match first output + dstSize := cap(dst) + dst = dst[:dstSize] + out := dst + dstEvery := (dstSize + 3) / 4 + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + single := d.dt.single[:tlSize] + + var decoded int + + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. + } + if use8BitTables { + decompress4x_8b_main_loop_asm(&ctx) + } else { + decompress4x_main_loop_asm(&ctx) + } + + decoded = ctx.decoded + out = out[decoded/4:] + } + + // Decode remaining. + remainBytes := dstEvery - (decoded / 4) + for i := range br { + offset := dstEvery * i + endsAt := min(offset+remainBytes, len(out)) + br := &br[i] + bitsLeft := br.remaining() + for bitsLeft > 0 { + br.fill() + if offset >= endsAt { + return nil, errors.New("corruption detected: stream overrun 4") + } + + // Read value and increment offset. + val := br.peekBitsFast(d.actualTableLog) + v := single[val&tlMask].entry + nBits := uint8(v) + br.advance(nBits) + bitsLeft -= uint(nBits) + out[offset] = uint8(v >> 8) + offset++ + } + if offset != endsAt { + return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) + } + decoded += offset - dstEvery*i + err = br.close() + if err != nil { + return nil, err + } + } + if dstSize != decoded { + return nil, errors.New("corruption detected: short output block") + } + return dst, nil +} + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + decompress1x_main_loop_asm(&ctx) + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 6103923222..e1bca5c686 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm // This file contains a generic implementation of Decoder.Decompress4X. package huff0 diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 2329e996f8..51f9da0387 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -400,8 +400,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } } var err error - // Use our out buffer. - huff.MaxDecodedSize = litRegenSize + // Decoder.Decompress* uses cap(dst) for the size limit. Do not write + // MaxDecodedSize on hist.huffTree: with a trained dictionary that + // pointer aliases the shared dict.litEnc and concurrent DecodeAll races. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -673,10 +674,6 @@ func (b *blockDec) executeSequences(hist *history) error { hbytes := hist.b if len(hbytes) > hist.windowSize { hbytes = hbytes[len(hbytes)-hist.windowSize:] - // We do not need history anymore. - if hist.dict != nil { - hist.dict.content = nil - } } hist.decoders.windowSize = hist.windowSize hist.decoders.out = b.dst[:0] diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go index 4f1c4938cd..67f40e7914 100644 --- a/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/vendor/github.com/klauspost/compress/zstd/dict.go @@ -296,40 +296,81 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if offset > 3 { newOffsets[offset-3]++ } else { - newOffsets[uint32(o.Offsets[offset-1])]++ + // Repeat codes reference the training Offsets. Skip unset + // (zero) entries so they are not ranked as real offsets. + prev := o.Offsets[offset-1] + if prev > 0 { + newOffsets[uint32(prev)]++ + } } } } // Find most used offsets. var sortedOffsets []uint32 for k := range newOffsets { + if k == 0 { + continue + } sortedOffsets = append(sortedOffsets, k) } sort.Slice(sortedOffsets, func(i, j int) bool { a, b := sortedOffsets[i], sortedOffsets[j] - if a == b { + ca, cb := newOffsets[a], newOffsets[b] + if ca == cb { // Prefer the longer offset - return sortedOffsets[i] > sortedOffsets[j] + return a > b } - return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]] + return ca > cb }) - if len(sortedOffsets) > 3 { - if debug { - print("Offsets:") - for i, v := range sortedOffsets { - if i > 20 { - break - } - printf("[%d: %d],", v, newOffsets[v]) + if debug { + print("Offsets:") + for i, v := range sortedOffsets { + if i > 20 { + break } - println("") + printf("[%d: %d],", v, newOffsets[v]) + } + println("") + } + // Dictionary recent-offsets must be three positive values within the + // history. Ranked matches may be fewer (or empty when only unset + // repeat codes were seen), so fill remaining slots with defaults. + used := make(map[int]bool, 3) + var finalOffsets [3]int + nOff := 0 + for _, v := range sortedOffsets { + iv := int(v) + if iv <= 0 || iv > len(hist) || used[iv] { + continue + } + finalOffsets[nOff] = iv + used[iv] = true + nOff++ + if nOff == 3 { + break } - - sortedOffsets = sortedOffsets[:3] } - for i, v := range sortedOffsets { - o.Offsets[i] = int(v) + for _, def := range []int{1, 4, 8} { + if nOff == 3 { + break + } + if def <= len(hist) && !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + for def := 1; nOff < 3 && def <= len(hist); def++ { + if !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + if nOff < 3 { + return nil, fmt.Errorf("could not determine 3 valid dictionary offsets (history size %d)", len(hist)) } + o.Offsets = finalOffsets if debug { println("New repeat offsets", o.Offsets) } @@ -337,6 +378,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if nUsed == 0 || seqs == 0 { return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs) } + if litTotal == 0 { + return nil, errors.New("0 literals found") + } if debug { println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal) } @@ -517,11 +561,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1]))) out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2]))) out.Write(hist) + if _, err := loadDict(out.Bytes()); err != nil { + return nil, fmt.Errorf("built dictionary failed validation: %w", err) + } if debug { - _, err := loadDict(out.Bytes()) - if err != nil { - panic(err) - } i, err := InspectDictionary(out.Bytes()) if err != nil { panic(err) diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index 3fc381c7a7..4d3188ff49 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -2081,7 +2081,7 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (AX)(R13*1), R14 + LEAQ 16(AX)(R13*1), R14 ADDQ R10, R14 CMPQ R14, 32(SP) JA error_not_enough_space @@ -2601,7 +2601,7 @@ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (CX)(R13*1), R14 + LEAQ 16(CX)(R13*1), R14 ADDQ R9, R14 CMPQ R14, 32(SP) JA error_not_enough_space diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s index a468e5fc2c..6f54ef21ba 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s @@ -12,7 +12,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -24,7 +24,7 @@ TEXT ·sequenceDecs_decode_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -60,7 +60,8 @@ sequenceDecs_decode_amd64_fill_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_of_update_zero @@ -81,7 +82,8 @@ sequenceDecs_decode_amd64_of_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_ml_update_zero @@ -131,7 +133,8 @@ sequenceDecs_decode_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_amd64_ll_update_zero @@ -148,7 +151,7 @@ sequenceDecs_decode_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) + MOVD R13, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -166,7 +169,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -187,7 +190,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -208,7 +211,7 @@ sequenceDecs_decode_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -360,7 +363,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 @@ -372,7 +375,7 @@ TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 MOVD 160(R0), R12 sequenceDecs_decode_56_amd64_main_loop: - MOVD (RSP), R13 + MOVD 8(RSP), R13 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -408,7 +411,8 @@ sequenceDecs_decode_56_amd64_fill_end: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_of_update_zero @@ -429,7 +433,8 @@ sequenceDecs_decode_56_amd64_of_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_ml_update_zero @@ -450,7 +455,8 @@ sequenceDecs_decode_56_amd64_ml_update_zero: MOVD R3, R1 MOVD R2, R14 LSL R1, R14, R14 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decode_56_amd64_ll_update_zero @@ -467,7 +473,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: MOVD R0, (R9) // Fill bitreader for state updates - MOVD R13, (RSP) + MOVD R13, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -485,7 +491,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -506,7 +512,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -527,7 +533,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero: NEG R1, R16 ROR R16, R14, R14 MOVD $0x00000001, R4 - MOVB R13, R1 + BFI $0, R13, $8, R1 LSLW R1, R4, R4 SUBW $1, R4, R4 AND R4, R14, R14 @@ -766,13 +772,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -834,24 +841,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -906,12 +916,13 @@ copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -1016,24 +1027,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R5), R13 - ADD R10, R5, R15 - MOVB -1(R15), R14 - MOVB R13, (R3) - ADD R10, R3, R15 - MOVB R14, -1(R15) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVBU (R5), R16 + BFI $0, R16, $8, R13 + ADD R10, R5, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R3) + ADD R10, R3, R15 + MOVB R14, -1(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_3: - MOVH (R5), R13 - MOVB 2(R5), R14 - MOVH R13, (R3) - MOVB R14, 2(R3) - ADD R10, R5, R5 - ADD R10, R3, R3 - JMP copy_1_end + MOVHU (R5), R13 + MOVBU 2(R5), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R3) + MOVB R14, 2(R3) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end copy_1_move_4through7: MOVWU (R5), R13 @@ -1104,13 +1118,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R10 - MOVB 2(R13), R11 - MOVH R10, (R3) - MOVB R11, 2(R3) - ADD R12, R13, R13 - ADD R12, R3, R3 - JMP copy_4_end + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R10 @@ -1172,24 +1187,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R10, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R3) - ADD R10, R3, R15 - MOVB R4, -1(R15) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R3) - MOVB R4, 2(R3) - ADD R10, R13, R13 - ADD R10, R3, R3 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1257,24 +1275,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R10), R11 - ADD R12, R10, R15 - MOVB -1(R15), R13 - MOVB R11, (R3) - ADD R12, R3, R15 - MOVB R13, -1(R15) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + ADD R12, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R11, (R3) + ADD R12, R3, R15 + MOVB R13, -1(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_3: - MOVH (R10), R11 - MOVB 2(R10), R13 - MOVH R11, (R3) - MOVB R13, 2(R3) - ADD R12, R10, R10 - ADD R12, R3, R3 - JMP copy_2_end + MOVHU (R10), R11 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R13 + MOVH R11, (R3) + MOVB R13, 2(R3) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end copy_2_move_4through7: MOVWU (R10), R11 @@ -1305,12 +1326,13 @@ copy_overlapping_match: ADD R12, R6, R6 copy_slow_3: - MOVB (R10), R11 - MOVB R11, (R3) - ADD $1, R10, R10 - ADD $1, R3, R3 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: ADD $0x18, R0, R0 @@ -1361,41 +1383,41 @@ TEXT ·sequenceDecs_decodeSync_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -1431,7 +1453,8 @@ sequenceDecs_decodeSync_amd64_fill_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_of_update_zero @@ -1445,14 +1468,15 @@ sequenceDecs_decodeSync_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_ml_update_zero @@ -1466,7 +1490,7 @@ sequenceDecs_decodeSync_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -1502,7 +1526,8 @@ sequenceDecs_decodeSync_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_amd64_ll_update_zero @@ -1516,10 +1541,10 @@ sequenceDecs_decodeSync_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) + MOVD R12, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -1537,7 +1562,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1558,7 +1583,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1579,7 +1604,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -1594,7 +1619,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero: sequenceDecs_decodeSync_amd64_skip_update: // Adjust offset MOVD s+0(FP), R1 - MOVD 8(RSP), R12 + MOVD 16(RSP), R12 CMP $0x01, R0 BLS sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 ADD $144, R1, R15 @@ -1605,7 +1630,7 @@ sequenceDecs_decodeSync_amd64_skip_update: JMP sequenceDecs_decodeSync_amd64_after_adjust sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -1643,11 +1668,11 @@ sequenceDecs_decodeSync_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -1666,14 +1691,15 @@ sequenceDecs_decodeSync_amd64_after_adjust: BNE sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 + ADD $16, R13, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -1697,11 +1723,11 @@ copy_1: // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -1709,7 +1735,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -1742,13 +1768,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -1807,24 +1834,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -1879,12 +1909,13 @@ copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -1913,7 +1944,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -1923,7 +1954,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -1932,7 +1963,7 @@ sequenceDecs_decodeSync_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -1942,7 +1973,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -1957,9 +1988,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 @@ -1977,41 +2008,41 @@ TEXT ·sequenceDecs_decodeSync_safe_arm64(SB), $64-32 MOVD (R1), R0 MOVD 32(R1), R5 ADD R5, R0, R0 - MOVD R0, (RSP) + MOVD R0, 8(RSP) MOVD ctx+16(FP), R0 MOVD 72(R0), R6 MOVD 80(R0), R7 MOVD 88(R0), R8 MOVD $0, R1 - MOVD R1, 8(RSP) MOVD R1, 16(RSP) MOVD R1, 24(RSP) + MOVD R1, 32(RSP) MOVD 112(R0), R9 MOVD 128(R0), R1 - MOVD R1, 32(RSP) + MOVD R1, 40(RSP) MOVD 144(R0), R10 MOVD 136(R0), R11 MOVD 200(R0), R1 - MOVD R1, 56(RSP) + MOVD R1, 64(RSP) MOVD 176(R0), R1 - MOVD R1, 48(RSP) + MOVD R1, 56(RSP) MOVD 184(R0), R0 - MOVD R0, 40(RSP) - MOVD 40(RSP), R0 - MOVD 48(RSP), R16 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 ADD R0, R16, R16 - MOVD R16, 48(RSP) + MOVD R16, 56(RSP) // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 ADD R9, R16, R16 - MOVD R16, 32(RSP) + MOVD R16, 40(RSP) // outBase += outPosition ADD R11, R9, R9 sequenceDecs_decodeSync_safe_amd64_main_loop: - MOVD (RSP), R12 + MOVD 8(RSP), R12 // Fill bitreader to have enough for the offset and match length. CMP $0x08, R5 @@ -2047,7 +2078,8 @@ sequenceDecs_decodeSync_safe_amd64_fill_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_of_update_zero @@ -2061,14 +2093,15 @@ sequenceDecs_decodeSync_safe_amd64_fill_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_of_update_zero: - MOVD R0, 8(RSP) + MOVD R0, 16(RSP) // Update match length MOVD R7, R0 MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_ml_update_zero @@ -2082,7 +2115,7 @@ sequenceDecs_decodeSync_safe_amd64_of_update_zero: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ml_update_zero: - MOVD R0, 16(RSP) + MOVD R0, 24(RSP) // Fill bitreader to have enough for the remaining CMP $0x08, R5 @@ -2118,7 +2151,8 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_end: MOVD R3, R1 MOVD R2, R13 LSL R1, R13, R13 - UBFX $8, R0, $8, R1 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 LSR $0x20, R0, R0 TST R1, R1 BEQ sequenceDecs_decodeSync_safe_amd64_ll_update_zero @@ -2132,10 +2166,10 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_end: ADD R13, R0, R0 sequenceDecs_decodeSync_safe_amd64_ll_update_zero: - MOVD R0, 24(RSP) + MOVD R0, 32(RSP) // Fill bitreader for state updates - MOVD R12, (RSP) + MOVD R12, 8(RSP) MOVD R8, R0 LSR $0x08, R0, R0 MOVBU R0, R0 @@ -2153,7 +2187,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2174,7 +2208,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2195,7 +2229,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: NEG R1, R16 ROR R16, R13, R13 MOVD $0x00000001, R14 - MOVB R12, R1 + BFI $0, R12, $8, R1 LSLW R1, R14, R14 SUBW $1, R14, R14 AND R14, R13, R13 @@ -2210,7 +2244,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero: sequenceDecs_decodeSync_safe_amd64_skip_update: // Adjust offset MOVD s+0(FP), R1 - MOVD 8(RSP), R12 + MOVD 16(RSP), R12 CMP $0x01, R0 BLS sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 ADD $144, R1, R15 @@ -2221,7 +2255,7 @@ sequenceDecs_decodeSync_safe_amd64_skip_update: JMP sequenceDecs_decodeSync_safe_amd64_after_adjust sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: - MOVD 24(RSP), R16 + MOVD 32(RSP), R16 CMP $0x00000000, R16 BNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero ADD $1, R12, R12 @@ -2259,11 +2293,11 @@ sequenceDecs_decodeSync_safe_amd64_adjust_skip: MOVD R13, R12 sequenceDecs_decodeSync_safe_amd64_after_adjust: - MOVD R12, 8(RSP) + MOVD R12, 16(RSP) // Check values - MOVD 16(RSP), R0 - MOVD 24(RSP), R1 + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 ADD R1, R0, R13 MOVD s+0(FP), R14 MOVD 256(R14), R16 @@ -2282,14 +2316,14 @@ sequenceDecs_decodeSync_safe_amd64_after_adjust: BNE sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: - MOVD 24(RSP), R0 - MOVD 8(RSP), R1 - MOVD 16(RSP), R12 + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 // Check if we have enough space in s.out ADD R12, R0, R13 ADD R9, R13, R13 - MOVD 32(RSP), R16 + MOVD 40(RSP), R16 CMP R16, R13 BHI error_not_enough_space @@ -2326,24 +2360,27 @@ copy_1_small: JMP copy_1_move_8through16 copy_1_move_1or2: - MOVB (R10), R13 - ADD R0, R10, R15 - MOVB -1(R15), R14 - MOVB R13, (R9) - ADD R0, R9, R15 - MOVB R14, -1(R15) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVBU (R10), R16 + BFI $0, R16, $8, R13 + ADD R0, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R9) + ADD R0, R9, R15 + MOVB R14, -1(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_3: - MOVH (R10), R13 - MOVB 2(R10), R14 - MOVH R13, (R9) - MOVB R14, 2(R9) - ADD R0, R10, R10 - ADD R0, R9, R9 - JMP copy_1_end + MOVHU (R10), R13 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R9) + MOVB R14, 2(R9) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end copy_1_move_4through7: MOVWU (R10), R13 @@ -2372,11 +2409,11 @@ copy_1_end: // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) check_offset: MOVD R11, R0 - MOVD 40(RSP), R16 + MOVD 48(RSP), R16 ADD R16, R0, R0 CMP R0, R1 BGT error_match_off_too_big - MOVD 56(RSP), R16 + MOVD 64(RSP), R16 CMP R16, R1 BGT error_match_off_too_big @@ -2384,7 +2421,7 @@ check_offset: MOVD R1, R0 SUBS R11, R0, R0 BLS copy_match - MOVD 48(RSP), R13 + MOVD 56(RSP), R13 SUB R0, R13, R13 CMP R0, R12 BGT copy_all_from_history @@ -2417,13 +2454,14 @@ copy_4_small: JMP copy_4_move_8through16 copy_4_move_3: - MOVH (R13), R0 - MOVB 2(R13), R1 - MOVH R0, (R9) - MOVB R1, 2(R9) - ADD R12, R13, R13 - ADD R12, R9, R9 - JMP copy_4_end + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end copy_4_move_4through7: MOVWU (R13), R0 @@ -2482,24 +2520,27 @@ copy_5_small: JMP copy_5_move_8through16 copy_5_move_1or2: - MOVB (R13), R14 - ADD R0, R13, R15 - MOVB -1(R15), R4 - MOVB R14, (R9) - ADD R0, R9, R15 - MOVB R4, -1(R15) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_3: - MOVH (R13), R14 - MOVB 2(R13), R4 - MOVH R14, (R9) - MOVB R4, 2(R9) - ADD R0, R13, R13 - ADD R0, R9, R9 - JMP copy_5_end + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end copy_5_move_4through7: MOVWU (R13), R14 @@ -2567,24 +2608,27 @@ copy_2_small: JMP copy_2_move_8through16 copy_2_move_1or2: - MOVB (R0), R1 - ADD R12, R0, R15 - MOVB -1(R15), R13 - MOVB R1, (R9) - ADD R12, R9, R15 - MOVB R13, -1(R15) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + ADD R12, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R1, (R9) + ADD R12, R9, R15 + MOVB R13, -1(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_3: - MOVH (R0), R1 - MOVB 2(R0), R13 - MOVH R1, (R9) - MOVB R13, 2(R9) - ADD R12, R0, R0 - ADD R12, R9, R9 - JMP copy_2_end + MOVHU (R0), R1 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R13 + MOVH R1, (R9) + MOVB R13, 2(R9) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end copy_2_move_4through7: MOVWU (R0), R1 @@ -2615,12 +2659,13 @@ copy_overlapping_match: ADD R12, R11, R11 copy_slow_3: - MOVB (R0), R1 - MOVB R1, (R9) - ADD $1, R0, R0 - ADD $1, R9, R9 - SUBS $1, R12, R12 - BNE copy_slow_3 + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 handle_loop: MOVD ctx+16(FP), R0 @@ -2649,7 +2694,7 @@ loop_finished: // Return with match length error sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: - MOVD 16(RSP), R0 + MOVD 24(RSP), R0 MOVD ctx+16(FP), R1 MOVD R0, 216(R1) MOVD $0x00000001, R16 @@ -2659,7 +2704,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: // Return with match too long error sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: MOVD ctx+16(FP), R0 - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD $0x00000002, R16 MOVD R16, ret+24(FP) @@ -2668,7 +2713,7 @@ sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: // Return with match offset too long error error_match_off_too_big: MOVD ctx+16(FP), R0 - MOVD 8(RSP), R1 + MOVD 16(RSP), R1 MOVD R1, 224(R0) MOVD R11, 136(R0) MOVD $0x00000003, R16 @@ -2678,7 +2723,7 @@ error_match_off_too_big: // Return with not enough literals error error_not_enough_literals: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) MOVD $0x00000004, R16 MOVD R16, ret+24(FP) @@ -2693,9 +2738,9 @@ error_overread: // Return with not enough output space error error_not_enough_space: MOVD ctx+16(FP), R0 - MOVD 24(RSP), R1 + MOVD 32(RSP), R1 MOVD R1, 208(R0) - MOVD 16(RSP), R1 + MOVD 24(RSP), R1 MOVD R1, 216(R0) MOVD R11, 136(R0) MOVD $0x00000005, R16 diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go index 55405f3914..42ce5de716 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go @@ -77,6 +77,35 @@ const errorNotEnoughSpace = 5 // error reported when bits are overread. const errorOverread = 6 +// useSafeDecodeSync reports whether decodeSyncSimple must use the bounds-exact +// ("safe") copy variants for the current buffer geometry. +// +// When the output and literal buffers have compressedBlockOverAlloc (16) +// bytes of slack past their logical use, the assembly may use extended +// memory copies that read and write in 16-byte blocks, overrunning the end +// of a literal run or match by up to 15 bytes. Otherwise it must use the +// bounds-exact ("safe") copies. This mirrors the analogous, always-dynamic +// selection in executeSimple below. +// +// The unsafe copies were disabled in #644 (2022) as a mitigation for a +// crash, but that crash's root cause — an unguarded bitReader overread that +// produced out-of-range match offsets/lengths — was fixed three days later +// in #645, which also added the fuzz corpus that has guarded this path since. +// See #1168. An asan-instrumented fuzz job (see .github/workflows/go.yml) +// covers the extended-copy path, which -race and plain fuzzing cannot. +func (s *sequenceDecs) useSafeDecodeSync() bool { + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + return true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + return true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + return true + } + return false +} + // decode sequences from the stream with the provided history but without a dictionary. func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { if len(s.dict) > 0 { @@ -86,9 +115,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { return false, nil } - // FIXME: Using unsafe memory copies leads to rare, random crashes - // with fuzz testing. It is therefore disabled for now. - const useSafe = true + useSafe := s.useSafeDecodeSync() br := s.br diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go index c592f6ad5f..a19a89279c 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -84,7 +84,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -124,7 +124,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Errorf(t, err, "error message %s", "formatted") @@ -144,8 +144,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -190,10 +190,10 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// assert.EventuallyWithTf(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -552,7 +552,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool return NoDirExists(t, path, append([]interface{}{msg}, args...)...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoErrorf(t, err, "error message %s", "formatted") { @@ -849,7 +849,19 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 58db928450..cd2a86061c 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -146,7 +146,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs return Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -158,7 +158,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... return EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -240,7 +240,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string return Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -269,8 +269,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. return ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -281,8 +281,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . return ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -311,7 +311,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter return ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -372,10 +372,10 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor // time.Sleep(8*time.Second) // externalValue = true // }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// a.EventuallyWithTf(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1096,7 +1096,7 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) return NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoError(err) { @@ -1109,7 +1109,7 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoErrorf(err, "error message %s", "formatted") { @@ -1690,7 +1690,19 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti return WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1698,7 +1710,19 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf return YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go index 2fdf80fdd3..a44b40ed3f 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -9,7 +9,7 @@ import ( func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { - return false + return Fail(t, fmt.Sprintf("object %T is not an ordered collection", object), msgAndArgs...) } objValue := reflect.ValueOf(object) @@ -50,6 +50,9 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR // assert.IsIncreasing(t, []float{1, 2}) // assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } @@ -59,6 +62,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonIncreasing(t, []float{2, 1}) // assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } @@ -68,6 +74,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // assert.IsDecreasing(t, []float{2, 1}) // assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } @@ -77,5 +86,8 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonDecreasing(t, []float{1, 2}) // assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index de8de0cb6c..1419e47761 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -17,11 +17,10 @@ import ( "unicode" "unicode/utf8" - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" - // Wrapper around gopkg.in/yaml.v3 "github.com/stretchr/testify/assert/yaml" + "github.com/stretchr/testify/internal/difflib" + "github.com/stretchr/testify/internal/spew" ) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" @@ -33,19 +32,19 @@ type TestingT interface { // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful // for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool +type ComparisonAssertionFunc = func(TestingT, interface{}, interface{}, ...interface{}) bool // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful // for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool +type ValueAssertionFunc = func(TestingT, interface{}, ...interface{}) bool // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful // for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool +type BoolAssertionFunc = func(TestingT, bool, ...interface{}) bool // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool +type ErrorAssertionFunc = func(TestingT, error, ...interface{}) bool // PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful // for table driven tests. @@ -325,13 +324,15 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { func indentMessageLines(message string, longestLabelLen int) string { outBuf := new(bytes.Buffer) - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + scanner := bufio.NewScanner(strings.NewReader(message)) + for firstLine := true; scanner.Scan(); firstLine = false { + if !firstLine { + fmt.Fprint(outBuf, "\n\t"+strings.Repeat(" ", longestLabelLen+1)+"\t") } - outBuf.WriteString(scanner.Text()) + fmt.Fprint(outBuf, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return fmt.Sprintf("cannot display message: %s", err) } return outBuf.String() @@ -544,9 +545,8 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b if !same { // both are pointers but not the same type & pointing to the same address return Fail(t, fmt.Sprintf("Not same: \n"+ - "expected: %p %#[1]v\n"+ - "actual : %p %#[2]v", - expected, actual), msgAndArgs...) + "expected: %[2]s (%[1]T)(%[1]p)\n"+ + "actual : %[4]s (%[3]T)(%[3]p)", expected, truncatingFormat("%#v", expected), actual, truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -571,8 +571,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} if same { return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#[1]v", - expected), msgAndArgs...) + "Expected and actual point to the same object: %p %s", + expected, truncatingFormat("%#v", expected)), msgAndArgs...) } return true } @@ -604,25 +604,26 @@ func samePointers(first, second interface{}) (same bool, ok bool) { // to a type conversion in the Go grammar. func formatUnequalValues(expected, actual interface{}) (e string, a string) { if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), - fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) + return fmt.Sprintf("%T(%s)", expected, truncatingFormat("%#v", expected)), + fmt.Sprintf("%T(%s)", actual, truncatingFormat("%#v", actual)) } switch expected.(type) { case time.Duration: return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) } - return truncatingFormat(expected), truncatingFormat(actual) + return truncatingFormat("%#v", expected), truncatingFormat("%#v", actual) } // truncatingFormat formats the data and truncates it if it's too long. // // This helps keep formatted error messages lines from exceeding the // bufio.MaxScanTokenSize max line length that the go testing framework imposes. -func truncatingFormat(data interface{}) string { - value := fmt.Sprintf("%#v", data) - max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. - if len(value) > max { - value = value[0:max] + "<... truncated>" +func truncatingFormat(format string, data interface{}) string { + value := fmt.Sprintf(format, data) + // Give us space for two truncated objects and the surrounding sentence. + maxMessageSize := bufio.MaxScanTokenSize/2 - 100 + if len(value) > maxMessageSize { + value = value[0:maxMessageSize] + "<... truncated>" } return value } @@ -743,7 +744,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected nil, but got: %s", truncatingFormat("%#v", object)), msgAndArgs...) } // isEmpty gets whether the specified object is considered empty or not. @@ -793,7 +794,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + Fail(t, fmt.Sprintf("Should be empty, but was %s", truncatingFormat("%v", object)), msgAndArgs...) } return pass @@ -836,11 +837,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) } l, ok := getLen(object) if !ok { - return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", truncatingFormat("%v", object)), msgAndArgs...) } if l != length { - return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q should have %d item(s), but has %d", truncatingFormat("%v", object), length, l), msgAndArgs...) } return true } @@ -889,7 +890,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ } if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -904,7 +905,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte } if ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -964,10 +965,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -986,10 +987,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s should not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -1031,10 +1032,10 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok av := actualMap.MapIndex(k) if !av.IsValid() { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } } @@ -1056,7 +1057,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", list), element), msgAndArgs...) } } @@ -1082,12 +1083,12 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) listKind := reflect.TypeOf(list).Kind() if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", list, listKind), msgAndArgs...) } subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", subset, subsetKind), msgAndArgs...) } if subsetKind == reflect.Map && listKind == reflect.Map { @@ -1106,7 +1107,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } subsetList := reflect.ValueOf(subset) @@ -1121,14 +1122,14 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { - return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { return true } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified @@ -1343,9 +1344,15 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . if !funcDidPanic { return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) } - panicErr, ok := panicValue.(error) - if !ok || panicErr.Error() != errString { - return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) + panicErr, isError := panicValue.(error) + if !isError || panicErr.Error() != errString { + msg := fmt.Sprintf("func %#v should panic with error message:\t%#v\n", f, errString) + if isError { + msg += fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) + } + msg += fmt.Sprintf("\tPanic value:\t%#v\n", panicValue) + msg += fmt.Sprintf("\tPanic stack:\t%s\n", panickedStack) + return Fail(t, msg, msgAndArgs...) } return true @@ -1624,7 +1631,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m Errors */ -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoError(t, err) { @@ -1635,13 +1642,13 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%s", truncatingFormat("%+v", err)), msgAndArgs...) } return true } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Error(t, err) @@ -1656,7 +1663,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { return true } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -1674,13 +1681,13 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte if expected != actual { return Fail(t, fmt.Sprintf("Error message not equal:\n"+ "expected: %q\n"+ - "actual : %q", expected, actual), msgAndArgs...) + "actual : %s", expected, truncatingFormat("%q", actual)), msgAndArgs...) } return true } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContains(t, err, expectedErrorSubString) @@ -1694,7 +1701,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in actual := theError.Error() if !strings.Contains(actual, contains) { - return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("Error %s does not contain %#v", truncatingFormat("%#v", actual), contains), msgAndArgs...) } return true @@ -1760,7 +1767,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { h.Helper() } if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should be zero, but was %s", truncatingFormat("%v", i)), msgAndArgs...) } return true } @@ -1874,7 +1881,19 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -2188,8 +2207,8 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ - "expected: %q\n"+ - "in chain: %s", expectedText, chain, + "expected: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2211,8 +2230,8 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %q\n"+ - "in chain: %s", expectedText, chain, + "found: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2236,7 +2255,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", expectedType, chain, + "in chain: %s", expectedType, truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2254,7 +2273,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ "found: %s\n"+ - "in chain: %s", reflect.TypeOf(target).Elem().String(), chain, + "in chain: %s", reflect.TypeOf(target).Elem().String(), truncatingFormat("%s", chain), ), msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go index a0b953aa5c..c111589c7e 100644 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -40,8 +40,8 @@ // // # Assertions // -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// Assertions allow you to easily write test code, and are global funcs in the assert package. +// All assertion functions take, as the first argument, the [*testing.T] object provided by the // testing framework. This allows the assertion funcs to write the failings and other details to // the correct place. // diff --git a/vendor/github.com/stretchr/testify/internal/difflib/LICENSE b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE new file mode 100644 index 0000000000..485be13c67 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/stretchr/testify/internal/difflib/difflib.go b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go new file mode 100644 index 0000000000..9984599b4f --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go @@ -0,0 +1,592 @@ +// Package difflib is a partial port of Python difflib module. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// The following class and functions have been ported: +// +// - SequenceMatcher +// +// - unified_diff +// +// Getting unified diffs was the main goal of the port. Keep in mind this code +// is mostly suitable to output text differences in a human friendly way, there +// are no guarantees generated diffs are consumable by patch(1). +// +// This package was adopted from [github.com/pmezard/go-difflib] which +// is no longer maintained. +// +// [github.com/pmezard/go-difflib]: https://github.com/pmezard/go-difflib +package difflib + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// +// and for all (i',j',k') meeting those conditions, +// +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/LICENSE b/vendor/github.com/stretchr/testify/internal/spew/LICENSE new file mode 100644 index 0000000000..bc52e96f2b --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/internal/spew/README.md b/vendor/github.com/stretchr/testify/internal/spew/README.md new file mode 100644 index 0000000000..51a909e2ef --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/README.md @@ -0,0 +1,12 @@ +go-spew +======= + +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) + +Go-spew implements a deep pretty printer for Go data structures to aid in +debugging. A comprehensive suite of tests with 100% test coverage is provided +to ensure proper functionality. + +## License + +Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypass.go b/vendor/github.com/stretchr/testify/internal/spew/bypass.go new file mode 100644 index 0000000000..70ddeaad3e --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypass.go @@ -0,0 +1,146 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is not running on Google App Engine, compiled by GopherJS, and +// "-tags safe" is not added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// Go versions prior to 1.4 are disabled because they use a different layout +// for interfaces which make the implementation of unsafeReflectValue more complex. +//go:build !js && !appengine && !safe && !disableunsafe && go1.4 +// +build !js,!appengine,!safe,!disableunsafe,go1.4 + +package spew + +import ( + "reflect" + "unsafe" +) + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = false + + // ptrSize is the size of a pointer on the current arch. + ptrSize = unsafe.Sizeof((*byte)(nil)) +) + +type flag uintptr + +var ( + // flagRO indicates whether the value field of a reflect.Value + // is read-only. + flagRO flag + + // flagAddr indicates whether the address of the reflect.Value's + // value may be taken. + flagAddr flag +) + +// flagKindMask holds the bits that make up the kind +// part of the flags field. In all the supported versions, +// it is in the lower 5 bits. +const flagKindMask = flag(0x1f) + +// Different versions of Go have used different +// bit layouts for the flags type. This table +// records the known combinations. +var okFlags = []struct { + ro, addr flag +}{{ + // From Go 1.4 to 1.5 + ro: 1 << 5, + addr: 1 << 7, +}, { + // Up to Go tip. + ro: 1<<5 | 1<<6, + addr: 1 << 8, +}} + +var flagValOffset = func() uintptr { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + return field.Offset +}() + +// flagField returns a pointer to the flag field of a reflect.Value. +func flagField(v *reflect.Value) *flag { + return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) +} + +// unsafeReflectValue converts the passed reflect.Value into a one that bypasses +// the typical safety restrictions preventing access to unaddressable and +// unexported data. It works by digging the raw pointer to the underlying +// value out of the protected value and generating a new unprotected (unsafe) +// reflect.Value to it. +// +// This allows us to check for implementations of the Stringer and error +// interfaces to be used for pretty printing ordinarily unaddressable and +// inaccessible values such as unexported struct fields. +func unsafeReflectValue(v reflect.Value) reflect.Value { + if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { + return v + } + flagFieldPtr := flagField(&v) + *flagFieldPtr &^= flagRO + *flagFieldPtr |= flagAddr + return v +} + +// Sanity checks against future reflect package changes +// to the type or semantics of the Value.flag field. +func init() { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { + panic("reflect.Value flag field has changed kind") + } + type t0 int + var t struct { + A t0 + // t0 will have flagEmbedRO set. + t0 + // a will have flagStickyRO set + a t0 + } + vA := reflect.ValueOf(t).FieldByName("A") + va := reflect.ValueOf(t).FieldByName("a") + vt0 := reflect.ValueOf(t).FieldByName("t0") + + // Infer flagRO from the difference between the flags + // for the (otherwise identical) fields in t. + flagPublic := *flagField(&vA) + flagWithRO := *flagField(&va) | *flagField(&vt0) + flagRO = flagPublic ^ flagWithRO + + // Infer flagAddr from the difference between a value + // taken from a pointer and not. + vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") + flagNoPtr := *flagField(&vA) + flagPtr := *flagField(&vPtrA) + flagAddr = flagNoPtr ^ flagPtr + + // Check that the inferred flags tally with one of the known versions. + for _, f := range okFlags { + if flagRO == f.ro && flagAddr == f.addr { + return + } + } + panic("reflect.Value read-only flag has changed semantics") +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go new file mode 100644 index 0000000000..5e2d890d6a --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is running on Google App Engine, compiled by GopherJS, or +// "-tags safe" is added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +//go:build js || appengine || safe || disableunsafe || !go1.4 +// +build js appengine safe disableunsafe !go1.4 + +package spew + +import "reflect" + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = true +) + +// unsafeReflectValue typically converts the passed reflect.Value into a one +// that bypasses the typical safety restrictions preventing access to +// unaddressable and unexported data. However, doing this relies on access to +// the unsafe package. This is a stub version which simply returns the passed +// reflect.Value when the unsafe package is not available. +func unsafeReflectValue(v reflect.Value) reflect.Value { + return v +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/common.go b/vendor/github.com/stretchr/testify/internal/spew/common.go new file mode 100644 index 0000000000..1be8ce9457 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/common.go @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "reflect" + "sort" + "strconv" +) + +// Some constants in the form of bytes to avoid string overhead. This mirrors +// the technique used in the fmt package. +var ( + panicBytes = []byte("(PANIC=") + plusBytes = []byte("+") + iBytes = []byte("i") + trueBytes = []byte("true") + falseBytes = []byte("false") + interfaceBytes = []byte("(interface {})") + commaNewlineBytes = []byte(",\n") + newlineBytes = []byte("\n") + openBraceBytes = []byte("{") + openBraceNewlineBytes = []byte("{\n") + closeBraceBytes = []byte("}") + asteriskBytes = []byte("*") + colonBytes = []byte(":") + colonSpaceBytes = []byte(": ") + openParenBytes = []byte("(") + closeParenBytes = []byte(")") + spaceBytes = []byte(" ") + pointerChainBytes = []byte("->") + nilAngleBytes = []byte("") + maxNewlineBytes = []byte("\n") + maxShortBytes = []byte("") + circularBytes = []byte("") + circularShortBytes = []byte("") + invalidAngleBytes = []byte("") + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + percentBytes = []byte("%") + precisionBytes = []byte(".") + openAngleBytes = []byte("<") + closeAngleBytes = []byte(">") + openMapBytes = []byte("map[") + closeMapBytes = []byte("]") + lenEqualsBytes = []byte("len=") + capEqualsBytes = []byte("cap=") +) + +// hexDigits is used to map a decimal value to a hex digit. +var hexDigits = "0123456789abcdef" + +// catchPanic handles any panics that might occur during the handleMethods +// calls. +func catchPanic(w io.Writer, v reflect.Value) { + if err := recover(); err != nil { + w.Write(panicBytes) + fmt.Fprintf(w, "%v", err) + w.Write(closeParenBytes) + } +} + +// handleMethods attempts to call the Error and String methods on the underlying +// type the passed reflect.Value represents and outputes the result to Writer w. +// +// It handles panics in any called methods by catching and displaying the error +// as the formatted value. +func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { + // We need an interface to check if the type implements the error or + // Stringer interface. However, the reflect package won't give us an + // interface on certain things like unexported struct fields in order + // to enforce visibility rules. We use unsafe, when it's available, + // to bypass these restrictions since this package does not mutate the + // values. + if !v.CanInterface() { + if UnsafeDisabled { + return false + } + + v = unsafeReflectValue(v) + } + + // Choose whether or not to do error and Stringer interface lookups against + // the base type or a pointer to the base type depending on settings. + // Technically calling one of these methods with a pointer receiver can + // mutate the value, however, types which choose to satisify an error or + // Stringer interface with a pointer receiver should not be mutating their + // state inside these interface methods. + if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { + v = unsafeReflectValue(v) + } + if v.CanAddr() { + v = v.Addr() + } + + // Is it an error or Stringer? + switch iface := v.Interface().(type) { + case error: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.Error())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + + w.Write([]byte(iface.Error())) + return true + + case fmt.Stringer: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.String())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + w.Write([]byte(iface.String())) + return true + } + return false +} + +// printBool outputs a boolean value as true or false to Writer w. +func printBool(w io.Writer, val bool) { + if val { + w.Write(trueBytes) + } else { + w.Write(falseBytes) + } +} + +// printInt outputs a signed integer value to Writer w. +func printInt(w io.Writer, val int64, base int) { + w.Write([]byte(strconv.FormatInt(val, base))) +} + +// printUint outputs an unsigned integer value to Writer w. +func printUint(w io.Writer, val uint64, base int) { + w.Write([]byte(strconv.FormatUint(val, base))) +} + +// printFloat outputs a floating point value using the specified precision, +// which is expected to be 32 or 64bit, to Writer w. +func printFloat(w io.Writer, val float64, precision int) { + w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) +} + +// printComplex outputs a complex value using the specified float precision +// for the real and imaginary parts to Writer w. +func printComplex(w io.Writer, c complex128, floatPrecision int) { + r := real(c) + w.Write(openParenBytes) + w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) + i := imag(c) + if i >= 0 { + w.Write(plusBytes) + } + w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) + w.Write(iBytes) + w.Write(closeParenBytes) +} + +// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' +// prefix to Writer w. +func printHexPtr(w io.Writer, p uintptr) { + // Null pointer. + num := uint64(p) + if num == 0 { + w.Write(nilAngleBytes) + return + } + + // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix + buf := make([]byte, 18) + + // It's simpler to construct the hex string right to left. + base := uint64(16) + i := len(buf) - 1 + for num >= base { + buf[i] = hexDigits[num%base] + num /= base + i-- + } + buf[i] = hexDigits[num] + + // Add '0x' prefix. + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + + // Strip unused leading bytes. + buf = buf[i:] + w.Write(buf) +} + +// valuesSorter implements sort.Interface to allow a slice of reflect.Value +// elements to be sorted. +type valuesSorter struct { + values []reflect.Value + strings []string // either nil or same len and values + cs *ConfigState +} + +// newValuesSorter initializes a valuesSorter instance, which holds a set of +// surrogate keys on which the data should be sorted. It uses flags in +// ConfigState to decide if and how to populate those surrogate keys. +func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { + vs := &valuesSorter{values: values, cs: cs} + if canSortSimply(vs.values[0].Kind()) { + return vs + } + if !cs.DisableMethods { + vs.strings = make([]string, len(values)) + for i := range vs.values { + b := bytes.Buffer{} + if !handleMethods(cs, &b, vs.values[i]) { + vs.strings = nil + break + } + vs.strings[i] = b.String() + } + } + if vs.strings == nil && cs.SpewKeys { + vs.strings = make([]string, len(values)) + for i := range vs.values { + vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) + } + } + return vs +} + +// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted +// directly, or whether it should be considered for sorting by surrogate keys +// (if the ConfigState allows it). +func canSortSimply(kind reflect.Kind) bool { + // This switch parallels valueSortLess, except for the default case. + switch kind { + case reflect.Bool: + return true + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return true + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Uintptr: + return true + case reflect.Array: + return true + } + return false +} + +// Len returns the number of values in the slice. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Len() int { + return len(s.values) +} + +// Swap swaps the values at the passed indices. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Swap(i, j int) { + s.values[i], s.values[j] = s.values[j], s.values[i] + if s.strings != nil { + s.strings[i], s.strings[j] = s.strings[j], s.strings[i] + } +} + +// valueSortLess returns whether the first value should sort before the second +// value. It is used by valueSorter.Less as part of the sort.Interface +// implementation. +func valueSortLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Bool: + return !a.Bool() && b.Bool() + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return a.Int() < b.Int() + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return a.Uint() < b.Uint() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.String: + return a.String() < b.String() + case reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Array: + // Compare the contents of both arrays. + l := a.Len() + for i := 0; i < l; i++ { + av := a.Index(i) + bv := b.Index(i) + if av.Interface() == bv.Interface() { + continue + } + return valueSortLess(av, bv) + } + } + return a.String() < b.String() +} + +// Less returns whether the value at index i should sort before the +// value at index j. It is part of the sort.Interface implementation. +func (s *valuesSorter) Less(i, j int) bool { + if s.strings == nil { + return valueSortLess(s.values[i], s.values[j]) + } + return s.strings[i] < s.strings[j] +} + +// sortValues is a sort function that handles both native types and any type that +// can be converted to error or Stringer. Other inputs are sorted according to +// their Value.String() value to ensure display stability. +func sortValues(values []reflect.Value, cs *ConfigState) { + if len(values) == 0 { + return + } + sort.Sort(newValuesSorter(values, cs)) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/config.go b/vendor/github.com/stretchr/testify/internal/spew/config.go new file mode 100644 index 0000000000..161895fc6d --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/config.go @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// ConfigState houses the configuration options used by spew to format and +// display values. There is a global instance, Config, that is used to control +// all top-level Formatter and Dump functionality. Each ConfigState instance +// provides methods equivalent to the top-level functions. +// +// The zero value for ConfigState provides no indentation. You would typically +// want to set it to a space or a tab. +// +// Alternatively, you can use NewDefaultConfig to get a ConfigState instance +// with default settings. See the documentation of NewDefaultConfig for default +// values. +type ConfigState struct { + // Indent specifies the string to use for each indentation level. The + // global config instance that all top-level functions use set this to a + // single space by default. If you would like more indentation, you might + // set this to a tab with "\t" or perhaps two spaces with " ". + Indent string + + // MaxDepth controls the maximum number of levels to descend into nested + // data structures. The default, 0, means there is no limit. + // + // NOTE: Circular data structures are properly detected, so it is not + // necessary to set this value unless you specifically want to limit deeply + // nested data structures. + MaxDepth int + + // DisableMethods specifies whether or not error and Stringer interfaces are + // invoked for types that implement them. + DisableMethods bool + + // DisablePointerMethods specifies whether or not to check for and invoke + // error and Stringer interfaces on types which only accept a pointer + // receiver when the current type is not a pointer. + // + // NOTE: This might be an unsafe action since calling one of these methods + // with a pointer receiver could technically mutate the value, however, + // in practice, types which choose to satisify an error or Stringer + // interface with a pointer receiver should not be mutating their state + // inside these interface methods. As a result, this option relies on + // access to the unsafe package, so it will not have any effect when + // running in environments without access to the unsafe package such as + // Google App Engine or with the "safe" build tag specified. + DisablePointerMethods bool + + // DisablePointerAddresses specifies whether to disable the printing of + // pointer addresses. This is useful when diffing data structures in tests. + DisablePointerAddresses bool + + // DisableCapacities specifies whether to disable the printing of capacities + // for arrays, slices, maps and channels. This is useful when diffing + // data structures in tests. + DisableCapacities bool + + // ContinueOnMethod specifies whether or not recursion should continue once + // a custom error or Stringer interface is invoked. The default, false, + // means it will print the results of invoking the custom error or Stringer + // interface and return immediately instead of continuing to recurse into + // the internals of the data type. + // + // NOTE: This flag does not have any effect if method invocation is disabled + // via the DisableMethods or DisablePointerMethods options. + ContinueOnMethod bool + + // SortKeys specifies map keys should be sorted before being printed. Use + // this to have a more deterministic, diffable output. Note that only + // native types (bool, int, uint, floats, uintptr and string) and types + // that support the error or Stringer interfaces (if methods are + // enabled) are supported, with other types sorted according to the + // reflect.Value.String() output which guarantees display stability. + SortKeys bool + + // SpewKeys specifies that, as a last resort attempt, map keys should + // be spewed to strings and sorted by those strings. This is only + // considered if SortKeys is true. + SpewKeys bool +} + +// Config is the active configuration of the top-level functions. +// The configuration can be changed by modifying the contents of spew.Config. +var Config = ConfigState{Indent: " "} + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the formatted string as a value that satisfies error. See NewFormatter +// for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, c.convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, c.convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, c.convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a Formatter interface returned by c.NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Print(a ...interface{}) (n int, err error) { + return fmt.Print(c.convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, c.convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Println(a ...interface{}) (n int, err error) { + return fmt.Println(c.convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprint(a ...interface{}) string { + return fmt.Sprint(c.convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, c.convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a Formatter interface returned by c.NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintln(a ...interface{}) string { + return fmt.Sprintln(c.convertArgs(a)...) +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +c.Printf, c.Println, or c.Printf. +*/ +func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(c, v) +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { + fdump(c, w, a...) +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by modifying the public members +of c. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func (c *ConfigState) Dump(a ...interface{}) { + fdump(c, os.Stdout, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func (c *ConfigState) Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(c, &buf, a...) + return buf.String() +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a spew Formatter interface using +// the ConfigState associated with s. +func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = newFormatter(c, arg) + } + return formatters +} + +// NewDefaultConfig returns a ConfigState with the following default settings. +// +// Indent: " " +// MaxDepth: 0 +// DisableMethods: false +// DisablePointerMethods: false +// ContinueOnMethod: false +// SortKeys: false +func NewDefaultConfig() *ConfigState { + return &ConfigState{Indent: " "} +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/doc.go b/vendor/github.com/stretchr/testify/internal/spew/doc.go new file mode 100644 index 0000000000..722e9aa791 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/doc.go @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package spew implements a deep pretty printer for Go data structures to aid in +debugging. + +A quick overview of the additional features spew provides over the built-in +printing facilities for Go data types are as follows: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output (only when using + Dump style) + +There are two different approaches spew allows for dumping Go data structures: + + - Dump style which prints with newlines, customizable indentation, + and additional debug information such as types and all pointer addresses + used to indirect to the final value + - A custom Formatter interface that integrates cleanly with the standard fmt + package and replaces %v, %+v, %#v, and %#+v to provide inline printing + similar to the default %v while providing the additional functionality + outlined above and passing unsupported format verbs such as %x and %q + along to fmt + +# Quick Start + +This section demonstrates how to quickly get started with spew. See the +sections below for further details on formatting and configuration options. + +To dump a variable with full newlines, indentation, type, and pointer +information use Dump, Fdump, or Sdump: + + spew.Dump(myVar1, myVar2, ...) + spew.Fdump(someWriter, myVar1, myVar2, ...) + str := spew.Sdump(myVar1, myVar2, ...) + +Alternatively, if you would prefer to use format strings with a compacted inline +printing style, use the convenience wrappers Printf, Fprintf, etc with +%v (most compact), %+v (adds pointer addresses), %#v (adds types), or +%#+v (adds types and pointer addresses): + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +# Configuration Options + +Configuration of spew is handled by fields in the ConfigState type. For +convenience, all of the top-level functions use a global state available +via the spew.Config global. + +It is also possible to create a ConfigState instance that provides methods +equivalent to the top-level functions. This allows concurrent configuration +options. See the ConfigState documentation for more details. + +The following configuration options are available: + + - Indent + String to use for each indentation level for Dump functions. + It is a single space by default. A popular alternative is "\t". + + - MaxDepth + Maximum number of levels to descend into nested data structures. + There is no limit by default. + + - DisableMethods + Disables invocation of error and Stringer interface methods. + Method invocation is enabled by default. + + - DisablePointerMethods + Disables invocation of error and Stringer interface methods on types + which only accept pointer receivers from non-pointer variables. + Pointer method invocation is enabled by default. + + - DisablePointerAddresses + DisablePointerAddresses specifies whether to disable the printing of + pointer addresses. This is useful when diffing data structures in tests. + + - DisableCapacities + DisableCapacities specifies whether to disable the printing of + capacities for arrays, slices, maps and channels. This is useful when + diffing data structures in tests. + + - ContinueOnMethod + Enables recursion into types after invoking error and Stringer interface + methods. Recursion after method invocation is disabled by default. + + - SortKeys + Specifies map keys should be sorted before being printed. Use + this to have a more deterministic, diffable output. Note that + only native types (bool, int, uint, floats, uintptr and string) + and types which implement error or Stringer interfaces are + supported with other types sorted according to the + reflect.Value.String() output which guarantees display + stability. Natural map order is used by default. + + - SpewKeys + Specifies that, as a last resort attempt, map keys should be + spewed to strings and sorted by those strings. This is only + considered if SortKeys is true. + +# Dump Usage + +Simply call spew.Dump with a list of variables you want to dump: + + spew.Dump(myVar1, myVar2, ...) + +You may also call spew.Fdump if you would prefer to output to an arbitrary +io.Writer. For example, to dump to standard error: + + spew.Fdump(os.Stderr, myVar1, myVar2, ...) + +A third option is to call spew.Sdump to get the formatted output as a string: + + str := spew.Sdump(myVar1, myVar2, ...) + +# Sample Dump Output + +See the Dump example for details on the setup of the types and variables being +shown here. + + (main.Foo) { + unexportedField: (*main.Bar)(0xf84002e210)({ + flag: (main.Flag) flagTwo, + data: (uintptr) + }), + ExportedField: (map[interface {}]interface {}) (len=1) { + (string) (len=3) "one": (bool) true + } + } + +Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C +command as shown. + + ([]uint8) (len=32 cap=32) { + 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | + 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| + 00000020 31 32 |12| + } + +# Custom Formatter + +Spew provides a custom formatter that implements the fmt.Formatter interface +so that it integrates cleanly with standard fmt package printing functions. The +formatter is useful for inline printing of smaller data types similar to the +standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +# Custom Formatter Usage + +The simplest way to make use of the spew custom formatter is to call one of the +convenience functions such as spew.Printf, spew.Println, or spew.Printf. The +functions have syntax you are most likely already familiar with: + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Println(myVar, myVar2) + spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +See the Index for the full list convenience functions. + +# Sample Formatter Output + +Double pointer to a uint8: + + %v: <**>5 + %+v: <**>(0xf8400420d0->0xf8400420c8)5 + %#v: (**uint8)5 + %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 + +Pointer to circular struct with a uint8 field and a pointer to itself: + + %v: <*>{1 <*>} + %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} + %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} + %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} + +See the Printf example for details on the setup of variables being shown +here. + +# Errors + +Since it is possible for custom Stringer/error interfaces to panic, spew +detects them and handles them internally by printing the panic information +inline with the output. Since spew is intended to provide deep pretty printing +capabilities on structures, it intentionally does not return any errors. +*/ +package spew diff --git a/vendor/github.com/stretchr/testify/internal/spew/dump.go b/vendor/github.com/stretchr/testify/internal/spew/dump.go new file mode 100644 index 0000000000..8323041a48 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/dump.go @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + // uint8Type is a reflect.Type representing a uint8. It is used to + // convert cgo types to uint8 slices for hexdumping. + uint8Type = reflect.TypeOf(uint8(0)) + + // cCharRE is a regular expression that matches a cgo char. + // It is used to detect character arrays to hexdump them. + cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) + + // cUnsignedCharRE is a regular expression that matches a cgo unsigned + // char. It is used to detect unsigned character arrays to hexdump + // them. + cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) + + // cUint8tCharRE is a regular expression that matches a cgo uint8_t. + // It is used to detect uint8_t arrays to hexdump them. + cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) +) + +// dumpState contains information about the state of a dump operation. +type dumpState struct { + w io.Writer + depth int + pointers map[uintptr]int + ignoreNextType bool + ignoreNextIndent bool + cs *ConfigState +} + +// indent performs indentation according to the depth level and cs.Indent +// option. +func (d *dumpState) indent() { + if d.ignoreNextIndent { + d.ignoreNextIndent = false + return + } + d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) +} + +// unpackValue returns values inside of non-nil interfaces when possible. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface && !v.IsNil() { + v = v.Elem() + } + return v +} + +// dumpPtr handles formatting of pointers by indirecting them as necessary. +func (d *dumpState) dumpPtr(v reflect.Value) { + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range d.pointers { + if depth >= d.depth { + delete(d.pointers, k) + } + } + + // Keep list of all dereferenced pointers to show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by dereferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := d.pointers[addr]; ok && pd < d.depth { + cycleFound = true + indirects-- + break + } + d.pointers[addr] = d.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type information. + d.w.Write(openParenBytes) + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) + d.w.Write([]byte(ve.Type().String())) + d.w.Write(closeParenBytes) + + // Display pointer information. + if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { + d.w.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + d.w.Write(pointerChainBytes) + } + printHexPtr(d.w, addr) + } + d.w.Write(closeParenBytes) + } + + // Display dereferenced value. + d.w.Write(openParenBytes) + switch { + case nilFound: + d.w.Write(nilAngleBytes) + + case cycleFound: + d.w.Write(circularBytes) + + default: + d.ignoreNextType = true + d.dump(ve) + } + d.w.Write(closeParenBytes) +} + +// dumpSlice handles formatting of arrays and slices. Byte (uint8 under +// reflection) arrays and slices are dumped in hexdump -C fashion. +func (d *dumpState) dumpSlice(v reflect.Value) { + // Determine whether this type should be hex dumped or not. Also, + // for types which should be hexdumped, try to use the underlying data + // first, then fall back to trying to convert them to a uint8 slice. + var buf []uint8 + doConvert := false + doHexDump := false + numEntries := v.Len() + if numEntries > 0 { + vt := v.Index(0).Type() + vts := vt.String() + switch { + // C types that need to be converted. + case cCharRE.MatchString(vts): + fallthrough + case cUnsignedCharRE.MatchString(vts): + fallthrough + case cUint8tCharRE.MatchString(vts): + doConvert = true + + // Try to use existing uint8 slices and fall back to converting + // and copying if that fails. + case vt.Kind() == reflect.Uint8: + // We need an addressable interface to convert the type + // to a byte slice. However, the reflect package won't + // give us an interface on certain things like + // unexported struct fields in order to enforce + // visibility rules. We use unsafe, when available, to + // bypass these restrictions since this package does not + // mutate the values. + vs := v + if !vs.CanInterface() || !vs.CanAddr() { + vs = unsafeReflectValue(vs) + } + if !UnsafeDisabled { + vs = vs.Slice(0, numEntries) + + // Use the existing uint8 slice if it can be + // type asserted. + iface := vs.Interface() + if slice, ok := iface.([]uint8); ok { + buf = slice + doHexDump = true + break + } + } + + // The underlying data needs to be converted if it can't + // be type asserted to a uint8 slice. + doConvert = true + } + + // Copy and convert the underlying type if needed. + if doConvert && vt.ConvertibleTo(uint8Type) { + // Convert and copy each element into a uint8 byte + // slice. + buf = make([]uint8, numEntries) + for i := 0; i < numEntries; i++ { + vv := v.Index(i) + buf[i] = uint8(vv.Convert(uint8Type).Uint()) + } + doHexDump = true + } + } + + // Hexdump the entire slice as needed. + if doHexDump { + indent := strings.Repeat(d.cs.Indent, d.depth) + str := indent + hex.Dump(buf) + str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.TrimRight(str, d.cs.Indent) + d.w.Write([]byte(str)) + return + } + + // Recursively call dump for each item. + for i := 0; i < numEntries; i++ { + d.dump(d.unpackValue(v.Index(i))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } +} + +// dump is the main workhorse for dumping a value. It uses the passed reflect +// value to figure out what kind of object we are dealing with and formats it +// appropriately. It is a recursive function, however circular data structures +// are detected and handled properly. +func (d *dumpState) dump(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + d.w.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + d.indent() + d.dumpPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !d.ignoreNextType { + d.indent() + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + d.ignoreNextType = false + + // Display length and capacity if the built-in len and cap functions + // work with the value's kind and the len/cap itself is non-zero. + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() + } + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { + d.w.Write(openParenBytes) + if valueLen != 0 { + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) + } + if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + + // Call Stringer/error interfaces if they exist and the handle methods flag + // is enabled + if !d.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(d.cs, d.w, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(d.w, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(d.w, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(d.w, v.Uint(), 10) + + case reflect.Float32: + printFloat(d.w, v.Float(), 32) + + case reflect.Float64: + printFloat(d.w, v.Float(), 64) + + case reflect.Complex64: + printComplex(d.w, v.Complex(), 32) + + case reflect.Complex128: + printComplex(d.w, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + d.dumpSlice(v) + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.String: + d.w.Write([]byte(strconv.Quote(v.String()))) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + d.w.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + numEntries := v.Len() + keys := v.MapKeys() + if d.cs.SortKeys { + sortValues(keys, d.cs) + } + for i, key := range keys { + d.dump(d.unpackValue(key)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.MapIndex(key))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Struct: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + vt := v.Type() + numFields := v.NumField() + for i := 0; i < numFields; i++ { + d.indent() + vtf := vt.Field(i) + d.w.Write([]byte(vtf.Name)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.Field(i))) + if i < (numFields - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(d.w, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(d.w, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it in case any new + // types are added. + default: + if v.CanInterface() { + fmt.Fprintf(d.w, "%v", v.Interface()) + } else { + fmt.Fprintf(d.w, "%v", v.String()) + } + } +} + +// fdump is a helper function to consolidate the logic from the various public +// methods which take varying writers and config states. +func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { + for _, arg := range a { + if arg == nil { + w.Write(interfaceBytes) + w.Write(spaceBytes) + w.Write(nilAngleBytes) + w.Write(newlineBytes) + continue + } + + d := dumpState{w: w, cs: cs} + d.pointers = make(map[uintptr]int) + d.dump(reflect.ValueOf(arg)) + d.w.Write(newlineBytes) + } +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func Fdump(w io.Writer, a ...interface{}) { + fdump(&Config, w, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(&Config, &buf, a...) + return buf.String() +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by an exported package global, +spew.Config. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func Dump(a ...interface{}) { + fdump(&Config, os.Stdout, a...) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/format.go b/vendor/github.com/stretchr/testify/internal/spew/format.go new file mode 100644 index 0000000000..b04edb7d7a --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/format.go @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" +) + +// supportedFlags is a list of all the character flags supported by fmt package. +const supportedFlags = "0-+# " + +// formatState implements the fmt.Formatter interface and contains information +// about the state of a formatting operation. The NewFormatter function can +// be used to get a new Formatter which can be used directly as arguments +// in standard fmt package printing calls. +type formatState struct { + value interface{} + fs fmt.State + depth int + pointers map[uintptr]int + ignoreNextType bool + cs *ConfigState +} + +// buildDefaultFormat recreates the original format string without precision +// and width information to pass in to fmt.Sprintf in the case of an +// unrecognized type. Unless new types are added to the language, this +// function won't ever be called. +func (f *formatState) buildDefaultFormat() (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + buf.WriteRune('v') + + format = buf.String() + return format +} + +// constructOrigFormat recreates the original format string including precision +// and width information to pass along to the standard fmt package. This allows +// automatic deferral of all format strings this package doesn't support. +func (f *formatState) constructOrigFormat(verb rune) (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + if width, ok := f.fs.Width(); ok { + buf.WriteString(strconv.Itoa(width)) + } + + if precision, ok := f.fs.Precision(); ok { + buf.Write(precisionBytes) + buf.WriteString(strconv.Itoa(precision)) + } + + buf.WriteRune(verb) + + format = buf.String() + return format +} + +// unpackValue returns values inside of non-nil interfaces when possible and +// ensures that types for values which have been unpacked from an interface +// are displayed when the show types flag is also set. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (f *formatState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface { + f.ignoreNextType = false + if !v.IsNil() { + v = v.Elem() + } + } + return v +} + +// formatPtr handles formatting of pointers by indirecting them as necessary. +func (f *formatState) formatPtr(v reflect.Value) { + // Display nil if top level pointer is nil. + showTypes := f.fs.Flag('#') + if v.IsNil() && (!showTypes || f.ignoreNextType) { + f.fs.Write(nilAngleBytes) + return + } + + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range f.pointers { + if depth >= f.depth { + delete(f.pointers, k) + } + } + + // Keep list of all dereferenced pointers to possibly show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by derferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := f.pointers[addr]; ok && pd < f.depth { + cycleFound = true + indirects-- + break + } + f.pointers[addr] = f.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type or indirection level depending on flags. + if showTypes && !f.ignoreNextType { + f.fs.Write(openParenBytes) + f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) + f.fs.Write([]byte(ve.Type().String())) + f.fs.Write(closeParenBytes) + } else { + if nilFound || cycleFound { + indirects += strings.Count(ve.Type().String(), "*") + } + f.fs.Write(openAngleBytes) + f.fs.Write([]byte(strings.Repeat("*", indirects))) + f.fs.Write(closeAngleBytes) + } + + // Display pointer information depending on flags. + if f.fs.Flag('+') && (len(pointerChain) > 0) { + f.fs.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + f.fs.Write(pointerChainBytes) + } + printHexPtr(f.fs, addr) + } + f.fs.Write(closeParenBytes) + } + + // Display dereferenced value. + switch { + case nilFound: + f.fs.Write(nilAngleBytes) + + case cycleFound: + f.fs.Write(circularShortBytes) + + default: + f.ignoreNextType = true + f.format(ve) + } +} + +// format is the main workhorse for providing the Formatter interface. It +// uses the passed reflect value to figure out what kind of object we are +// dealing with and formats it appropriately. It is a recursive function, +// however circular data structures are detected and handled properly. +func (f *formatState) format(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + f.fs.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + f.formatPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !f.ignoreNextType && f.fs.Flag('#') { + f.fs.Write(openParenBytes) + f.fs.Write([]byte(v.Type().String())) + f.fs.Write(closeParenBytes) + } + f.ignoreNextType = false + + // Call Stringer/error interfaces if they exist and the handle methods + // flag is enabled. + if !f.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(f.cs, f.fs, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(f.fs, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(f.fs, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(f.fs, v.Uint(), 10) + + case reflect.Float32: + printFloat(f.fs, v.Float(), 32) + + case reflect.Float64: + printFloat(f.fs, v.Float(), 64) + + case reflect.Complex64: + printComplex(f.fs, v.Complex(), 32) + + case reflect.Complex128: + printComplex(f.fs, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + f.fs.Write(openBracketBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + numEntries := v.Len() + for i := 0; i < numEntries; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(v.Index(i))) + } + } + f.depth-- + f.fs.Write(closeBracketBytes) + + case reflect.String: + f.fs.Write([]byte(v.String())) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + f.fs.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + + f.fs.Write(openMapBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + keys := v.MapKeys() + if f.cs.SortKeys { + sortValues(keys, f.cs) + } + for i, key := range keys { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(key)) + f.fs.Write(colonBytes) + f.ignoreNextType = true + f.format(f.unpackValue(v.MapIndex(key))) + } + } + f.depth-- + f.fs.Write(closeMapBytes) + + case reflect.Struct: + numFields := v.NumField() + f.fs.Write(openBraceBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + vt := v.Type() + for i := 0; i < numFields; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + vtf := vt.Field(i) + if f.fs.Flag('+') || f.fs.Flag('#') { + f.fs.Write([]byte(vtf.Name)) + f.fs.Write(colonBytes) + } + f.format(f.unpackValue(v.Field(i))) + } + } + f.depth-- + f.fs.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(f.fs, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(f.fs, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it if any get added. + default: + format := f.buildDefaultFormat() + if v.CanInterface() { + fmt.Fprintf(f.fs, format, v.Interface()) + } else { + fmt.Fprintf(f.fs, format, v.String()) + } + } +} + +// Format satisfies the fmt.Formatter interface. See NewFormatter for usage +// details. +func (f *formatState) Format(fs fmt.State, verb rune) { + f.fs = fs + + // Use standard formatting for verbs that are not v. + if verb != 'v' { + format := f.constructOrigFormat(verb) + fmt.Fprintf(fs, format, f.value) + return + } + + if f.value == nil { + if fs.Flag('#') { + fs.Write(interfaceBytes) + } + fs.Write(nilAngleBytes) + return + } + + f.format(reflect.ValueOf(f.value)) +} + +// newFormatter is a helper function to consolidate the logic from the various +// public methods which take varying config states. +func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { + fs := &formatState{value: v, cs: cs} + fs.pointers = make(map[uintptr]int) + return fs +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +Printf, Println, or Fprintf. +*/ +func NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(&Config, v) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/spew.go b/vendor/github.com/stretchr/testify/internal/spew/spew.go new file mode 100644 index 0000000000..32c0e33882 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/spew.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "fmt" + "io" +) + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the formatted string as a value that satisfies error. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a default Formatter interface returned by NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) +func Print(a ...interface{}) (n int, err error) { + return fmt.Print(convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) +func Println(a ...interface{}) (n int, err error) { + return fmt.Println(convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprint(a ...interface{}) string { + return fmt.Sprint(convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintln(a ...interface{}) string { + return fmt.Sprintln(convertArgs(a)...) +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a default spew Formatter interface. +func convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = NewFormatter(arg) + } + return formatters +} diff --git a/vendor/github.com/stretchr/testify/require/doc.go b/vendor/github.com/stretchr/testify/require/doc.go index c8e3f94a80..ee84cc4791 100644 --- a/vendor/github.com/stretchr/testify/require/doc.go +++ b/vendor/github.com/stretchr/testify/require/doc.go @@ -1,4 +1,4 @@ -// Package require implements the same assertions as the `assert` package but +// Package require implements the same assertions as the assert package but // stops test execution when a test fails. // // # Example Usage @@ -21,8 +21,8 @@ // // # Assertions // -// The `require` package have same global functions as in the `assert` package, -// but instead of returning a boolean result they call `t.FailNow()`. +// The require package have same global functions as in the assert package, +// but instead of returning a boolean result they call [testing.T.FailNow]. // A consequence of this is that it must be called from the goroutine running // the test function, not from other goroutines created during the test. // diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go index 2d02f9bcef..652871f2eb 100644 --- a/vendor/github.com/stretchr/testify/require/require.go +++ b/vendor/github.com/stretchr/testify/require/require.go @@ -180,7 +180,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i t.FailNow() } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -195,7 +195,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte t.FailNow() } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -295,7 +295,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar t.FailNow() } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Error(t, err) @@ -333,8 +333,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int t.FailNow() } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContains(t, err, expectedErrorSubString) @@ -348,8 +348,8 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in t.FailNow() } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -387,7 +387,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface t.FailNow() } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Errorf(t, err, "error message %s", "formatted") @@ -429,7 +429,7 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // time.Sleep(8*time.Second) // externalValue = true // }() -// require.EventuallyWithT(t, func(c *require.CollectT) { +// require.EventuallyWithT(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") @@ -457,10 +457,10 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // time.Sleep(8*time.Second) // externalValue = true // }() -// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { +// require.EventuallyWithTf(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -671,8 +671,6 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // body that contains a string. // // require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -687,8 +685,6 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // body that contains a string. // // require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -703,8 +699,6 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // body that does not contain a string. // // require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -719,8 +713,6 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // body that does not contain a string. // // require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -734,8 +726,6 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // // require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -749,8 +739,6 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPErrorf asserts that a specified handler returns an error status code. // // require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -764,8 +752,6 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // // require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -779,8 +765,6 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // HTTPRedirectf asserts that a specified handler returns a redirect status code. // // require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -794,8 +778,6 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // // require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -809,8 +791,6 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // // require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -824,8 +804,6 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // // require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -839,8 +817,6 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // HTTPSuccessf asserts that a specified handler returns a success status code. // // require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1385,12 +1361,11 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { t.FailNow() } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if require.NoError(t, err) { -// require.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// require.NoError(t, err) +// require.Equal(t, expectedObj, actualObj) func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1401,12 +1376,11 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { t.FailNow() } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if require.NoErrorf(t, err, "error message %s", "formatted") { -// require.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// require.NoErrorf(t, err, "error message %s", "formatted") +// require.Equal(t, expectedObj, actualObj) func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1515,9 +1489,8 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str // NotEmpty asserts that the specified object is NOT [Empty]. // -// if require.NotEmpty(t, obj) { -// require.Equal(t, "two", obj[1]) -// } +// require.NotEmpty(t, obj) +// require.Equal(t, "two", obj[1]) func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1530,9 +1503,8 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT [Empty]. // -// if require.NotEmptyf(t, obj, "error message %s", "formatted") { -// require.Equal(t, "two", obj[1]) -// } +// require.NotEmptyf(t, obj, "error message %s", "formatted") +// require.Equal(t, "two", obj[1]) func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2135,7 +2107,19 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, t.FailNow() } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2146,7 +2130,19 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ t.FailNow() } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require.go.tmpl b/vendor/github.com/stretchr/testify/require/require.go.tmpl index 8b32836850..6a975501ee 100644 --- a/vendor/github.com/stretchr/testify/require/require.go.tmpl +++ b/vendor/github.com/stretchr/testify/require/require.go.tmpl @@ -1,4 +1,4 @@ -{{ replace .Comment "assert." "require."}} +{{.CommentRequire}} func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go index e6f7e94468..edac147ef4 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go +++ b/vendor/github.com/stretchr/testify/require/require_forward.go @@ -147,7 +147,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -159,7 +159,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -241,7 +241,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -270,8 +270,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -282,8 +282,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -312,7 +312,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -373,10 +373,10 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), w // time.Sleep(8*time.Second) // externalValue = true // }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// a.EventuallyWithTf(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -539,8 +539,6 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // body that contains a string. // // a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -552,8 +550,6 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // body that contains a string. // // a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -565,8 +561,6 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // body that does not contain a string. // // a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -578,8 +572,6 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // body that does not contain a string. // // a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -590,8 +582,6 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -602,8 +592,6 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // // a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -614,8 +602,6 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -626,8 +612,6 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // // a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -638,8 +622,6 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // // a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -650,8 +632,6 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // // a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -662,8 +642,6 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -674,8 +652,6 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // // a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1097,12 +1073,11 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// a.NoError(err) +// a.Equal(expectedObj, actualObj) func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1110,12 +1085,11 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// a.NoErrorf(err, "error message %s", "formatted") +// a.Equal(expectedObj, actualObj) func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1203,9 +1177,8 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg // NotEmpty asserts that the specified object is NOT [Empty]. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// a.NotEmpty(obj) +// a.Equal("two", obj[1]) func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1215,9 +1188,8 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT [Empty]. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// a.NotEmptyf(obj, "error message %s", "formatted") +// a.Equal("two", obj[1]) func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1691,7 +1663,19 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1699,7 +1683,19 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl b/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl index 54124df1d3..b3b751de48 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl +++ b/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl @@ -1,4 +1,4 @@ -{{.CommentWithoutT "a"}} +{{.CommentRequireWithoutT "a"}} func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) { if h, ok := a.t.(tHelper); ok { h.Helper() } {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go index 6b7ce929eb..375adb0a6a 100644 --- a/vendor/github.com/stretchr/testify/require/requirements.go +++ b/vendor/github.com/stretchr/testify/require/requirements.go @@ -12,18 +12,18 @@ type tHelper = interface { // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful // for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) +type ComparisonAssertionFunc = func(TestingT, interface{}, interface{}, ...interface{}) // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful // for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) +type ValueAssertionFunc = func(TestingT, interface{}, ...interface{}) // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful // for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) +type BoolAssertionFunc = func(TestingT, bool, ...interface{}) // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) +type ErrorAssertionFunc = func(TestingT, error, ...interface{}) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs" diff --git a/vendor/modules.txt b/vendor/modules.txt index f4d1500460..e7c37a2ddf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -245,8 +245,11 @@ github.com/containers/ocicrypt/utils/keyprovider # github.com/cucumber/gherkin/go/v26 v26.2.0 ## explicit; go 1.19 github.com/cucumber/gherkin/go/v26 -# github.com/cucumber/godog v0.15.1 -## explicit; go 1.16 +# github.com/cucumber/gherkin/go/v42 v42.0.0 +## explicit; go 1.19 +github.com/cucumber/gherkin/go/v42 +# github.com/cucumber/godog v0.16.0 +## explicit; go 1.18 github.com/cucumber/godog github.com/cucumber/godog/colors github.com/cucumber/godog/formatters @@ -261,6 +264,9 @@ github.com/cucumber/godog/internal/utils # github.com/cucumber/messages/go/v21 v21.0.1 ## explicit; go 1.19 github.com/cucumber/messages/go/v21 +# github.com/cucumber/messages/go/v34 v34.2.0 +## explicit; go 1.19 +github.com/cucumber/messages/go/v34 # github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 ## explicit github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer @@ -471,7 +477,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-containerregistry v0.21.7 +# github.com/google/go-containerregistry v0.21.9 ## explicit; go 1.25.0 github.com/google/go-containerregistry/internal/and github.com/google/go-containerregistry/internal/compression @@ -585,7 +591,7 @@ github.com/joelanford/ignore # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go -# github.com/klauspost/compress v1.19.1 +# github.com/klauspost/compress v1.19.2 ## explicit; go 1.24 github.com/klauspost/compress github.com/klauspost/compress/flate @@ -838,10 +844,12 @@ github.com/spf13/pflag # github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 ## explicit; go 1.19 github.com/stefanberger/go-pkcs11uri -# github.com/stretchr/testify v1.11.1 +# github.com/stretchr/testify v1.12.0 ## explicit; go 1.17 github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml +github.com/stretchr/testify/internal/difflib +github.com/stretchr/testify/internal/spew github.com/stretchr/testify/require # github.com/ulikunitz/xz v0.5.16 ## explicit; go 1.20