package com.moseph.mra.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.*; import com.moseph.mra.*; import junit.framework.*; import javax.sound.midi.*; import org.w3c.dom.*; import static com.moseph.mra.midi.MidiUtilities.*; public class FragmentTest extends TestCase { private Fragment a; private Fragment b; private Fragment c; public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } public void setUp() { a = new Fragment(); b = new Fragment(); c = new Fragment(); Note n = new Note( 0.0, 66, 0.9, 0.5 ); a.addNote( n ); b.addNote( n ); Note n2 = new Note( 0.0, 68, 0.9, 0.5 ); c.addNote( n2 ); } public void testEquality() { assertEquals( "Equal fragments are shown to be not equal", a, b ); //System.out.println( a + "\n" + c ); //assertEquals( "Equal fragments are shown to be not equal", a, c ); assertFalse( "Transposed fragments are shown as equal", a.equals( c ) ); } public void testTranspose() { assertFalse( a.equals( c ) ); a.transpose( 2 ); assertEquals( a, c ); } public void testXML() { Document doc = MRAUtilities.getMAXMLXMLDocument(); Element elem = a.getXMLElement( doc ); Fragment fromXML = new Fragment( elem ); assertEquals( a, fromXML ); } public void testMerging() { Fragment f = new Fragment(); f.addNote( new Note( 0.0, 60, 0.7, 0.5, false, true ) ); f.addNote( new Note( 0.5, 60, 0.7, 0.5, true, false ) ); Fragment j = new Fragment(); j.addNote( new Note( 0.0, 60, 0.7, 1.0, false, false )); assertEquals( j, f ); } public void testChunking() { Fragment f = new Fragment( 4 ); f.addNote( 0.0, 60, 0.7, 1.5 ); f.addNote( 0.5, 62, 0.7, 2.0 ); f.addNote( 1.5, 64, 0.7, 1.5 ); System.err.println( f ); Fragment f1a = f.copyChunk( 0.0, 1.0 ); Fragment f1c = f1a.clone(); Fragment f2a = f.copyChunk( 1.0, 2.0 ); Fragment f2c = f2a.clone(); Fragment f3a = f.copyChunk( 2.0, 3.0 ); Fragment f3c = f3a.clone(); Fragment f1b = new Fragment( 1.0 ); f1b.addNote( new Note( 0.0, 60, 0.7, 1.0, false, true ) ); f1b.addNote( new Note( 0.5, 62, 0.7, 0.5, false, true ) ); Fragment f2b = new Fragment( 1.0 ); f2b.addNote( new Note( 0.0, 60, 0.7, 0.5, true, false ) ); f2b.addNote( new Note( 0.0, 62, 0.7, 1.0, true, true ) ); f2b.addNote( new Note( 0.5, 64, 0.7, 0.5, false, true ) ); Fragment f3b = new Fragment( 1.0 ); f3b.addNote( new Note( 0.0, 62, 0.7, 0.5, true, false ) ); f3b.addNote( new Note( 0.0, 64, 0.7, 1.0, true, false ) ); //System.out.println( "Section 1:\n"+ f1a + f1b + f1c ); //System.out.println( "Section 2:\n"+ f2a + f2b + f2c ); //System.out.println( "Section 3:\n"+ f3a + f3b + f3c ); assertTrue( "First chunk not equal to constructed version", f1a.equals( f1b ) ); assertTrue( "Second chunk not equal to constructed version", f2a.equals( f2b ) ); assertTrue( "Third chunk not equal to constructed version", f3a.equals( f3b ) ); f1a.append( f2a ); f1a.append( f3a ); f1c.append( f2c ); f1c.append( f3c ); System.out.println( "Reconstructed:\n"+ f1a + "\n" + f ); assertTrue( "Reconstructed version not equal to original", f1a.equals( f ) ); assertTrue( "Copied Reconstructed version not equal to original", f1c.equals( f ) ); } public void testAppendLengths() { Fragment p = new Fragment( 2.0 ); Fragment q = new Fragment( 2.0 ); assertEquals( "Blank fragments have correct length", 2.0, p.getLength() ); p.append( q ); assertEquals( "Concatenated blank fragments have correct length", 4.0, p.getLength() ); p.append( p ); assertEquals( "Appending to self works OK", 8.0, p.getLength() ); } public static Test suite() { return new TestSuite(FragmentTest.class); } public void testSerialization() { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos; try { oos = new ObjectOutputStream( bos ); oos.writeObject(a); byte[] data = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream( data ); ObjectInputStream ois = new ObjectInputStream( bis ); Object o = ois.readObject(); assertEquals( (Fragment)o, a ); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void testAdditionTime() { /* Fragment f = Fragment.getExampleFragment(); Fragment a = Fragment.getExampleFragment(); double start = timeAdditions( f, a, 2050 ); start = timeAdditions( f, a, 20050 ); for( int i = 0; i < 10000; i++ ) f.append( a ); double end = timeAdditions( f, a, 10000 ); end = timeAdditions( f, a, 1000 ); end = timeAdditions( f, a, 1000 ); System.out.printf( "Start: %f, End: %f\n", start, end ); assertTrue( end < start ); */ } public double timeAdditions( Fragment target, Fragment appendage, int number ) { Date before = new Date(); for( int i = 0; i < number; i++ ) target.append( appendage ); double time = new Date().getTime() - before.getTime(); System.out.println( "Timed " + number + ": " + time ); return time; } /* public void testAccessTime() { System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); System.out.println( "Warmup: " + timeFragmentAtEnd( 10000, 0.25, 1000 ) ); long big = timeFragmentAtEnd( 10000, 0.25, 1000 ); long small = timeFragmentAtEnd( 100, 0.25, 1000 ); assertTrue( big < small * 2 ); } */ long timeFragmentAtEnd( double length, double spacing, int numTests ) { Fragment f = new Fragment(); for( double i = 0.0; i < length; i+=spacing ) f.addNote( new Note( i, 64, 0.8, 0.5 )); Date before = new Date(); for( int i = 0; i < numTests; i++ ) f.copyChunk( length - 4.0, length ); return new Date().getTime() - before.getTime(); } public void testGracenotes() { Fragment f = new Fragment( 2 ); f.addNote( new Gracenote( 1.0, 60, 0.5 )); Fragment fa = f.copyChunk( 0, 2 ); assertEquals( f, fa ); Fragment g = new Fragment( 1 ); g.addNote( new Gracenote( 0.0, 60, 0.5 )); assertEquals( g, f.copyChunk( 1, 2) ); Fragment main = new Fragment(); main.addNote( new Gracenote( 0.0, 60, 0.5 )); main.addNote( new Note( 0.0, 64, 0.5, 1.0 )); main.addNote( new Gracenote( 1.0, 60, 0.5 )); main.addNote( new Note( 1.0, 64, 0.5, 1.0 )); Fragment tmp = main.copyChunk( 0.0, 1.0 ); System.out.println( main + "" + tmp ); tmp.append( main.copyChunk( 1.0, 2.0 )); System.out.println( main + "" + tmp ); assertEquals( main, tmp ); } public void testChunkLengths() { Fragment f = new Fragment( 1.0 ); f.addNote( 0.0, 60, 0.5, 0.7 ); assertEquals( "Fragment Length reported correctly", 1.0, f.getLength() ); assertEquals( "Chunk has correct length", 1.0, f.copyChunk( 0.0, 1.0 ).getLength() ); Fragment g = new Fragment(); g.addNote( 0.0, 60, 0.5, 0.7 ); assertEquals( "Fragment Length reported correctly", 0.7, g.getLength() ); assertEquals( "Chunk has correct length", 1.0, g.copyChunk( 0.0, 1.0 ).getLength() ); } public void testOrdering() { Fragment f = new Fragment(); f.addNote( 0.7, 60, 0.5, 0.7 ); f.addNote( 0.2, 63, 0.5, 1.9 ); f.addNote( 0.3, 42, 0.5, 0.3 ); f.addNote( 0.5, 42, 0.5, 0.9 ); f.addNote( 0.6, 42, 0.5, 0.9 ); System.out.println( f ); List<Note> notes = f.getNotes(); for( Note n : notes ) System.out.println( "n: " + n ); for( int i = 0; i < notes.size(); i++ ) for( int j = i+1; j< notes.size(); j++ ) { int comp = notes.get( i ).compareTo( notes.get( j ) ); assertTrue( comp < 0 ); //Compare the other way round! int compB = notes.get( j ).compareTo( notes.get( i ) ); assertTrue( compB > 0 ); } } public void testClosingMultipleNotes() { Fragment f = new Fragment(); Note n1 = new Note( 0.0, 60, 0.5, 1.0, false, true ); Note n2 = new Note( 0.5, 60, 0.5, 0.5, false, true ); Note n3 = new Note( 1.0, 60, 0.5, 0.5, true, false ); f.addNote( n1 ); f.addNote( n2 ); f.addNote( n3 ); System.out.println( f ); for( Note n : f.getNotes() ) assertFalse( "No notes left hanging", n.getLongerThan() ); } public void testRemovingNotes() { Fragment f1 = new Fragment(); Fragment f2 = new Fragment(); Fragment fRes = new Fragment(); Note n = new Note( 0.5, 66, 0.5, 0.5 ); Note n2 = new Note( 0.0, 60, 0.5, 0.5 ); Note n3 = new Note( 0.0, 60, 0.5, 0.5 ); f1.addNote( n ); f1.addNote( n2 ); f2.addNote( n ); f2.addNote( n2 ); fRes.addNote( n ); f1.remove( n2 ); assertEquals( fRes, f1 ); f2.remove( n3 ); assertEquals( fRes, f2 ); } public void testStripQuietNotes() { Fragment f1 = new Fragment(2.5); Fragment fExp = new Fragment(2.5); Note n1 = new Note( 0.0, 60, 0.6, 0.5 ); Note n2 = new Note( 0.5, 61, 0.6, 0.5 ); Note n3 = new Note( 1.0, 62, 0.006, 0.5 ); Note n4 = new Note( 1.5, 63, 0.006, 0.5 ); Note n5 = new Note( 2.0, 64, 0.6, 0.5 ); f1.addNote( n1 ); f1.addNote( n2 ); f1.addNote( n3 ); f1.addNote( n4 ); f1.addNote( n5 ); fExp.addNote( n1 ); fExp.addNote( n2 ); fExp.addNote( n5 ); f1.stripQuietNotes( 0.1 ); assertEquals( fExp, f1 ); } public void testChunkingOverlaps() { Fragment orig = new Fragment(); for( double i = 0.0; i < 10.0; i++ ) { double length = 0.2; if( i > 3 && i < 7 ) length = 3.8; orig.addNote( i, 20, 0.7, length ); } for( double step = 1.0; step < 2.0; step += 0.1 ) { Fragment chunked = new Fragment(); for( double d = 0.0; d < orig.getLength(); d += step ) chunked.addFragment( orig.copyChunk( d, d+step ), d ); System.out.println( "*** Running at step " + step + ":\n" + orig + "\n" + chunked ); assertEquals( orig, chunked ); } } }