irc-core 2.1.1.1 → 2.2.0.0
raw patch · 5 files changed
+115/−19 lines, 5 filesdep ~hashablePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hashable
API changes (from Hackage documentation)
+ Irc.Codes: instance GHC.Classes.Eq Irc.Codes.ReplyCode
+ Irc.Codes: instance GHC.Classes.Eq Irc.Codes.ReplyCodeInfo
+ Irc.Codes: instance GHC.Classes.Eq Irc.Codes.ReplyType
+ Irc.Codes: instance GHC.Classes.Ord Irc.Codes.ReplyCode
+ Irc.Codes: instance GHC.Classes.Ord Irc.Codes.ReplyCodeInfo
+ Irc.Codes: instance GHC.Classes.Ord Irc.Codes.ReplyType
+ Irc.Codes: instance GHC.Read.Read Irc.Codes.ReplyCode
+ Irc.Codes: instance GHC.Read.Read Irc.Codes.ReplyCodeInfo
+ Irc.Codes: instance GHC.Read.Read Irc.Codes.ReplyType
+ Irc.Codes: instance GHC.Show.Show Irc.Codes.ReplyCodeInfo
+ Irc.Codes: instance GHC.Show.Show Irc.Codes.ReplyType
- Irc.Commands: ircNick :: Identifier -> RawIrcMsg
+ Irc.Commands: ircNick :: Text -> RawIrcMsg
- Irc.Commands: ircNotice :: Identifier -> Text -> RawIrcMsg
+ Irc.Commands: ircNotice :: Text -> Text -> RawIrcMsg
- Irc.Commands: ircPrivmsg :: Identifier -> Text -> RawIrcMsg
+ Irc.Commands: ircPrivmsg :: Text -> Text -> RawIrcMsg
Files
- ChangeLog.md +6/−0
- irc-core.cabal +3/−2
- src/Irc/Codes.hs +16/−2
- src/Irc/Commands.hs +10/−10
- test/Main.hs +80/−5
ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for irc-core +## 2.2.0.0 -- 2016-09-15++* `ircIson` packs all the nicks into a single argument+* `Eq` and `Ord` instances for `ReplyCode`+* Use `Text` for nickname targets in Irc.Commands+ ## 2.1.1.1 -- 2016-08-28 * Added parsing tests
irc-core.cabal view
@@ -1,5 +1,5 @@ name: irc-core-version: 2.1.1.1+version: 2.2.0.0 synopsis: IRC core library for glirc description: IRC core library for glirc .@@ -53,5 +53,6 @@ build-depends: irc-core, base, text,- HUnit >= 1.3 && < 1.4+ hashable,+ HUnit >= 1.3 && < 1.4 default-language: Haskell2010
src/Irc/Codes.hs view
@@ -24,16 +24,23 @@ -- | Type of numeric reply codes newtype ReplyCode = ReplyCode Word+ deriving (Eq, Ord) +-- | Shows number instance Show ReplyCode where showsPrec p (ReplyCode x) = showsPrec p x +-- | Reads only the number+instance Read ReplyCode where+ readsPrec p str = [ (ReplyCode x, xs) | (x,xs) <- readsPrec p str ]+ -- | Categories for reply codes data ReplyType = ClientServerReply -- ^ 0-99 Messages between client and server | CommandReply -- ^ 200-399 Responses to commands | ErrorReply -- ^ 200-399 Errors | UnknownReply -- ^ Uncategorized+ deriving (Eq, Ord, Read, Show) pattern RPL_WELCOME = ReplyCode 001 pattern RPL_YOURHOST = ReplyCode 002@@ -432,11 +439,15 @@ pattern ERR_TEXTTOOSHORT = ReplyCode 983 pattern ERR_NUMERIC_ERR = ReplyCode 999 +-- | Information describing the category and human decipherable name of a+-- reply. data ReplyCodeInfo = ReplyCodeInfo- { replyCodeType :: !ReplyType- , replyCodeText :: !Text+ { replyCodeType :: !ReplyType -- ^ category+ , replyCodeText :: !Text -- ^ human-decipherable name }+ deriving (Eq, Ord, Show, Read) +-- | Compute information for a reply code replyCodeInfo :: ReplyCode -> ReplyCodeInfo replyCodeInfo (ReplyCode w) = case replyCodeInfoTable Vector.!? i of@@ -445,9 +456,12 @@ where i = fromIntegral w +-- | Categorize a reply code using the unknown category and simply showing+-- the reply code's number as its name. defaultReplyCodeInfo :: Int -> ReplyCodeInfo defaultReplyCodeInfo = ReplyCodeInfo UnknownReply . Text.pack . show +-- | Information about reply codes as derived from Freenode's ircd-seven. replyCodeInfoTable :: Vector ReplyCodeInfo replyCodeInfoTable = Vector.accumulate
src/Irc/Commands.hs view
@@ -55,17 +55,17 @@ -- | PRIVMSG command ircPrivmsg ::- Identifier {- ^ target -} ->- Text {- ^ message -} ->+ Text {- ^ target -} ->+ Text {- ^ message -} -> RawIrcMsg-ircPrivmsg who msg = rawIrcMsg "PRIVMSG" [idText who, msg]+ircPrivmsg who msg = rawIrcMsg "PRIVMSG" [who, msg] -- | NOTICE command ircNotice ::- Identifier {- ^ target -} ->- Text {- ^ message -} ->+ Text {- ^ target -} ->+ Text {- ^ message -} -> RawIrcMsg-ircNotice who msg = rawIrcMsg "NOTICE" [idText who, msg]+ircNotice who msg = rawIrcMsg "NOTICE" [who, msg] -- | MODE command ircMode ::@@ -94,9 +94,9 @@ -- | NICK command ircNick ::- Identifier {- ^ nickname -} ->+ Text {- ^ nickname -} -> RawIrcMsg-ircNick nick = rawIrcMsg "NICK" [idText nick]+ircNick nick = rawIrcMsg "NICK" [nick] -- | PART command ircPart ::@@ -175,9 +175,9 @@ -- | ISON command ircIson ::- [Text] {- ^ parameters -} ->+ [Text] {- ^ nicknames -} -> RawIrcMsg-ircIson = rawIrcMsg "ISON"+ircIson nicks = rawIrcMsg "ISON" [Text.unwords nicks] -- | TIME command ircTime ::
test/Main.hs view
@@ -12,21 +12,26 @@ module Main (main) where import qualified Data.Text as Text+import Data.Hashable import Data.Semigroup import Irc.RawIrcMsg import Irc.UserInfo+import Irc.Identifier import System.Exit import Test.HUnit+import Text.Read main :: IO a main =- do counts <- runTestTT tests- if errors counts == 0 && failures counts == 0+ do outcome <- runTestTT tests+ if errors outcome == 0 && failures outcome == 0 then exitSuccess else exitFailure tests :: Test-tests = test [ irc0, irc2, irc15, ircWithPrefix, ircWithTags, userInfos, renderIrc ]+tests = test [ irc0, irc2, irc15, ircWithPrefix, ircWithTags,+ parseUserInfos, renderUserInfos, renderIrc,+ badRawMsgs, userInfoFields, identifierInstances ] -- | Check that we can handle commands without parameters irc0 :: Test@@ -109,10 +114,45 @@ ] -userInfos :: Test-userInfos = test+renderUserInfos :: Test+renderUserInfos = test [ assertEqual "missing user and hostname"+ "glguy"+ (renderUserInfo (UserInfo "glguy" "" ""))++ , assertEqual "freenode cloak"+ "glguy!~glguy@haskell/developer/glguy"+ (renderUserInfo (UserInfo "glguy" "~glguy" "haskell/developer/glguy"))++ , assertEqual "missing user"+ "glguy@haskell/developer/glguy"+ (renderUserInfo (UserInfo "glguy" "" "haskell/developer/glguy"))++ , assertEqual "missing host"+ "glguy!~glguy"+ (renderUserInfo (UserInfo "glguy" "~glguy" ""))++ , assertEqual "extra @ goes into host"+ "nick!user@server@name"+ (renderUserInfo (UserInfo "nick" "user" "server@name"))++ , assertEqual "servername in nick"+ "morgan.freenode.net"+ (renderUserInfo (UserInfo "morgan.freenode.net" "" ""))+ ]++userInfoFields :: Test+userInfoFields = test+ [ assertEqual "nickfield" "nick" (userNick (UserInfo "nick" "user" "host"))+ , assertEqual "userfield" "user" (userName (UserInfo "nick" "user" "host"))+ , assertEqual "hostfield" "host" (userHost (UserInfo "nick" "user" "host"))+ ]++parseUserInfos :: Test+parseUserInfos = test++ [ assertEqual "missing user and hostname" (UserInfo "glguy" "" "") (parseUserInfo "glguy") @@ -174,4 +214,39 @@ { _msgTags = [TagEntry "time" "", TagEntry "magic" ""] }) + ]++badRawMsgs :: Test+badRawMsgs = test+ [ assertEqual "bad prefix"+ Nothing+ (parseRawIrcMsg ": CMD")+ , assertEqual "empty string"+ Nothing+ (parseRawIrcMsg "")+ , assertEqual "whitespace"+ Nothing+ (parseRawIrcMsg " ")+ , assertEqual "only prefix"+ Nothing+ (parseRawIrcMsg ":glguy!glguy@glguy")+ , assertEqual "only tags"+ Nothing+ (parseRawIrcMsg "@glguy=tester")+ ]++identifierInstances :: Test+identifierInstances = test+ [ assertEqual "read" (Just ("GLGUY"::Identifier)) (readMaybe "\"glguy\"")+ , assertEqual "read2" (Just ("Glguy"::Identifier)) (readMaybe "\"glguy\"")+ , assertEqual "show1" "\"GLguy\"" (show ("GLguy"::Identifier))+ , assertEqual "show2" "\"glguy\"" (show ("glguy"::Identifier))+ , assertBool "hash" $ hash ("glguy"::Identifier) ==+ hash ("GLGUY"::Identifier)+ , assertBool "lt1" $ "glguy" < ("tester" :: Identifier)+ , assertBool "gt1" $ "tester" > ("glguy" :: Identifier)+ , assertBool "lt2" $ "GLGUY" < ("tester" :: Identifier)+ , assertBool "gt2" $ "TESTER" > ("glguy" :: Identifier)+ , assertBool "pre" $ idPrefix "gl" "GLGUY"+ , assertBool "pre" $ not $ idPrefix "glguy" "gl" ]