• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mbarbin / fingerboard / 118

23 Dec 2025 10:30PM UTC coverage: 92.134% (-3.0%) from 95.087%
118

Pull #11

github

web-flow
Merge b17e74f06 into ccb9da732
Pull Request #11: Reduce deps

323 of 528 new or added lines in 29 files covered. (61.17%)

1 existing line in 1 file now uncovered.

3830 of 4157 relevant lines covered (92.13%)

20265.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.55
/src/note.ml
1
(**********************************************************************************)
2
(*  Fingerboard - a microtonal geography of the cello fingerboard                 *)
3
(*  Copyright (C) 2022-2024 Mathieu Barbin <mathieu.barbin@gmail.com>             *)
4
(*                                                                                *)
5
(*  This file is part of Fingerboard.                                             *)
6
(*                                                                                *)
7
(*  Fingerboard is free software: you can redistribute it and/or modify it under  *)
8
(*  the terms of the GNU Affero General Public License as published by the Free   *)
9
(*  Software Foundation, either version 3 of the License, or any later version.   *)
10
(*                                                                                *)
11
(*  Fingerboard is distributed in the hope that it will be useful, but WITHOUT    *)
12
(*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or         *)
13
(*  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License   *)
14
(*  for more details.                                                             *)
15
(*                                                                                *)
16
(*  You should have received a copy of the GNU Affero General Public License      *)
17
(*  along with Fingerboard. If not, see <https://www.gnu.org/licenses/>.          *)
18
(**********************************************************************************)
19

20
module Letter_name = struct
21
  type t =
22
    | A
23
    | B
24
    | C
25
    | D
26
    | E
27
    | F
28
    | G
29

30
  let constructor_name = function
31
    | A -> "A"
5,218✔
32
    | B -> "B"
5,216✔
33
    | C -> "C"
5,313✔
34
    | D -> "D"
5,284✔
35
    | E -> "E"
5,309✔
36
    | F -> "F"
5,171✔
37
    | G -> "G"
5,199✔
38
  ;;
39

40
  let constructor_rank = function
41
    | A -> 0
256,681✔
42
    | B -> 1
813,552✔
43
    | C -> 2
329,623✔
44
    | D -> 3
230,640✔
45
    | E -> 4
238,830✔
46
    | F -> 5
244,093✔
47
    | G -> 6
251,087✔
48
  ;;
49

50
  let all = [ A; B; C; D; E; F; G ]
51
  let compare t1 t2 = Int.compare (constructor_rank t1) (constructor_rank t2)
23,898✔
52
  let equal t1 t2 = Int.equal (constructor_rank t1) (constructor_rank t2)
1,158,355✔
53
  let to_dyn t = Dyn.variant (constructor_name t) []
92✔
54
  let to_string = constructor_name
55

56
  let succ = function
57
    | A -> B
79,480✔
58
    | B -> C
77,306✔
59
    | C -> D
76,130✔
60
    | D -> E
78,590✔
61
    | E -> F
80,443✔
62
    | F -> G
80,893✔
63
    | G -> A
80,772✔
64
  ;;
65

66
  let pred = function
67
    | A -> G
15,988✔
68
    | B -> A
15,377✔
69
    | C -> B
14,632✔
70
    | D -> C
15,498✔
71
    | E -> D
15,994✔
72
    | F -> E
16,215✔
73
    | G -> F
16,221✔
74
  ;;
75

76
  let semitons_step ~from =
77
    match from with
437,125✔
78
    | A -> 2
63,098✔
79
    | B -> 1
61,628✔
80
    | C -> 2
59,666✔
81
    | D -> 2
61,588✔
82
    | E -> 1
63,353✔
83
    | F -> 2
63,856✔
84
    | G -> 2
63,936✔
85
  ;;
86

87
  let succ_octave_designation t ~octave_designation =
88
    octave_designation + if equal t B then 1 else 0
77,304✔
89
  ;;
90

91
  let pred_octave_designation t ~octave_designation =
92
    octave_designation - if equal t C then 1 else 0
14,632✔
93
  ;;
94
end
95

96
module Symbol = struct
97
  type t =
98
    | Triple_flat
99
    | Double_flat
100
    | Flat
101
    | Natural
102
    | Sharp
103
    | Double_sharp
104
    | Triple_sharp
105

106
  let constructor_rank = function
107
    | Triple_flat -> 0
4,992✔
108
    | Double_flat -> 1
6,518✔
109
    | Flat -> 2
7,980✔
110
    | Natural -> 3
8,460✔
111
    | Sharp -> 4
7,980✔
112
    | Double_sharp -> 5
6,518✔
113
    | Triple_sharp -> 6
4,992✔
114
  ;;
115

116
  let constructor_name = function
117
    | Triple_flat -> "Triple_flat"
×
118
    | Double_flat -> "Double_flat"
×
119
    | Flat -> "Flat"
×
120
    | Natural -> "Natural"
91✔
121
    | Sharp -> "Sharp"
1✔
122
    | Double_sharp -> "Double_sharp"
×
123
    | Triple_sharp -> "Triple_sharp"
×
124
  ;;
125

126
  let all = [ Triple_flat; Double_flat; Flat; Natural; Sharp; Double_sharp; Triple_sharp ]
127
  let compare t1 t2 = Int.compare (constructor_rank t1) (constructor_rank t2)
23,720✔
NEW
128
  let equal t1 t2 = Int.equal (constructor_rank t1) (constructor_rank t2)
×
129
  let to_dyn t = Dyn.variant (constructor_name t) []
92✔
130

131
  let to_string = function
132
    | Triple_flat -> "bbb"
2,496✔
133
    | Double_flat -> "bb"
3,281✔
134
    | Flat -> "b"
6,960✔
135
    | Natural -> ""
10,890✔
136
    | Sharp -> "#"
7,200✔
137
    | Double_sharp -> "##"
3,295✔
138
    | Triple_sharp -> "###"
2,496✔
139
  ;;
140

141
  let prefix_notation = function
142
    | Triple_flat -> "bbb"
×
143
    | Double_flat -> "bb"
×
144
    | Flat -> "b"
×
145
    | Natural -> ""
×
146
    | Sharp -> "#"
×
147
    | Double_sharp -> "x"
×
148
    | Triple_sharp -> "#x"
×
149
  ;;
150

151
  let semitons_shift = function
152
    | Triple_flat -> -3
10,676✔
153
    | Double_flat -> -2
12,246✔
154
    | Flat -> -1
20,055✔
155
    | Natural -> 0
29,135✔
156
    | Sharp -> 1
20,330✔
157
    | Double_sharp -> 2
12,274✔
158
    | Triple_sharp -> 3
10,676✔
159
  ;;
160

161
  let succ = function
162
    | Triple_flat -> Some Double_flat
1,684✔
163
    | Double_flat -> Some Flat
2,621✔
164
    | Flat -> Some Natural
3,765✔
165
    | Natural -> Some Sharp
3,577✔
166
    | Sharp -> Some Double_sharp
2,629✔
167
    | Double_sharp -> Some Triple_sharp
1,684✔
168
    | Triple_sharp -> None
×
169
  ;;
170

171
  let pred = function
172
    | Triple_flat -> None
×
173
    | Double_flat -> Some Triple_flat
1,684✔
174
    | Flat -> Some Double_flat
2,621✔
175
    | Natural -> Some Flat
3,656✔
176
    | Sharp -> Some Natural
3,577✔
177
    | Double_sharp -> Some Sharp
2,629✔
178
    | Triple_sharp -> Some Double_sharp
1,684✔
179
  ;;
180
end
181

182
type t =
183
  { letter_name : Letter_name.t
184
  ; symbol : Symbol.t
185
  ; octave_designation : Octave_designation.t
186
  }
187

188
let compare t ({ letter_name; symbol; octave_designation } as t2) : Ordering.t =
189
  if phys_equal t t2
23,898✔
NEW
190
  then Eq
×
191
  else (
23,898✔
192
    match Letter_name.compare t.letter_name letter_name with
193
    | (Lt | Gt) as r -> r
66✔
194
    | Eq ->
23,720✔
195
      (match Symbol.compare t.symbol symbol with
NEW
196
       | (Lt | Gt) as r -> r
×
197
       | Eq -> Octave_designation.compare t.octave_designation octave_designation))
23,720✔
198
;;
199

200
let equal t1 t2 =
201
  match compare t1 t2 with
23,898✔
202
  | Eq -> true
23,720✔
203
  | Lt | Gt -> false
66✔
204
;;
205

206
let to_dyn { letter_name; symbol; octave_designation } =
207
  Dyn.record
92✔
208
    [ "letter_name", letter_name |> Letter_name.to_dyn
92✔
209
    ; "symbol", symbol |> Symbol.to_dyn
92✔
210
    ; "octave_designation", octave_designation |> Octave_designation.to_dyn
92✔
211
    ]
212
;;
213

214
let to_string { letter_name; symbol; octave_designation } =
215
  Letter_name.to_string letter_name
36,618✔
216
  ^ Symbol.to_string symbol
36,618✔
217
  ^ Int.to_string octave_designation
36,618✔
218
;;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc