27 Commits
0.8.0 ... 0.9.0

Author SHA1 Message Date
Jonathan Lamothe
89fe646d0e version 0.9.0 2019-12-27 00:54:08 -05:00
Jonathan Lamothe
b35136944c Merge pull request #53 from mtlstats/edit-menu
implement edit menu
2019-12-17 22:57:42 -05:00
Jonathan Lamothe
4d41c454a1 updated change log 2019-12-17 22:52:21 -05:00
Jonathan Lamothe
18ba758c0c changed return wording on player/goalie edit menus 2019-12-17 22:50:39 -05:00
Jonathan Lamothe
3aedd01b08 make player/goalie edit return to edit menu on completion 2019-12-17 22:47:17 -05:00
Jonathan Lamothe
235dd4e611 return to edit menu after player/goalie creation 2019-12-17 12:30:55 -05:00
Jonathan Lamothe
adf09c2cc4 moved player/goalie creation to edit menu 2019-12-17 12:23:53 -05:00
Jonathan Lamothe
a44ecc5e24 implemented edit 2019-12-17 12:16:26 -05:00
Jonathan Lamothe
9980a095ed added edit menu to main menu 2019-12-17 12:05:10 -05:00
Jonathan Lamothe
1d6a4aa7f3 implemented editMenu 2019-12-17 12:05:10 -05:00
Jonathan Lamothe
8988ad9146 implemented Mtlstats.Control.editMenuC 2019-12-17 11:38:35 -05:00
Jonathan Lamothe
59d48ec154 added EditMenu mode 2019-12-17 11:32:32 -05:00
Jonathan Lamothe
be990538bc Merge pull request #52 from mtlstats/hlint
hlint suggestions
2019-12-17 11:27:41 -05:00
Jonathan Lamothe
55c8806186 hlint suggestions
hlint didn't like reverse, and suggested using Data.Ord Down instead
2019-12-17 11:19:38 -05:00
Jonathan Lamothe
0ecf899b56 Merge pull request #51 from mtlstats/sort-players
sort players in YTD/lifetime reports by points
2019-12-15 13:30:47 -05:00
Jonathan Lamothe
2f06fd221d sort descending 2019-12-15 13:26:22 -05:00
Jonathan Lamothe
f1227da9ca sort players in YTD/lifetime reports by points 2019-12-15 13:19:12 -05:00
Jonathan Lamothe
38db3c8d8f Merge pull request #50 from mtlstats/no-totals
don't show totals in lifetime stats
2019-12-15 12:33:30 -05:00
Jonathan Lamothe
2b9a21c28b don't show totals in lifetime stats 2019-12-15 12:27:06 -05:00
Jonathan Lamothe
84c487dba5 typo in change log 2019-12-15 11:05:22 -05:00
Jonathan Lamothe
6345e3d5d8 Merge pull request #49 from mtlstats/auto-capitalize
Auto capitalize player/goalie names
2019-12-14 01:25:44 -05:00
Jonathan Lamothe
0ca03b7f21 updated change log 2019-12-14 01:19:18 -05:00
Jonathan Lamothe
482f42dca7 force proper name capitalization on player/goalie creation 2019-12-14 01:15:00 -05:00
Jonathan Lamothe
996bad94f1 force capitalization of player/goalie names in player selection 2019-12-14 01:09:40 -05:00
Jonathan Lamothe
4ca0b54de2 Merge pull request #48 from mtlstats/bugfix
Bugfix: display lifetime statistics in report instead of year-to-date
2019-12-14 00:16:55 -05:00
Jonathan Lamothe
3738088dde display lifetime stats in report 2019-12-13 11:43:22 -05:00
Jonathan Lamothe
1ec9e93f16 hlint recommenfations 2019-12-13 11:42:49 -05:00
15 changed files with 196 additions and 47 deletions

View File

