@@ -23,7 +23,6 @@ global._ = jest.fn(str => str);
2323global . window = {
2424 btoa : jest . fn ( str => Buffer . from ( str , "utf8" ) . toString ( "base64" ) )
2525} ;
26- global . INVALIDPITCH = "Not a valid pitch name" ;
2726
2827const {
2928 scaleDegreeToPitchMapping,
@@ -98,15 +97,14 @@ const {
9897 numberToPitchSharp,
9998 getNumber,
10099 getNoteFromInterval,
101- NOTESSHARP ,
102- MUSICALMODES ,
103- getStepSizeUp,
104- getStepSizeDown,
105- INVALIDPITCH ,
106100 numberToPitch,
107101 GetNotesForInterval,
108102 base64Encode,
109- NOTESFLAT
103+ NOTESFLAT ,
104+ NOTESSHARP ,
105+ MUSICALMODES ,
106+ getStepSizeUp,
107+ getStepSizeDown
110108} = require ( "../musicutils" ) ;
111109
112110describe ( "musicutils" , ( ) => {
@@ -2243,6 +2241,39 @@ describe("getPitchInfo", () => {
22432241 } ) ;
22442242} ) ;
22452243
2244+ describe ( "_calculate_pitch_number" , ( ) => {
2245+ let activity , tur ;
2246+
2247+ beforeEach ( ( ) => {
2248+ activity = {
2249+ errorMsg : jest . fn ( )
2250+ } ;
2251+
2252+ tur = {
2253+ singer : {
2254+ lastNotePlayed : null ,
2255+ inNoteBlock : { } ,
2256+ notePitches : { } ,
2257+ noteOctaves : { } ,
2258+ keySignature : "C major" ,
2259+ movable : false ,
2260+ pitchNumberOffset : 0
2261+ }
2262+ } ;
2263+ } ) ;
2264+
2265+ it ( "calculates pitch number for a standard note string" , ( ) => {
2266+ const val = _calculate_pitch_number ( activity , "C4" , tur ) ;
2267+ expect ( typeof val ) . toBe ( "number" ) ;
2268+ } ) ;
2269+
2270+ it ( "calculates pitch number relative to another note" , ( ) => {
2271+ const valC4 = _calculate_pitch_number ( activity , "C4" , tur ) ;
2272+ const valC5 = _calculate_pitch_number ( activity , "C5" , tur ) ;
2273+ expect ( valC5 ) . toBeGreaterThan ( valC4 ) ;
2274+ } ) ;
2275+ } ) ;
2276+
22462277describe ( "NOTESFLAT" , ( ) => {
22472278 it ( "should contain 12 chromatic notes" , ( ) => {
22482279 expect ( NOTESFLAT . length ) . toBe ( 12 ) ;
@@ -2373,96 +2404,3 @@ describe("getStepSizeUp", () => {
23732404 expect ( result ) . toBe ( 0 ) ;
23742405 } ) ;
23752406} ) ;
2376-
2377- describe ( "_calculate_pitch_number" , ( ) => {
2378- it ( "should return the correct pitch number for common notes" , ( ) => {
2379- expect ( _calculate_pitch_number ( "C" , 4 ) ) . toBe ( 60 ) ;
2380- expect ( _calculate_pitch_number ( "A" , 4 ) ) . toBe ( 69 ) ;
2381- expect ( _calculate_pitch_number ( "C" , 5 ) ) . toBe ( 72 ) ;
2382- } ) ;
2383-
2384- it ( "should maintain enharmonic consistency" , ( ) => {
2385- expect ( _calculate_pitch_number ( "C#" , 4 ) ) . toBe ( 61 ) ;
2386- expect ( _calculate_pitch_number ( "Db" , 4 ) ) . toBe ( 61 ) ;
2387- } ) ;
2388-
2389- it ( "should return INVALIDPITCH for invalid input" , ( ) => {
2390- expect ( _calculate_pitch_number ( "Invalid" , 4 ) ) . toBe ( "Not a valid pitch name" ) ;
2391- expect ( _calculate_pitch_number ( null , 4 ) ) . toBe ( "Not a valid pitch name" ) ;
2392- } ) ;
2393- } ) ;
2394-
2395- describe ( "getPitchInfo" , ( ) => {
2396- it ( "should correctly parse string inputs" , ( ) => {
2397- const info = getPitchInfo ( "C#5" ) ;
2398- expect ( info ) . toEqual ( {
2399- name : "C#" ,
2400- octave : 5 ,
2401- pitchNumber : 73
2402- } ) ;
2403-
2404- const info10 = getPitchInfo ( "C10" ) ;
2405- expect ( info10 ) . toEqual ( {
2406- name : "C" ,
2407- octave : 10 ,
2408- pitchNumber : 132
2409- } ) ;
2410-
2411- // F𝄪5 (F double-sharp) → same pitch as G5 = (5+1)*12 + 7 = 79
2412- const infoDoubleSharp = getPitchInfo ( "F\u{1D12A}5" ) ;
2413- expect ( infoDoubleSharp . pitchNumber ) . toBe ( 79 ) ;
2414- expect ( infoDoubleSharp . octave ) . toBe ( 5 ) ;
2415-
2416- // Bb𝄫5 (B double-flat) → same pitch as A5 = (5+1)*12 + 9 = 81
2417- const infoDoubleFlat = getPitchInfo ( "B\u{1D12B}5" ) ;
2418- expect ( infoDoubleFlat . pitchNumber ) . toBe ( 81 ) ;
2419- expect ( infoDoubleFlat . octave ) . toBe ( 5 ) ;
2420-
2421- // Cx4 (C textual double-sharp) → same pitch as D4 = (4+1)*12 + 2 = 62
2422- const infoX = getPitchInfo ( "Cx4" ) ;
2423- expect ( infoX . pitchNumber ) . toBe ( 62 ) ;
2424- expect ( infoX . octave ) . toBe ( 4 ) ;
2425- } ) ;
2426-
2427- it ( "should correctly parse numeric inputs" , ( ) => {
2428- const info = getPitchInfo ( 60 ) ;
2429- expect ( info ) . toEqual ( {
2430- name : "C" ,
2431- octave : 4 ,
2432- pitchNumber : 60
2433- } ) ;
2434- } ) ;
2435-
2436- it ( "should handle invalid inputs" , ( ) => {
2437- const info = getPitchInfo ( "InvalidNote" ) ;
2438- expect ( info ) . toEqual ( {
2439- name : null ,
2440- octave : null ,
2441- pitchNumber : "Not a valid pitch name"
2442- } ) ;
2443- } ) ;
2444-
2445- it ( "should handle accidental offset accumulation edge cases" , ( ) => {
2446- // Gb-1: G(7) + flat(-1) = index 6 (G♭). (-1+1)*12 + 6 = 6
2447- const infoGbNeg1 = getPitchInfo ( "Gb-1" ) ;
2448- expect ( infoGbNeg1 . pitchNumber ) . toBe ( 6 ) ;
2449- expect ( infoGbNeg1 . octave ) . toBe ( - 1 ) ;
2450-
2451- // D𝄫-1 enharmonic of C at oct -1: (-1+1)*12 + 2 + (-2) = 0
2452- // Note: D𝄫-2 (oct=-2) gives -12; octave must be -1 to reach pitch 0.
2453- const infoDdblFlatNeg1 = getPitchInfo ( "D\u{1D12B}-1" ) ;
2454- expect ( infoDdblFlatNeg1 . pitchNumber ) . toBe ( 0 ) ;
2455- expect ( infoDdblFlatNeg1 . octave ) . toBe ( - 1 ) ;
2456-
2457- // E##4: E(4) + ##(+2) → index 6 (F#). (4+1)*12 + 4 + 2 = 66
2458- // Spelled with two ASCII '#' chars; each contributes +1 via ACCIDENTAL_SEMITONE_MAP.
2459- const infoEDblSharp4 = getPitchInfo ( "E##4" ) ;
2460- expect ( infoEDblSharp4 . pitchNumber ) . toBe ( 66 ) ;
2461- expect ( infoEDblSharp4 . octave ) . toBe ( 4 ) ;
2462-
2463- // Fx10: F(5) + x(+2) → index 7 (G). (10+1)*12 + 5 + 2 = 139
2464- const infoFx10 = getPitchInfo ( "Fx10" ) ;
2465- expect ( infoFx10 . pitchNumber ) . toBe ( 139 ) ;
2466- expect ( infoFx10 . octave ) . toBe ( 10 ) ;
2467- } ) ;
2468- } ) ;
0 commit comments