From 81df71e1177d55eee2a8070c4c5afe528e41f92e Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 16:04:58 -0700 Subject: [PATCH 1/6] Add some tests around `match1From` I don't know if the behavior is expected, but these tests pass. --- test/Main.purs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/Main.purs b/test/Main.purs index 4e1fd54..82d19d4 100755 --- a/test/Main.purs +++ b/test/Main.purs @@ -13,10 +13,13 @@ import Data.List (List(..), singleton, (:)) import Data.Maybe (Maybe(Nothing, Just)) import Data.Monoid (mempty) import Data.Path.Pathy (currentDir, parentDir', file, dir, rootDir, ()) +import Data.String.Regex (Regex, regex) +import Data.String.Regex.Flags (global, noFlags) import Data.Tuple (Tuple(..)) import Data.URI (AbsoluteURI(..), Authority(..), Fragment(..), HierarchicalPart(..), Host(..), Port(..), Query(..), RelativePart(..), RelativeRef(..), Scheme(..), URI(..), UserInfo(..)) import Data.URI.AbsoluteURI as AbsoluteURI import Data.URI.Authority as Authority +import Data.URI.Common as Common import Data.URI.Host as Host import Data.URI.Host.Gen as Host.Gen import Data.URI.Port as Port @@ -74,6 +77,22 @@ testParseQueryParses uri query = ("parses: \"" <> uri <> "\"") (equal (Right query) (runParser Query.parser uri)) +testMatch1FromMatches :: forall a. Either String Regex -> Int -> String -> Maybe String -> TestSuite a +testMatch1FromMatches rx' n str expected = case rx' of + Left error -> test "faulty regex given" (assert error false) + Right rx -> + test + ("matches: " <> show rx <> " at " <> show n <> " in " <> show str) + (equal expected $ Common.match1From rx n str) + +testMatch1FromMisses :: forall a. Either String Regex -> Int -> String -> TestSuite a +testMatch1FromMisses rx' n str = case rx' of + Left error -> test "faulty regex given" (assert error false) + Right rx -> + test + ("does not match: " <> show rx <> " at " <> show n <> " in " <> show str) + (equal Nothing $ Common.match1From rx n str) + main :: forall eff. Eff (console :: CONSOLE, testOutput :: TESTOUTPUT, avar :: AVAR, exception :: EXCEPTION, random :: RANDOM | eff) Unit main = runTest $ suite "Data.URI" do @@ -443,6 +462,17 @@ main = runTest $ suite "Data.URI" do "key1=&key2=" (Query (Tuple "key1" (Just "") : Tuple "key2" (Just "") : Nil)) + suite "Common.match1From" do + testMatch1FromMisses (regex "key1" noFlags) 0 "" + testMatch1FromMisses (regex "key1" noFlags) 1 "key1" + testMatch1FromMisses (regex "key1" noFlags) 1 "key1=&key1=" + testMatch1FromMisses (regex "key1" global) 1 "key1=&key1=" + testMatch1FromMisses (regex "key1|key2" noFlags) 1 "key1=&key2=" + + testMatch1FromMatches (regex "key1" noFlags) 0 "key1" (Just "key1") + testMatch1FromMatches (regex "key1" noFlags) 6 "key1=&key1=" (Just "key1") + testMatch1FromMatches (regex "key1|key2" noFlags) 6 "key1=&key2=" (Just "key2") + forAll :: forall eff prop. QC.Testable prop => QCG.Gen prop -> Test (console :: CONSOLE, random :: RANDOM, exception :: EXCEPTION | eff) forAll = quickCheck From be8d5b14aa1b1289a4789b97171e02f1be31d658 Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 16:05:59 -0700 Subject: [PATCH 2/6] Do the regex splitting in PS --- src/Data/URI/Common.js | 20 +++++++++----------- src/Data/URI/Common.purs | 6 ++++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js index ac17ea5..b5d5419 100644 --- a/src/Data/URI/Common.js +++ b/src/Data/URI/Common.js @@ -5,17 +5,15 @@ exports.match1FromImpl = function (just) { return function (nothing) { - return function (rx) { - var rxStr = rx.toString(); - var flagIndex = rxStr.lastIndexOf("/"); - var pattern = rxStr.substring(1, flagIndex); - var flags = rxStr.substring(flagIndex + 1); - return function (i) { - var rx = new RegExp(pattern, flags.indexOf("g") === -1 ? flags + "g" : flags); - return function (str) { - rx.lastIndex = i; - var result = rx.exec(str); - return result && result.index === i ? just(result[0]) : nothing; + return function (pattern) { + return function (flags) { + return function (i) { + var rx = new RegExp(pattern, flags.indexOf("g") === -1 ? flags + "g" : flags); + return function (str) { + rx.lastIndex = i; + var result = rx.exec(str); + return result && result.index === i ? just(result[0]) : nothing; + }; }; }; }; diff --git a/src/Data/URI/Common.purs b/src/Data/URI/Common.purs index 7525e91..08e344b 100644 --- a/src/Data/URI/Common.purs +++ b/src/Data/URI/Common.purs @@ -78,12 +78,14 @@ anyMatch rx = Parser \{ str: str, pos: i } → case match1From rx i str of Nothing → Left { error: (ParseError $ "Expected " <> show rx), pos: i } match1From ∷ RX.Regex → Int → String → Maybe String -match1From = match1FromImpl Just Nothing +match1From rx = + match1FromImpl Just Nothing (RX.source rx) (RX.renderFlags $ RX.flags rx) foreign import match1FromImpl ∷ (∀ a. a → Maybe a) → (∀ a. Maybe a) - → RX.Regex + → String + → String → Int → String → (Maybe String) From 0ba02851a68c29d371d261fc704fb6dcb541c69e Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 16:18:58 -0700 Subject: [PATCH 3/6] Do the global override in PS --- src/Data/URI/Common.js | 15 ++++++--------- src/Data/URI/Common.purs | 9 +++++---- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js index b5d5419..ac78811 100644 --- a/src/Data/URI/Common.js +++ b/src/Data/URI/Common.js @@ -5,15 +5,12 @@ exports.match1FromImpl = function (just) { return function (nothing) { - return function (pattern) { - return function (flags) { - return function (i) { - var rx = new RegExp(pattern, flags.indexOf("g") === -1 ? flags + "g" : flags); - return function (str) { - rx.lastIndex = i; - var result = rx.exec(str); - return result && result.index === i ? just(result[0]) : nothing; - }; + return function (rx) { + return function (i) { + return function (str) { + rx.lastIndex = i; + var result = rx.exec(str); + return result && result.index === i ? just(result[0]) : nothing; }; }; }; diff --git a/src/Data/URI/Common.purs b/src/Data/URI/Common.purs index 08e344b..5d37c92 100644 --- a/src/Data/URI/Common.purs +++ b/src/Data/URI/Common.purs @@ -78,14 +78,15 @@ anyMatch rx = Parser \{ str: str, pos: i } → case match1From rx i str of Nothing → Left { error: (ParseError $ "Expected " <> show rx), pos: i } match1From ∷ RX.Regex → Int → String → Maybe String -match1From rx = - match1FromImpl Just Nothing (RX.source rx) (RX.renderFlags $ RX.flags rx) +match1From rx' n str = + case RX.regex (RX.source rx') (RXF.global <> RX.flags rx') of + Left _ -> Nothing + Right rx -> match1FromImpl Just Nothing rx n str foreign import match1FromImpl ∷ (∀ a. a → Maybe a) → (∀ a. Maybe a) - → String - → String + → RX.Regex → Int → String → (Maybe String) From 9a6d174a6246c50ea197332397783c0f2f3a36e3 Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 16:42:40 -0700 Subject: [PATCH 4/6] Use `slice` instead of `lastIndex` --- src/Data/URI/Common.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js index ac78811..35b6c21 100644 --- a/src/Data/URI/Common.js +++ b/src/Data/URI/Common.js @@ -8,9 +8,8 @@ exports.match1FromImpl = function (just) { return function (rx) { return function (i) { return function (str) { - rx.lastIndex = i; - var result = rx.exec(str); - return result && result.index === i ? just(result[0]) : nothing; + var result = rx.exec(str.slice(i)); + return result && result.index === 0 ? just(result[0]) : nothing; }; }; }; From 0d6d3d45bf68bbeb82586dd784fbb877de488e8f Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 16:52:19 -0700 Subject: [PATCH 5/6] Slice the string in PS --- src/Data/URI/Common.js | 8 +++----- src/Data/URI/Common.purs | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js index 35b6c21..9ee4c97 100644 --- a/src/Data/URI/Common.js +++ b/src/Data/URI/Common.js @@ -6,11 +6,9 @@ exports.match1FromImpl = function (just) { return function (nothing) { return function (rx) { - return function (i) { - return function (str) { - var result = rx.exec(str.slice(i)); - return result && result.index === 0 ? just(result[0]) : nothing; - }; + return function (str) { + var result = rx.exec(str); + return result && result.index === 0 ? just(result[0]) : nothing; }; }; }; diff --git a/src/Data/URI/Common.purs b/src/Data/URI/Common.purs index 5d37c92..0cbe87d 100644 --- a/src/Data/URI/Common.purs +++ b/src/Data/URI/Common.purs @@ -81,12 +81,11 @@ match1From ∷ RX.Regex → Int → String → Maybe String match1From rx' n str = case RX.regex (RX.source rx') (RXF.global <> RX.flags rx') of Left _ -> Nothing - Right rx -> match1FromImpl Just Nothing rx n str + Right rx -> match1FromImpl Just Nothing rx (S.drop n str) foreign import match1FromImpl ∷ (∀ a. a → Maybe a) → (∀ a. Maybe a) → RX.Regex - → Int → String → (Maybe String) From f24affaefb0a42acf89cdf592e4f3fa0df8c805d Mon Sep 17 00:00:00 2001 From: joneshf Date: Sun, 24 Sep 2017 17:11:31 -0700 Subject: [PATCH 6/6] Move all logic to PS --- src/Data/URI/Common.js | 15 --------------- src/Data/URI/Common.purs | 19 +++++++++---------- 2 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 src/Data/URI/Common.js diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js deleted file mode 100644 index 9ee4c97..0000000 --- a/src/Data/URI/Common.js +++ /dev/null @@ -1,15 +0,0 @@ -/* global exports */ -"use strict"; - -// module Data.URI.Common - -exports.match1FromImpl = function (just) { - return function (nothing) { - return function (rx) { - return function (str) { - var result = rx.exec(str); - return result && result.index === 0 ? just(result[0]) : nothing; - }; - }; - }; -}; diff --git a/src/Data/URI/Common.purs b/src/Data/URI/Common.purs index 0cbe87d..3e86785 100644 --- a/src/Data/URI/Common.purs +++ b/src/Data/URI/Common.purs @@ -3,7 +3,8 @@ module Data.URI.Common where import Prelude import Control.Alt ((<|>)) -import Data.Array (fromFoldable) +import Control.MonadZero (guard) +import Data.Array (fromFoldable, head) import Data.Either (Either(..), fromRight) import Data.List (List) import Data.Maybe (Maybe(..)) @@ -78,14 +79,12 @@ anyMatch rx = Parser \{ str: str, pos: i } → case match1From rx i str of Nothing → Left { error: (ParseError $ "Expected " <> show rx), pos: i } match1From ∷ RX.Regex → Int → String → Maybe String -match1From rx' n str = +match1From rx' n str' = case RX.regex (RX.source rx') (RXF.global <> RX.flags rx') of Left _ -> Nothing - Right rx -> match1FromImpl Just Nothing rx (S.drop n str) - -foreign import match1FromImpl - ∷ (∀ a. a → Maybe a) - → (∀ a. Maybe a) - → RX.Regex - → String - → (Maybe String) + Right rx -> do + let str = S.drop n str' + i <- RX.search rx str + guard $ i == 0 + matches <- RX.match rx str + join $ head matches