@@ -1,5 +1,12 @@
# Changelog for mtlstats # Changelog for mtlstats
## 0.9.0
- Bugfix: Display lifetime stats in report, not YTD
- Force expected capitalization on player/goalie names
- Don't show lifetime totals in report
- Sort players in YTD and lifetime reports by points
- Moved player/goalie creation/editing to edit submenu
## 0.8.0 ## 0.8.0
- Bugfix: removed quotation marks from goalie names in report - Bugfix: removed quotation marks from goalie names in report
- Allow lower case player names - Allow lower case player names

View File

@@ -1,5 +1,5 @@
name: mtlstats name: mtlstats
version: 0.8.0 version: 0.9.0
github: "mtlstats/mtlstats" github: "mtlstats/mtlstats"
license: GPL-3 license: GPL-3
author: "Jonathan Lamothe" author: "Jonathan Lamothe"

View File

@@ -30,6 +30,7 @@ module Mtlstats.Actions
, removeChar , removeChar
, createPlayer , createPlayer
, createGoalie , createGoalie
, edit
, editPlayer , editPlayer
, editGoalie , editGoalie
, addPlayer , addPlayer
@@ -82,7 +83,7 @@ removeChar = inputBuffer %~ \case
-- | Starts player creation mode -- | Starts player creation mode
createPlayer :: ProgState -> ProgState createPlayer :: ProgState -> ProgState
createPlayer = let createPlayer = let
callback = modify $ progMode .~ MainMenu callback = modify edit
cps = newCreatePlayerState cps = newCreatePlayerState
& cpsSuccessCallback .~ callback & cpsSuccessCallback .~ callback
& cpsFailureCallback .~ callback & cpsFailureCallback .~ callback
@@ -91,12 +92,16 @@ createPlayer = let
-- | Starts goalie creation mode -- | Starts goalie creation mode
createGoalie :: ProgState -> ProgState createGoalie :: ProgState -> ProgState
createGoalie = let createGoalie = let
callback = modify $ progMode .~ MainMenu callback = modify edit
cgs = newCreateGoalieState cgs = newCreateGoalieState
& cgsSuccessCallback .~ callback & cgsSuccessCallback .~ callback
& cgsFailureCallback .~ callback & cgsFailureCallback .~ callback
in progMode .~ CreateGoalie cgs in progMode .~ CreateGoalie cgs
-- | Launches the edit menu
edit :: ProgState -> ProgState
edit = progMode .~ EditMenu
-- | Starts the player editing process -- | Starts the player editing process
editPlayer :: ProgState -> ProgState editPlayer :: ProgState -> ProgState
editPlayer = progMode .~ EditPlayer newEditPlayerState editPlayer = progMode .~ EditPlayer newEditPlayerState

View File

