diff --git a/.tidyrc.json b/.tidyrc.json new file mode 100644 index 0000000..87c37ec --- /dev/null +++ b/.tidyrc.json @@ -0,0 +1,8 @@ +{ + "indent": 2, + "operatorsFile": null, + "ribbon": 1, + "typeArrowPlacement": "first", + "unicode": "source", + "width": null +} diff --git a/package-lock.json b/package-lock.json index 2b3ea50..e0b713a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,10 +6,9 @@ "": { "license": "MIT", "devDependencies": { - "purescript": "^0.14.0", - "purescript-language-server": "^0.12.7", - "purty": "^6.2.0", - "spago": "^0.19.1", + "purescript": "^0.14.3", + "purs-tidy": "^0.2.2", + "spago": "^0.20.0", "ssri": ">=8.0.1" } }, @@ -1080,9 +1079,9 @@ } }, "node_modules/purescript": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.14.0.tgz", - "integrity": "sha512-iTA1k8mwxHqrJp/K296g6omVfve5RCjnB5D6Up93PVtZdP66mCIqlOYC4hrLBHg2hgkk27xePDt5NUXKvH4ApQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.14.3.tgz", + "integrity": "sha512-lAzHU/tcmxF4n3YUwUTwG/sIwHzjUq1zsIOBNmaVpbm7hxM+RhOTKMJdwdbTeCjxlilyVPWOLUQ6Exll4DYuMA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1126,32 +1125,13 @@ "node": ">=8.3.0" } }, - "node_modules/purescript-language-server": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/purescript-language-server/-/purescript-language-server-0.12.7.tgz", - "integrity": "sha512-uXYrzoKPjlgEOgJqctqcfddtkCa57N3/1t2wENxS8TnxJnZt1j/LVQCWMhrEUfw90DPohhRKaaQmdrWrCpq9ow==", + "node_modules/purs-tidy": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/purs-tidy/-/purs-tidy-0.2.2.tgz", + "integrity": "sha512-JWqLuzlc1VKyUn1vebBzWcs/+rvTD5Z7dRE3xqkj+wYEBzRzHsJgpLv1sEgS2DNwGBPcw+2ujMGlyX9YI7vSuw==", "dev": true, - "dependencies": { - "vscode-languageserver": "^3.2.0", - "vscode-uri": "^1.0.0", - "which": "^1.2.9" - }, - "bin": { - "purescript-language-server": "cli.js" - } - }, - "node_modules/purty": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/purty/-/purty-6.2.0.tgz", - "integrity": "sha512-JfT8kJHSyxuOFQtRiH2x55SiPxXZsSdedQlZap8JehQ7KzB49B5C9cWwVybtSB36BdADQcxPvtw8D52z4EPnBw==", - "dev": true, - "os": [ - "linux", - "darwin", - "win32" - ], "bin": { - "purty": "bin/purty.js" + "purs-tidy": "bin/index.js" } }, "node_modules/qs": { @@ -1305,9 +1285,9 @@ "dev": true }, "node_modules/spago": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/spago/-/spago-0.19.1.tgz", - "integrity": "sha512-OD/yopJZ9Ub+XsFtayDeLAWLT4kLdMxosJEyyp8W5OkyJVVSbCrvYacsO7iq3lSuHJmmNny/TEZdyb7uSyupng==", + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.3.tgz", + "integrity": "sha512-R4CWLP5IbaWoNIpS1QAUuDK2LKlKYqT5gBKVZL7ILilvCwdwS72u3NbGZbvx7VCRRZz4lG7zXUkqKNow7zh6wQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1441,9 +1421,9 @@ } }, "node_modules/tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", "dev": true, "dependencies": { "chownr": "^1.1.1", @@ -1561,50 +1541,6 @@ "extsprintf": "^1.2.0" } }, - "node_modules/vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=", - "dev": true, - "engines": { - "node": ">=4.0.0 || >=6.0.0" - } - }, - "node_modules/vscode-languageserver": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.1.tgz", - "integrity": "sha512-RYUKn0DgHTFcS8kS4VaNCjNMaQXYqiXdN9bKrFjXzu5RPKfjIYcoh47oVWwZj4L3R/DPB0Se7HPaDatvYY2XgQ==", - "dev": true, - "dependencies": { - "vscode-languageserver-protocol": "3.5.1", - "vscode-uri": "^1.0.1" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", - "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", - "dev": true, - "dependencies": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" - } - }, - "node_modules/vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=", - "dev": true - }, - "node_modules/vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==", - "dev": true - }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2563,9 +2499,9 @@ "dev": true }, "purescript": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.14.0.tgz", - "integrity": "sha512-iTA1k8mwxHqrJp/K296g6omVfve5RCjnB5D6Up93PVtZdP66mCIqlOYC4hrLBHg2hgkk27xePDt5NUXKvH4ApQ==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.14.3.tgz", + "integrity": "sha512-lAzHU/tcmxF4n3YUwUTwG/sIwHzjUq1zsIOBNmaVpbm7hxM+RhOTKMJdwdbTeCjxlilyVPWOLUQ6Exll4DYuMA==", "dev": true, "requires": { "purescript-installer": "^0.2.0" @@ -2599,21 +2535,10 @@ "zen-observable": "^0.8.14" } }, - "purescript-language-server": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/purescript-language-server/-/purescript-language-server-0.12.7.tgz", - "integrity": "sha512-uXYrzoKPjlgEOgJqctqcfddtkCa57N3/1t2wENxS8TnxJnZt1j/LVQCWMhrEUfw90DPohhRKaaQmdrWrCpq9ow==", - "dev": true, - "requires": { - "vscode-languageserver": "^3.2.0", - "vscode-uri": "^1.0.0", - "which": "^1.2.9" - } - }, - "purty": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/purty/-/purty-6.2.0.tgz", - "integrity": "sha512-JfT8kJHSyxuOFQtRiH2x55SiPxXZsSdedQlZap8JehQ7KzB49B5C9cWwVybtSB36BdADQcxPvtw8D52z4EPnBw==", + "purs-tidy": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/purs-tidy/-/purs-tidy-0.2.2.tgz", + "integrity": "sha512-JWqLuzlc1VKyUn1vebBzWcs/+rvTD5Z7dRE3xqkj+wYEBzRzHsJgpLv1sEgS2DNwGBPcw+2ujMGlyX9YI7vSuw==", "dev": true }, "qs": { @@ -2744,9 +2669,9 @@ "dev": true }, "spago": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/spago/-/spago-0.19.1.tgz", - "integrity": "sha512-OD/yopJZ9Ub+XsFtayDeLAWLT4kLdMxosJEyyp8W5OkyJVVSbCrvYacsO7iq3lSuHJmmNny/TEZdyb7uSyupng==", + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.3.tgz", + "integrity": "sha512-R4CWLP5IbaWoNIpS1QAUuDK2LKlKYqT5gBKVZL7ILilvCwdwS72u3NbGZbvx7VCRRZz4lG7zXUkqKNow7zh6wQ==", "dev": true, "requires": { "request": "^2.88.0", @@ -2857,9 +2782,9 @@ } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", "dev": true, "requires": { "chownr": "^1.1.1", @@ -2962,44 +2887,6 @@ "extsprintf": "^1.2.0" } }, - "vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=", - "dev": true - }, - "vscode-languageserver": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.1.tgz", - "integrity": "sha512-RYUKn0DgHTFcS8kS4VaNCjNMaQXYqiXdN9bKrFjXzu5RPKfjIYcoh47oVWwZj4L3R/DPB0Se7HPaDatvYY2XgQ==", - "dev": true, - "requires": { - "vscode-languageserver-protocol": "3.5.1", - "vscode-uri": "^1.0.1" - } - }, - "vscode-languageserver-protocol": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", - "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", - "dev": true, - "requires": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" - } - }, - "vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=", - "dev": true - }, - "vscode-uri": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", - "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==", - "dev": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 39f36a3..05f599b 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,14 @@ "repository": "https://github.com/drewolson/purescript-biscotti-cookie", "license": "MIT", "scripts": { - "ci": "npm run test && npm run format:check", + "ci": "npm run test", "test": "spago test", - "format": "find src test -name \"*.purs\" | xargs -n1 purty format --write", - "format:check": "find src test -name \"*.purs\" | xargs -n1 purty validate" + "format": "purs-tidy format-in-place 'src/**/*.purs' && purs-tidy format-in-place 'test/**/*.purs'" }, "devDependencies": { - "purescript": "^0.14.0", - "purescript-language-server": "^0.12.7", - "purty": "^6.2.0", - "spago": "^0.19.1", + "purescript": "^0.14.3", + "purs-tidy": "^0.2.2", + "spago": "^0.20.0", "ssri": ">=8.0.1" } } diff --git a/src/Biscotti/Cookie/Generator.purs b/src/Biscotti/Cookie/Generator.purs index ac9276b..dc7771f 100644 --- a/src/Biscotti/Cookie/Generator.purs +++ b/src/Biscotti/Cookie/Generator.purs @@ -41,15 +41,15 @@ stringify :: Cookie -> String stringify cookie = intercalate "; " $ catMaybes - [ attr (getName cookie) $ Just (getValue cookie) - , attr domainTag $ getDomain cookie - , attr pathTag $ getPath cookie - , attr expiresTag $ formatDateTime <$> getExpires cookie - , attr maxAgeTag $ show <$> getMaxAge cookie - , attr sameSiteTag $ show <$> getSameSite cookie - , flag secureTag $ getSecure cookie - , flag httpOnlyTag $ getHttpOnly cookie - ] + [ attr (getName cookie) $ Just (getValue cookie) + , attr domainTag $ getDomain cookie + , attr pathTag $ getPath cookie + , attr expiresTag $ formatDateTime <$> getExpires cookie + , attr maxAgeTag $ show <$> getMaxAge cookie + , attr sameSiteTag $ show <$> getSameSite cookie + , flag secureTag $ getSecure cookie + , flag httpOnlyTag $ getHttpOnly cookie + ] attr :: String -> Maybe String -> Maybe String attr name = case _ of diff --git a/src/Biscotti/Cookie/Types.purs b/src/Biscotti/Cookie/Types.purs index f49a70d..23eff1e 100644 --- a/src/Biscotti/Cookie/Types.purs +++ b/src/Biscotti/Cookie/Types.purs @@ -60,21 +60,20 @@ instance showSameSite :: Show SameSite where show Lax = "Lax" show None = "None" -type CookieFields - = { name :: String - , value :: String - , domain :: Maybe String - , path :: Maybe String - , expires :: Maybe DateTime - , maxAge :: Maybe Int - , sameSite :: Maybe SameSite - , secure :: Boolean - , httpOnly :: Boolean - } +type CookieFields = + { name :: String + , value :: String + , domain :: Maybe String + , path :: Maybe String + , expires :: Maybe DateTime + , maxAge :: Maybe Int + , sameSite :: Maybe SameSite + , secure :: Boolean + , httpOnly :: Boolean + } -- | The `Cookie` type -newtype Cookie - = Cookie CookieFields +newtype Cookie = Cookie CookieFields derive newtype instance eqCookie :: Eq Cookie @@ -105,8 +104,8 @@ fromFields = Cookie expire :: Cookie -> Effect (Either String Cookie) expire cookie = do now <- nowDateTime - let - maybeDate = DateTime.adjust (Days $ -1.0) now + let maybeDate = DateTime.adjust (Days $ -1.0) now + case maybeDate of Nothing -> pure $ Left "Invalid date" Just yesterday -> pure $ Right $ setExpires yesterday cookie diff --git a/test/Test/Biscotti/CookieTest.purs b/test/Test/Biscotti/CookieTest.purs index d2debc8..b273660 100644 --- a/test/Test/Biscotti/CookieTest.purs +++ b/test/Test/Biscotti/CookieTest.purs @@ -43,19 +43,18 @@ instance arbitraryTestCookie :: Arbitrary TestCookie where sameSite <- genMaybe $ genSameSite secure <- arbitrary httpOnly <- arbitrary - pure - $ TestCookie - $ Cookie.fromFields - { name - , value - , domain - , path - , expires - , maxAge - , sameSite - , secure - , httpOnly - } + + pure $ TestCookie $ Cookie.fromFields + { name + , value + , domain + , path + , expires + , maxAge + , sameSite + , secure + , httpOnly + } where genSameSite :: Gen SameSite genSameSite = elements $ fromNonEmpty $ Strict :| [ Lax, None ] @@ -77,18 +76,18 @@ testSuite = do suite "properties" do test "parse and stringify round trip correctly" do quickCheck \(TestCookie cookie) -> do - let - new = Cookie.parse $ Cookie.stringify $ cookie + let new = Cookie.parse $ Cookie.stringify $ cookie + new ==? Right cookie + suite "stringify" do test "produces a correctly-formated expires attribute" do - let - date = unsafePartial $ fromJust $ DateTime.canonicalDate <$> toEnum 2019 <*> toEnum 12 <*> toEnum 1 - let - time = unsafePartial $ fromJust $ Time <$> toEnum 12 <*> toEnum 1 <*> toEnum 2 <*> toEnum 0 - let - cookieString = Cookie.stringify $ Cookie.setExpires (DateTime date time) $ Cookie.new "foo" "bar" + let date = unsafePartial $ fromJust $ DateTime.canonicalDate <$> toEnum 2019 <*> toEnum 12 <*> toEnum 1 + let time = unsafePartial $ fromJust $ Time <$> toEnum 12 <*> toEnum 1 <*> toEnum 2 <*> toEnum 0 + let cookieString = Cookie.stringify $ Cookie.setExpires (DateTime date time) $ Cookie.new "foo" "bar" + cookieString `shouldContainString` "Expires=Sun, 01 Dec 2019 12:01:02 GMT" + suite "parse" do test "parses a simple cookie" do let @@ -104,7 +103,9 @@ testSuite = do , secure: false , httpOnly: false } + Cookie.parse "key=val" `shouldEqual` Right expected + suite "parseMany" do test "parses multiple name/value pairs only" do let @@ -133,4 +134,5 @@ testSuite = do , httpOnly: false } ] + Cookie.parseMany "key1=val1; key2=val2" `shouldEqual` Right expected diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 36db4ed..a937569 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -6,6 +6,5 @@ import Test.Biscotti.CookieTest as CookieTest import Test.Unit.Main (runTest) main :: Effect Unit -main = - runTest do - CookieTest.testSuite +main = runTest do + CookieTest.testSuite diff --git a/test/Test/Util/Assert.purs b/test/Test/Util/Assert.purs index f9b0030..2f9bdec 100644 --- a/test/Test/Util/Assert.purs +++ b/test/Test/Util/Assert.purs @@ -9,6 +9,6 @@ import Test.Unit (Test) import Test.Unit.Assert (assert) shouldContainString :: String -> String -> Test -shouldContainString haystack needle = do +shouldContainString haystack needle = assert ("Expected \"" <> haystack <> "\" to contain \"" <> needle <> "\"") $ String.contains (Pattern needle) haystack