<commit_before>﻿module FSharpx.DataStructures.Tests.FileSystemZipperTest

open System
open FSharpx
open FSharpx.DataStructures
open NUnit.Framework
open FsUnit

type FileName = string
type FSItem =
    | File of FileName
    | Folder of FileName * FSItem list

type Path = 
    | Top
    | Node of FileName * FSItem list * FSItem list

type FSZipper = FSItem * Path

/// Moves the zipper one directory up
let up (zipper:FSZipper) : FSZipper = 
    match zipper with
    | (item,(Node (name,ls,rs) as bs)) -> Folder(name,(ls @ [item] @ rs)), bs

let nameIs name = function
    | File fileName -> name = fileName
    | Folder(folderName,_) ->name = folderName  

let moveTo name (zipper:FSZipper) : FSZipper = 
    match zipper with
    | Folder(folderName,items),bs ->
        let (ls, item::rs) = List.split (nameIs name) items
        item,Node(folderName,ls,rs)
  
let zipper fileSystem : FSZipper = fileSystem,Top

let disk =
    Folder("root",
        [File "goat_yelling_like_man.wmv"
         File "pope_time.avi"
         Folder("pics",
            [File "ape_throwing_up.jpg"
             File "watermelon_smash.gif"
             File "skull_man(scary).bmp"])
         File "dijon_poupon.doc"
         Folder("programs",
            [File "fartwizard.exe"
             File "owl_bandit.dmg"
             File "not_a_virus.exe"
             Folder("source code",
                [File "best_hs_prog.hs"
                 File "random.hs"])
            ])
        ])

[<Test>]
let ``Can move to subdir``() =       
   let item,_ = disk |> zipper |> moveTo "pics" |> moveTo "skull_man(scary).bmp"  
   Assert.AreEqual(item,File "skull_man(scary).bmp")<commit_msg>Using records in the FileSystemZipper sample<commit_after>﻿module FSharpx.DataStructures.Tests.FileSystemZipperTest

open System
open FSharpx
open FSharpx.DataStructures
open NUnit.Framework
open FsUnit

type FileName = string

type Folder = { Name: FileName; Items: FSItem list }
and FSItem =
    | File of FileName
    | Folder of Folder

let folder(name,items) = Folder { Name = name ; Items = items }

type Path = FileName * FSItem list * FSItem list

type FSZipper = { Focus : FSItem; Path : Path option }

/// Moves the zipper one directory up
let up (zipper:FSZipper) : FSZipper = 
   
    match zipper.Path with
    | Some (name,ls,rs) -> { zipper with Focus = Folder { Name = name; Items = ls @ [zipper.Focus] @ rs} }

let getName = function
    | File fileName -> fileName
    | Folder folder -> folder.Name  

let nameIs name item = getName item = name

let moveTo name (zipper:FSZipper) : FSZipper = 
    match zipper.Focus with
    | Folder folder ->
        let (ls, item::rs) = List.split (nameIs name) folder.Items
        { Focus = item; Path = Some(folder.Name,ls,rs) }
  
let zipper fileSystem : FSZipper = { Focus = fileSystem; Path = None }

let disk =
    folder("root",
        [File "goat_yelling_like_man.wmv"
         File "pope_time.avi"
         folder("pics",
            [File "ape_throwing_up.jpg"
             File "watermelon_smash.gif"
             File "skull_man(scary).bmp"])
         File "dijon_poupon.doc"
         folder("programs",
            [File "fartwizard.exe"
             File "owl_bandit.dmg"
             File "not_a_virus.exe"
             folder("source code",
                [File "best_hs_prog.hs"
                 File "random.hs"])
            ])
        ])

[<Test>]
let ``Can move to subdir``() =       
   let z = disk |> zipper |> moveTo "pics" |> moveTo "skull_man(scary).bmp"  
   Assert.AreEqual(z.Focus,File "skull_man(scary).bmp")

[<Test>]
let ``Can move to subdir and up again``() =       
   let z = disk |> zipper |> moveTo "pics" |> moveTo "skull_man(scary).bmp" |> up
   Assert.AreEqual(getName z.Focus,"pics")
{'fraction_non_alphanumeric': 0.1162356704878699, 'fraction_numerical': 0.0, 'mean_word_length': 2.506542056074766, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2273529', 'n_tokens_mistral': 1318, 'n_tokens_neox': 1276, 'n_words': 328}