@@ -41,9 +41,10 @@ import Mtlstats.Types
-- run -- run
dispatch :: ProgState -> Controller dispatch :: ProgState -> Controller
dispatch s = case s^.progMode of dispatch s = case s^.progMode of
MainMenu -> mainMenuC MainMenu -> mainMenuC
NewSeason -> newSeasonC NewSeason -> newSeasonC
NewGame gs -> newGameC gs NewGame gs -> newGameC gs
EditMenu -> editMenuC
CreatePlayer cps CreatePlayer cps
| null $ cps^.cpsNumber -> getPlayerNumC | null $ cps^.cpsNumber -> getPlayerNumC
| null $ cps^.cpsName -> getPlayerNameC | null $ cps^.cpsName -> getPlayerNameC
@@ -70,6 +71,9 @@ newSeasonC = Controller
return True return True
} }
editMenuC :: Controller
editMenuC = menuController editMenu
getPlayerNumC :: Controller getPlayerNumC :: Controller
getPlayerNumC = Controller getPlayerNumC = Controller
{ drawController = drawPrompt playerNumPrompt { drawController = drawPrompt playerNumPrompt

View File

@@ -26,6 +26,7 @@ module Mtlstats.Format
, left , left
, right , right
, centre , centre
, padRight
, overlay , overlay
, month , month
, labelTable , labelTable
@@ -87,6 +88,16 @@ centre n str = let
pad = replicate pLen ' ' pad = replicate pLen ' '
in take n $ pad ++ str ++ repeat ' ' in take n $ pad ++ str ++ repeat ' '
-- | Pads text on the right with spaces to fit a minimum width
padRight
:: Int
-- ^ The width to pad to
-> String
-- ^ The text to pad
-> String
padRight width str =
overlay str $ replicate width ' '
-- | Overlays one string on top of another -- | Overlays one string on top of another
overlay overlay
:: String :: String

View File

@@ -31,7 +31,8 @@ module Mtlstats.Menu (
newSeasonMenu, newSeasonMenu,
gameMonthMenu, gameMonthMenu,
gameTypeMenu, gameTypeMenu,
gameGoalieMenu gameGoalieMenu,
editMenu
) where ) where
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
@@ -113,14 +114,8 @@ mainMenu = Menu "*** MAIN MENU ***" True
modify startNewSeason >> return True modify startNewSeason >> return True
, MenuItem '2' "New Game" $ , MenuItem '2' "New Game" $
modify startNewGame >> return True modify startNewGame >> return True
, MenuItem '3' "Create Player" $ , MenuItem '3' "Edit" $
modify createPlayer >> return True modify edit >> return True
, MenuItem '4' "Create Goalie" $
modify createGoalie >> return True
, MenuItem '5' "Edit Player" $
modify editPlayer >> return True
, MenuItem '6' "Edit Goalie" $
modify editGoalie >> return True
, MenuItem 'X' "Exit" $ do , MenuItem 'X' "Exit" $ do
db <- gets $ view database db <- gets $ view database
liftIO $ do liftIO $ do
@@ -186,3 +181,18 @@ gameGoalieMenu s = let
(\(ch, (gid, goalie)) -> MenuItem ch (goalieSummary goalie) $ (\(ch, (gid, goalie)) -> MenuItem ch (goalieSummary goalie) $
modify $ GI.setGameGoalie gid) $ modify $ GI.setGameGoalie gid) $
zip ['1'..] goalies zip ['1'..] goalies
-- | The edit menu
editMenu :: Menu ()
editMenu = Menu "*** EDIT ***" ()
[ MenuItem '1' "Create Player" $
modify createPlayer
, MenuItem '2' "Create Goalie" $
modify createGoalie
, MenuItem '3' "Edit Player" $
modify editPlayer
, MenuItem '4' "Edit Goalie" $
modify editGoalie
, MenuItem 'R' "Return to Main Menu" $
modify backHome
]

View File

@@ -26,25 +26,25 @@ module Mtlstats.Menu.EditGoalie
) where ) where
import Control.Monad.Trans.State (modify) import Control.Monad.Trans.State (modify)
import Data.Maybe (maybe)
import Lens.Micro ((.~)) import Lens.Micro ((.~))
import Mtlstats.Actions
import Mtlstats.Types import Mtlstats.Types
import Mtlstats.Types.Menu import Mtlstats.Types.Menu
-- | The 'Goalie' edit menu -- | The 'Goalie' edit menu
editGoalieMenu :: Menu () editGoalieMenu :: Menu ()
editGoalieMenu = Menu "*** EDIT GOALTENDER ***" () $ map editGoalieMenu = Menu "*** EDIT GOALTENDER ***" () $ map
(\(key, label, val) -> MenuItem key label $ modify $ maybe (\(ch, label, mode) -> MenuItem ch label $
(progMode .~ MainMenu) modify $ case mode of
(progMode.editGoalieStateL.egsMode .~) Nothing -> edit
val) Just m -> progMode.editGoalieStateL.egsMode .~ m)
-- key, label, value -- key, label, value
[ ( '1', "Edit number", Just EGNumber ) [ ( '1', "Edit number", Just EGNumber )
, ( '2', "Edit name", Just EGName ) , ( '2', "Edit name", Just EGName )
, ( '3', "Edit YTD stats", Just EGYtd ) , ( '3', "Edit YTD stats", Just EGYtd )
, ( '4', "Edit Lifetime stats", Just EGLifetime ) , ( '4', "Edit Lifetime stats", Just EGLifetime )
, ( 'R', "Return to Main Menu", Nothing ) , ( 'R', "Return to Edit Menu", Nothing )
] ]
-- | The 'Goalie' YTD edit menu -- | The 'Goalie' YTD edit menu

