ipynb 0.1 → 0.1.0.1
raw patch · 4 files changed
+36/−6 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Changelog.md +4/−0
- ipynb.cabal +1/−1
- src/Data/Ipynb.hs +14/−1
- test/roundtrip.hs +17/−4
Changelog.md view
@@ -1,5 +1,9 @@ # Revision history for ipynb +## 0.1.0.1 -- 2020-04-25++* Fixed to build with base64-bytestring 1.1.+ ## 0.1.0.0 -- 2019-01-22 * Initial release.
ipynb.cabal view
@@ -1,5 +1,5 @@ name: ipynb-version: 0.1+version: 0.1.0.1 synopsis: Data structure for working with Jupyter notebooks (ipynb). description: ipynb defines a data structure for representing Jupyter notebooks, along with ToJSON and FromJSON instances
src/Data/Ipynb.hs view
@@ -45,6 +45,7 @@ import Data.Aeson as Aeson import qualified Data.Aeson.Types as Aeson import Data.ByteString (ByteString)+import qualified Data.ByteString as B import qualified Data.ByteString.Base64 as Base64 import Data.Char (isSpace) import qualified Data.HashMap.Strict as HM@@ -483,10 +484,22 @@ instance ToJSON MimeBundle where toJSON (MimeBundle m) = let mimeBundleToValue (BinaryData bs) =- toJSON $ TE.decodeUtf8 . Base64.joinWith "\n" 76 . Base64.encode $ bs+ toJSON .+ TE.decodeUtf8 .+ (<> "\n") .+ B.intercalate "\n" . chunksOf 76 .+ Base64.encode+ $ bs mimeBundleToValue (JsonData v) = v mimeBundleToValue (TextualData t) = toJSON (breakLines t) in toJSON $ M.map mimeBundleToValue m++chunksOf :: Int -> ByteString -> [ByteString]+chunksOf k s+ | B.null s = []+ | otherwise =+ let (h,t) = B.splitAt k s+ in h : chunksOf k t -- | Break up a string into a list of strings, each representing -- one line of the string (including trailing newline if any).
test/roundtrip.hs view
@@ -2,9 +2,10 @@ {-# LANGUAGE ScopedTypeVariables #-} import Data.Aeson (Value (..), eitherDecode, encode)-import Data.Aeson.Diff+import Data.Aeson.Diff as AesonDiff import qualified Data.ByteString.Base64 as Base64 import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString as B import qualified Data.HashMap.Strict as HM import Data.Ipynb import qualified Data.Text as T@@ -16,6 +17,7 @@ import System.FilePath import Test.Tasty import Test.Tasty.HUnit+import Data.Monoid main :: IO () main = do@@ -49,9 +51,18 @@ case Base64.decode (TE.encodeUtf8 (T.filter (/='\n') t)) of Left _ -> String t -- textual Right b -> String $- TE.decodeUtf8 . Base64.joinWith "\n" 76 . Base64.encode $ b+ TE.decodeUtf8 . (<> "\n") .+ B.intercalate "\n" . chunksOf 76 .+ Base64.encode $ b go v = v +chunksOf :: Int -> B.ByteString -> [B.ByteString]+chunksOf k s+ | B.null s = []+ | otherwise =+ let (h,t) = B.splitAt k s+ in h : chunksOf k t+ rtTest :: FilePath -> TestTree rtTest fp = testCase fp $ do inRaw <- BL.readFile fp@@ -68,7 +79,8 @@ (nb' :: Notebook NbV3) <- either error return $ eitherDecode outRaw (outJSON :: Value) <- either error return $ eitherDecode outRaw -- test that (read . write) == id- let patch' = diff (normalizeBase64 inJSON) (normalizeBase64 outJSON)+ let patch' = AesonDiff.diff+ (normalizeBase64 inJSON) (normalizeBase64 outJSON) assertBool (show patch') (patch' == Patch []) -- now test that (write . read) == id assertEqual "write . read != read" nb nb'@@ -81,7 +93,8 @@ (nb' :: Notebook NbV4) <- either error return $ eitherDecode outRaw (outJSON :: Value) <- either error return $ eitherDecode outRaw -- test that (read . write) == id- let patch' = diff (normalizeBase64 inJSON) (normalizeBase64 outJSON)+ let patch' = AesonDiff.diff+ (normalizeBase64 inJSON) (normalizeBase64 outJSON) assertBool (show patch') (patch' == Patch []) -- now test that (write . read) == id assertEqual "write . read != read" nb nb'