View File

@@ -28,22 +28,24 @@ module Mtlstats.Menu.EditPlayer
import Control.Monad.Trans.State (modify) import Control.Monad.Trans.State (modify)
import Lens.Micro ((.~)) import Lens.Micro ((.~))
import Mtlstats.Actions
import Mtlstats.Types import Mtlstats.Types
import Mtlstats.Types.Menu import Mtlstats.Types.Menu
-- | The 'Player' edit menu -- | The 'Player' edit menu
editPlayerMenu :: Menu () editPlayerMenu :: Menu ()
editPlayerMenu = Menu "*** EDIT PLAYER ***" () $ map editPlayerMenu = Menu "*** EDIT PLAYER ***" () $ map
(\(ch, label, mode) -> MenuItem ch label $ case mode of (\(ch, label, mode) -> MenuItem ch label $
Nothing -> modify $ progMode .~ MainMenu modify $ case mode of
Just m -> modify $ progMode.editPlayerStateL.epsMode .~ m) Nothing -> edit
Just m -> progMode.editPlayerStateL.epsMode .~ m)
-- key, label, value -- key, label, value
[ ( '1', "Edit number", Just EPNumber ) [ ( '1', "Edit number", Just EPNumber )
, ( '2', "Edit name", Just EPName ) , ( '2', "Edit name", Just EPName )
, ( '3', "Edit position", Just EPPosition ) , ( '3', "Edit position", Just EPPosition )
, ( '4', "Edit YTD stats", Just EPYtd ) , ( '4', "Edit YTD stats", Just EPYtd )
, ( '5', "Edit lifetime stats", Just EPLifetime ) , ( '5', "Edit lifetime stats", Just EPLifetime )
, ( 'R', "Finished editing", Nothing ) , ( 'R', "Return to Edit Menu", Nothing )
] ]
-- | The 'Player' YTD stats edit menu -- | The 'Player' YTD stats edit menu

View File

@@ -29,6 +29,7 @@ module Mtlstats.Prompt (
promptController, promptController,
strPrompt, strPrompt,
ucStrPrompt, ucStrPrompt,
namePrompt,
numPrompt, numPrompt,
selectPrompt, selectPrompt,
-- * Individual prompts -- * Individual prompts
@@ -126,6 +127,17 @@ ucStrPrompt
ucStrPrompt pStr act = (strPrompt pStr act) ucStrPrompt pStr act = (strPrompt pStr act)
{ promptProcessChar = \ch -> (++ [toUpper ch]) } { promptProcessChar = \ch -> (++ [toUpper ch]) }
-- | Creates a prompt which forces capitalization of input to
-- accomodate a player or goalie name
namePrompt
:: String
-- ^ The prompt string
-> (String -> Action ())
-- ^ The callback function for the result
-> Prompt
namePrompt pStr act = (strPrompt pStr act)
{ promptProcessChar = capitalizeName }
-- | Builds a numeric prompt -- | Builds a numeric prompt
numPrompt numPrompt
:: String :: String
@@ -157,7 +169,7 @@ selectPrompt params = Prompt
in "F" ++ show n ++ ") " ++ desc) in "F" ++ show n ++ ") " ++ desc)
results results
C.moveCursor row col C.moveCursor row col
, promptProcessChar = \ch -> (++[ch]) , promptProcessChar = spProcessChar params
, promptAction = \sStr -> if null sStr , promptAction = \sStr -> if null sStr
then spCallback params Nothing then spCallback params Nothing
else do else do
@@ -186,7 +198,7 @@ playerNumPrompt = numPrompt "Player number: " $
-- | Prompts for a new player's name -- | Prompts for a new player's name
playerNamePrompt :: Prompt playerNamePrompt :: Prompt
playerNamePrompt = strPrompt "Player name: " $ playerNamePrompt = namePrompt "Player name: " $
modify . (progMode.createPlayerStateL.cpsName .~) modify . (progMode.createPlayerStateL.cpsName .~)
-- | Prompts for a new player's position -- | Prompts for a new player's position
@@ -201,7 +213,7 @@ goalieNumPrompt = numPrompt "Goalie number: " $
-- | Prompts for the goalie's name -- | Prompts for the goalie's name
goalieNamePrompt :: Prompt goalieNamePrompt :: Prompt
goalieNamePrompt = strPrompt "Goalie name: " $ goalieNamePrompt = namePrompt "Goalie name: " $
modify . (progMode.createGoalieStateL.cgsName .~) modify . (progMode.createGoalieStateL.cgsName .~)
-- | Selects a player (creating one if necessary) -- | Selects a player (creating one if necessary)
@@ -218,6 +230,7 @@ selectPlayerPrompt pStr callback = selectPrompt SelectParams
, spSearch = \sStr db -> playerSearch sStr (db^.dbPlayers) , spSearch = \sStr db -> playerSearch sStr (db^.dbPlayers)
, spSearchExact = \sStr db -> fst <$> playerSearchExact sStr (db^.dbPlayers) , spSearchExact = \sStr db -> fst <$> playerSearchExact sStr (db^.dbPlayers)
, spElemDesc = playerSummary , spElemDesc = playerSummary
, spProcessChar = capitalizeName
, spCallback = callback , spCallback = callback
, spNotFound = \sStr -> do , spNotFound = \sStr -> do
mode <- gets (^.progMode) mode <- gets (^.progMode)
@@ -246,6 +259,7 @@ selectGoaliePrompt pStr callback = selectPrompt SelectParams
, spSearch = \sStr db -> goalieSearch sStr (db^.dbGoalies) , spSearch = \sStr db -> goalieSearch sStr (db^.dbGoalies)
, spSearchExact = \sStr db -> fst <$> goalieSearchExact sStr (db^.dbGoalies) , spSearchExact = \sStr db -> fst <$> goalieSearchExact sStr (db^.dbGoalies)
, spElemDesc = goalieSummary , spElemDesc = goalieSummary
, spProcessChar = capitalizeName
, spCallback = callback , spCallback = callback
, spNotFound = \sStr -> do , spNotFound = \sStr -> do
mode <- gets (^.progMode) mode <- gets (^.progMode)

View File

@@ -21,8 +21,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
module Mtlstats.Report (report, gameDate) where module Mtlstats.Report (report, gameDate) where
import Data.List (sortOn)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe (fromMaybe, mapMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Data.Ord (Down (Down))
import Lens.Micro ((^.)) import Lens.Micro ((^.))
import Mtlstats.Config import Mtlstats.Config
@@ -127,7 +129,7 @@ gameStatsReport width s = let
criteria (_, ps) = psPoints ps > 0 criteria (_, ps) = psPoints ps > 0
in filteredPlayerReport width "GAME" criteria playerStats in filteredPlayerReport width "GAME" criteria True playerStats
++ [""] ++ [""]
++ gameGoalieReport width goalieStats ++ gameGoalieReport width goalieStats
@@ -135,7 +137,8 @@ yearToDateStatsReport :: Int -> ProgState -> [String]
yearToDateStatsReport width s = let yearToDateStatsReport width s = let
db = s^.database db = s^.database
playerStats = map (\p -> (p, p^.pYtd)) playerStats = sortOn (Down . psPoints . snd)
$ map (\p -> (p, p^.pYtd))
$ filter playerIsActive $ filter playerIsActive
$ db^.dbPlayers $ db^.dbPlayers
@@ -143,23 +146,24 @@ yearToDateStatsReport width s = let
$ filter goalieIsActive $ filter goalieIsActive
$ db^.dbGoalies $ db^.dbGoalies
in playerReport width "YEAR TO DATE" playerStats in playerReport width "YEAR TO DATE" True playerStats
++ [""] ++ [""]
++ goalieReport width goalieStats ++ goalieReport width True goalieStats
lifetimeStatsReport :: Int -> ProgState -> [String] lifetimeStatsReport :: Int -> ProgState -> [String]
lifetimeStatsReport width s = let lifetimeStatsReport width s = let
db = s^.database db = s^.database
playerStats = map (\p -> (p, p^.pYtd)) playerStats = sortOn (Down . psPoints . snd)
$ map (\p -> (p, p^.pLifetime))
$ db^.dbPlayers $ db^.dbPlayers
goalieStats = map (\g -> (g, g^.gYtd)) goalieStats = map (\g -> (g, g^.gLifetime))
$ db^.dbGoalies $ db^.dbGoalies
in playerReport width "LIFETIME" playerStats in playerReport width "LIFETIME" False playerStats
++ [""] ++ [""]
++ goalieReport width goalieStats ++ goalieReport width False goalieStats
gameDate :: GameState -> String gameDate :: GameState -> String
gameDate gs = fromMaybe "" $ do gameDate gs = fromMaybe "" $ do
@@ -168,17 +172,23 @@ gameDate gs = fromMaybe "" $ do
d <- padNum 2 <$> gs^.gameDay d <- padNum 2 <$> gs^.gameDay
Just $ m ++ " " ++ d ++ " " ++ y Just $ m ++ " " ++ d ++ " " ++ y
playerReport :: Int -> String -> [(Player, PlayerStats)] -> [String] playerReport
playerReport width label ps = :: Int
filteredPlayerReport width label (const True) ps -> String
-> Bool
-> [(Player, PlayerStats)]
-> [String]
playerReport width label =
filteredPlayerReport width label (const True)
filteredPlayerReport filteredPlayerReport
:: Int :: Int
-> String -> String
-> ((Player, PlayerStats) -> Bool) -> ((Player, PlayerStats) -> Bool)
-> Bool
-> [(Player, PlayerStats)] -> [(Player, PlayerStats)]
-> [String] -> [String]
filteredPlayerReport width label criteria ps = let filteredPlayerReport width label criteria showTotals ps = let
tStats = foldl addPlayerStats newPlayerStats $ map snd ps tStats = foldl addPlayerStats newPlayerStats $ map snd ps
fps = filter criteria ps fps = filter criteria ps
@@ -217,23 +227,35 @@ filteredPlayerReport width label criteria ps = let
, CellText "" , CellText ""
] ++ statsCells tStats ] ++ statsCells tStats
table = overlayLast (label ++ " TOTALS") olayText = if showTotals
then label ++ " TOTALS"
else ""
table = overlayLast olayText
$ map (centre width) $ map (centre width)
$ complexTable ([right, left] ++ repeat right) $ complexTable ([right, left] ++ repeat right)
$ tHeader : body ++ [separator, totals] $ tHeader : body ++ if showTotals
then [separator, totals]
else []
in rHeader ++ table in rHeader ++ table
goalieReport :: Int -> [(Goalie, GoalieStats)] -> [String] goalieReport
goalieReport width goalieData = let :: Int
olayText = "GOALTENDING TOTALS" -> Bool
-> [(Goalie, GoalieStats)]
-> [String]
goalieReport width showTotals goalieData = let
olayText = if showTotals
then "GOALTENDING TOTALS"
else ""
tData = foldl addGoalieStats newGoalieStats tData = foldl addGoalieStats newGoalieStats
$ map snd goalieData $ map snd goalieData
header = header =
[ CellText "NO." [ CellText "NO."
, CellText $ left (length olayText) "GOALTENDER" , CellText $ padRight (length olayText) "GOALTENDER"
, CellText "GP" , CellText "GP"
, CellText " MIN" , CellText " MIN"
, CellText " GA" , CellText " GA"
@@ -265,7 +287,9 @@ goalieReport width goalieData = let
in map (centre width) in map (centre width)
$ overlayLast olayText $ overlayLast olayText
$ complexTable ([right, left] ++ repeat right) $ complexTable ([right, left] ++ repeat right)
$ header : body ++ [separator, summary] $ header : body ++ if showTotals
then [separator, summary]
else []
gameGoalieReport :: Int -> [(Goalie, GoalieStats)] -> [String] gameGoalieReport :: Int -> [(Goalie, GoalieStats)] -> [String]
gameGoalieReport width goalieData = let gameGoalieReport width goalieData = let

View File

@@ -230,6 +230,7 @@ data ProgMode
= MainMenu = MainMenu
| NewSeason | NewSeason
| NewGame GameState | NewGame GameState
| EditMenu
| CreatePlayer CreatePlayerState | CreatePlayer CreatePlayerState
| CreateGoalie CreateGoalieState | CreateGoalie CreateGoalieState
| EditPlayer EditPlayerState | EditPlayer EditPlayerState
@@ -239,6 +240,7 @@ instance Show ProgMode where
show MainMenu = "MainMenu" show MainMenu = "MainMenu"
show NewSeason = "NewSeason" show NewSeason = "NewSeason"
show (NewGame _) = "NewGame" show (NewGame _) = "NewGame"
show EditMenu = "EditMenu"
show (CreatePlayer _) = "CreatePlayer" show (CreatePlayer _) = "CreatePlayer"
show (CreateGoalie _) = "CreateGoalie" show (CreateGoalie _) = "CreateGoalie"
show (EditPlayer _) = "EditPlayer" show (EditPlayer _) = "EditPlayer"
@@ -622,6 +624,8 @@ data SelectParams a = SelectParams
-- ^ Search function looking for an exact match -- ^ Search function looking for an exact match
, spElemDesc :: a -> String , spElemDesc :: a -> String
-- ^ Provides a string description of an element -- ^ Provides a string description of an element
, spProcessChar :: Char -> String -> String
-- ^ Processes a character entered by the user
, spCallback :: Maybe Int -> Action () , spCallback :: Maybe Int -> Action ()
-- ^ The function when the selection is made -- ^ The function when the selection is made
, spNotFound :: String -> Action () , spNotFound :: String -> Action ()

View File

@@ -19,8 +19,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
-} -}
module Mtlstats.Util (nth, modifyNth, updateMap, slice) where module Mtlstats.Util
( nth
, modifyNth
, updateMap
, slice
, capitalizeName
) where
import Data.Char (isSpace, toUpper)
import qualified Data.Map as M import qualified Data.Map as M
-- | Attempt to select the element from a list at a given index -- | Attempt to select the element from a list at a given index
@@ -75,3 +82,25 @@ slice
-- ^ The list to take a subset of -- ^ The list to take a subset of
-> [a] -> [a]
slice offset len = take len . drop offset slice offset len = take len . drop offset
-- | Name capitalization function for a player
capitalizeName
:: Char
-- ^ The character being input
-> String
-- ^ The current string
-> String
-- ^ The resulting string
capitalizeName ch str = str ++ [ch']
where
ch' = if lockFlag str
then toUpper ch
else ch
lockFlag "" = True
lockFlag (c:cs)
| c == ',' = lockFlag' cs
| otherwise = lockFlag cs
lockFlag' "" = True
lockFlag' (c:cs)
| isSpace c = lockFlag' cs
| otherwise = False

View File

@@ -52,6 +52,7 @@ spec = describe "Mtlstats.Actions" $ do
removeCharSpec removeCharSpec
createPlayerSpec createPlayerSpec
createGoalieSpec createGoalieSpec
editSpec
editPlayerSpec editPlayerSpec
editGoalieSpec editGoalieSpec
addPlayerSpec addPlayerSpec
@@ -198,6 +199,12 @@ createGoalieSpec = describe "createGoalie" $
s = createGoalie newProgState s = createGoalie newProgState
in show (s^.progMode) `shouldBe` "CreateGoalie" in show (s^.progMode) `shouldBe` "CreateGoalie"
editSpec :: Spec
editSpec = describe "edit" $
it "should change the mode to EditMenu" $ let
ps = edit newProgState
in show (ps^.progMode) `shouldBe` "EditMenu"
editPlayerSpec :: Spec editPlayerSpec :: Spec
editPlayerSpec = describe "editPlayer" $ editPlayerSpec = describe "editPlayer" $
it "should change the mode appropriately" $ let it "should change the mode appropriately" $ let

View File

@@ -33,6 +33,7 @@ spec = describe "Mtlstats.Format" $ do
leftSpec leftSpec
rightSpec rightSpec
centreSpec centreSpec
padRightSpec
overlaySpec overlaySpec
monthSpec monthSpec
labelTableSpec labelTableSpec
@@ -98,6 +99,16 @@ centreSpec = describe "centre" $ do
it "should truncate the text" $ it "should truncate the text" $
centre 2 "foo" `shouldBe` "fo" centre 2 "foo" `shouldBe` "fo"
padRightSpec :: Spec
padRightSpec = describe "padRight" $ mapM_
(\(label, width, str, expected) -> context label $
it ("should be " ++ show expected) $
padRight width str `shouldBe` expected)
-- label, width, input string, expected
[ ( "text shorter", 5, "foo", "foo " )
, ( "text longer", 3, "foobar", "foobar" )
]
overlaySpec :: Spec overlaySpec :: Spec
overlaySpec = describe "overlay" $ do overlaySpec = describe "overlay" $ do

View File

@@ -32,6 +32,7 @@ spec = describe "Mtlstats.Util" $ do
modifyNthSpec modifyNthSpec
updateMapSpec updateMapSpec
sliceSpec sliceSpec
capitalizeNameSpec
nthSpec :: Spec nthSpec :: Spec
nthSpec = describe "nth" $ mapM_ nthSpec = describe "nth" $ mapM_
@@ -93,3 +94,23 @@ sliceSpec = describe "slice" $ do
context "negative offset" $ context "negative offset" $
it "should return the correct number of elements from the beginning" $ it "should return the correct number of elements from the beginning" $
slice (-10) 2 list `shouldBe` [2, 4] slice (-10) 2 list `shouldBe` [2, 4]
capitalizeNameSpec :: Spec
capitalizeNameSpec = describe "capitalizeName" $ mapM_
(\(label, ch, str, expected) -> context label $
it ("should be " ++ expected) $
capitalizeName ch str `shouldBe` expected)
-- label, character, string, expected
[ ( "initial lower", 'a', "", "A" )
, ( "initial upper", 'A', "", "A" )
, ( "initial non-alpha", '0', "", "0" )
, ( "pre-comma lower", 'a', "A", "AA" )
, ( "pre-comma upper", 'A', "A", "AA" )
, ( "pre-comma non-alpha", '0', "A", "A0" )
, ( "post-comma first lower", 'a', "FOO, ", "FOO, A" )
, ( "post-comma first upper", 'A', "FOO, ", "FOO, A" )
, ( "post-comma first non-alpha", '0', "FOO, ", "FOO, 0" )
, ( "unrestricted upper", 'A', "FOO, A", "FOO, AA" )
, ( "unrestricted lower", 'a', "FOO, A", "FOO, Aa" )
, ( "unrestricted non-alpha", '0', "FOO, A", "FOO, A0" )
]