Skip to content

Commit

Permalink
Merge 9408778 into dce0c25
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed May 13, 2024
2 parents dce0c25 + 9408778 commit 64a8f89
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 100 deletions.
14 changes: 14 additions & 0 deletions lib/src/comparators.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/// Adds comparison operators to a comparable class with a total order.
mixin Comparators<T> implements Comparable<T> {
/// Whether this [T] is numerically smaller than [other].
bool operator <(T other) => compareTo(other) < 0;

/// Whether this [T] is numerically smaller than or equal to [other].
bool operator <=(T other) => compareTo(other) <= 0;

/// Whether this [T] is numerically greater than [other].
bool operator >(T other) => compareTo(other) > 0;

/// Whether this [T] is numerically greater than or equal to [other].
bool operator >=(T other) => compareTo(other) >= 0;
}
51 changes: 2 additions & 49 deletions lib/src/interval/interval.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import 'package:meta/meta.dart' show immutable;
import 'package:music_notes/utils.dart';

import '../comparators.dart';
import '../enharmonic.dart';
import '../note/note.dart';
import '../scalable.dart';
Expand All @@ -18,7 +19,7 @@ import 'size.dart';
/// * [IntervalClass].
@immutable
final class Interval
with Enharmonic<IntervalClass>
with Enharmonic<IntervalClass>, Comparators<Interval>
implements Comparable<Interval> {
/// Number of lines and spaces (or alphabet letters) spanning the two notes,
/// including the beginning and end.
Expand Down Expand Up @@ -430,54 +431,6 @@ final class Interval
/// ```
Interval operator -() => Interval._(-size, quality);

/// Whether this [Interval] is smaller than [other], regardless of their
/// direction (ascending or descending).
///
/// Example:
/// ```dart
/// Interval.m3 < Interval.P5 == true
/// Interval.m7 < Interval.P5 == false
/// Interval.d4 < Interval.d4 == false
/// Interval.M3 < -Interval.P4 == true
/// ```
bool operator <(Interval other) => semitones.abs() < other.semitones.abs();

/// Whether this [Interval] is smaller than or equal to [other], regardless of
/// their direction (ascending or descending).
///
/// Example:
/// ```dart
/// Interval.m3 <= Interval.P5 == true
/// Interval.m7 <= Interval.P5 == false
/// Interval.d4 <= Interval.d4 == true
/// Interval.P4 <= -Interval.P4 == true
/// ```
bool operator <=(Interval other) => semitones.abs() <= other.semitones.abs();

/// Whether this [Interval] is larger than [other], regardless of their
/// direction (ascending or descending).
///
/// Example:
/// ```dart
/// Interval.P5 > Interval.m3 == true
/// Interval.P5 > Interval.m7 == false
/// Interval.d4 > Interval.d4 == false
/// -Interval.P4 > Interval.M3 == true
/// ```
bool operator >(Interval other) => semitones.abs() > other.semitones.abs();

/// Whether this [Interval] is larger than or equal to [other], regardless of
/// their direction (ascending or descending).
///
/// Example:
/// ```dart
/// Interval.P5 >= Interval.m3 == true
/// Interval.P5 >= Interval.m7 == false
/// Interval.d4 >= Interval.d4 == true
/// -Interval.P4 >= Interval.P4 == true
/// ```
bool operator >=(Interval other) => semitones.abs() >= other.semitones.abs();

@override
bool operator ==(Object other) =>
other is Interval && size == other.size && quality == other.quality;
Expand Down
5 changes: 4 additions & 1 deletion lib/src/interval/interval_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:collection/collection.dart' show IterableExtension;
import 'package:meta/meta.dart' show immutable;
import 'package:music_notes/utils.dart';

import '../comparators.dart';
import '../music.dart';
import '../note/pitch_class.dart';
import 'interval.dart';
Expand All @@ -24,7 +25,9 @@ import 'size.dart';
/// See also:
/// * [Interval].
@immutable
final class IntervalClass implements Comparable<IntervalClass> {
final class IntervalClass
with Comparators<IntervalClass>
implements Comparable<IntervalClass> {
/// The distance in semitones that defines this [IntervalClass].
final int semitones;

Expand Down
45 changes: 4 additions & 41 deletions lib/src/note/pitch.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:meta/meta.dart' show immutable;
import 'package:music_notes/utils.dart';

import '../comparators.dart';
import '../enharmonic.dart';
import '../harmony/chord.dart';
import '../harmony/chord_pattern.dart';
Expand Down Expand Up @@ -29,7 +30,9 @@ import 'pitch_class.dart';
/// * [Frequency].
/// * [ClosestPitch].
@immutable
final class Pitch extends Scalable<Pitch> implements Comparable<Pitch> {
final class Pitch extends Scalable<Pitch>
with Comparators<Pitch>
implements Comparable<Pitch> {
/// The note inside the octave.
final Note note;

Expand Down Expand Up @@ -505,46 +508,6 @@ final class Pitch extends Scalable<Pitch> implements Comparable<Pitch> {
/// ```
ClosestPitch operator -(Cent cents) => ClosestPitch(this, cents: -cents);

/// Whether this [Pitch] is lower than [other].
///
/// Example:
/// ```dart
/// Note.c.inOctave(4) < Note.c.inOctave(5) == true
/// Note.a.inOctave(5) < Note.g.inOctave(4) == false
/// Note.d.inOctave(4) < Note.d.inOctave(4) == false
/// ```
bool operator <(Pitch other) => semitones < other.semitones;

/// Whether this [Pitch] is lower than or equal to [other].
///
/// Example:
/// ```dart
/// Note.c.inOctave(4) <= Note.c.inOctave(5) == true
/// Note.a.inOctave(5) <= Note.g.inOctave(4) == false
/// Note.d.inOctave(4) <= Note.d.inOctave(4) == true
/// ```
bool operator <=(Pitch other) => semitones <= other.semitones;

/// Whether this [Pitch] is higher than [other].
///
/// Example:
/// ```dart
/// Note.c.inOctave(5) > Note.c.inOctave(4) == true
/// Note.a.inOctave(4) > Note.g.inOctave(5) == false
/// Note.d.inOctave(4) > Note.d.inOctave(4) == false
/// ```
bool operator >(Pitch other) => semitones > other.semitones;

/// Whether this [Pitch] is higher than or equal to [other].
///
/// Example:
/// ```dart
/// Note.c.inOctave(5) >= Note.c.inOctave(4) == true
/// Note.a.inOctave(4) >= Note.g.inOctave(5) == false
/// Note.d.inOctave(4) >= Note.d.inOctave(4) == true
/// ```
bool operator >=(Pitch other) => semitones >= other.semitones;

@override
bool operator ==(Object other) =>
other is Pitch && note == other.note && octave == other.octave;
Expand Down
18 changes: 9 additions & 9 deletions test/src/interval/interval_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -589,12 +589,12 @@ void main() {
group('operator <()', () {
test('returns whether this Interval is smaller than other', () {
expect(Interval.m2 < Interval.M3, isTrue);
expect(Interval.M2 < -Interval.P5, isTrue);
expect(-Interval.m6 < Interval.d5, isTrue);
expect(Interval.A4 < Interval.d5, isTrue);

expect(Interval.m3 < Interval.m2, isFalse);
expect(Interval.P4 < Interval.P4, isFalse);
expect(Interval.A4 < Interval.d5, isFalse);
expect(-Interval.m6 < Interval.d5, isFalse);
expect(Interval.M2 < -Interval.P5, isFalse);
});
});

Expand All @@ -603,25 +603,25 @@ void main() {
'returns whether this Interval is smaller than or equal to other',
() {
expect(Interval.P1 <= Interval.M3, isTrue);
expect(Interval.m2 <= -Interval.A4, isTrue);
expect(Interval.d8 <= Interval.d8, isTrue);
expect(-Interval.m6 <= Interval.d5, isTrue);
expect(-Interval.A4 <= Interval.d5, isTrue);

expect(Interval.m3 <= Interval.m2, isFalse);
expect(-Interval.m6 <= Interval.d5, isFalse);
expect(Interval.m2 <= -Interval.A4, isFalse);
},
);
});

group('operator >()', () {
test('returns whether this Interval is larger than other', () {
expect(Interval.M3 > Interval.m2, isTrue);
expect(-Interval.P5 > Interval.M2, isTrue);
expect(Interval.A5 > -Interval.m6, isTrue);
expect(Interval.d8 > Interval.M7, isTrue);

expect(Interval.m2 > Interval.m3, isFalse);
expect(Interval.P4 > Interval.P4, isFalse);
expect(Interval.d8 > Interval.M7, isFalse);
expect(Interval.A5 > -Interval.m6, isFalse);
expect(-Interval.P5 > Interval.M2, isFalse);
});
});

Expand All @@ -630,13 +630,13 @@ void main() {
'returns whether this Interval is larger than or equal to other',
() {
expect(Interval.M3 >= Interval.m2, isTrue);
expect(-Interval.P5 >= Interval.M2, isTrue);
expect(Interval.P4 >= Interval.P4, isTrue);
expect(Interval.d8 >= Interval.m7, isTrue);
expect(Interval.A5 >= -Interval.m6, isTrue);

expect(Interval.m2 >= Interval.m3, isFalse);
expect(-Interval.A1 >= Interval.m3, isFalse);
expect(-Interval.P5 >= Interval.M2, isFalse);
},
);
});
Expand Down
29 changes: 29 additions & 0 deletions test/src/interval/size_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,34 @@ void main() {
expect(Size.twelfth.simple.augmented, Interval.A5);
});
});
/*
group('.simple', () {
test('returns the simplified version of this Size', () {
expect(Size.unison.simple, Size.unison);
expect((-Size.third).simple, -Size.third);
expect(Size.ninth.simple, Size.second);
expect((-Size.eleventh).simple, -Size.fourth);
expect(const Size(15).simple, Size.octave);
expect(const Size(16).simple, Size.second);
expect(const Size(17).simple, Size.third);
expect(const Size(18).simple, Size.fourth);
expect(const Size(19).simple, Size.fifth);
expect(const Size(20).simple, Size.sixth);
expect(const Size(21).simple, Size.seventh);
expect(const Size(22).simple, Size.octave);
expect(const Size(23).simple, Size.second);
expect(const Size(24).simple, Size.third);
expect(const Size(25).simple, Size.fourth);
expect(const Size(26).simple, Size.fifth);
expect(const Size(27).simple, Size.sixth);
expect(const Size(28).simple, Size.seventh);
expect(const Size(29).simple, Size.octave);
expect(const Size(36).simple, Size.octave);
});
});
*/
});
}
12 changes: 12 additions & 0 deletions test/src/note/pitch_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,11 @@ void main() {
test('returns whether this Pitch is lower than other', () {
expect(Note.a.inOctave(3) < Note.a.inOctave(4), isTrue);
expect(Note.f.sharp.inOctave(4) < Note.a.inOctave(4), isTrue);
expect(
skip: 'See #477',
Note.g.sharp.inOctave(4) < Note.a.flat.inOctave(3),
isTrue,
);

expect(Note.a.inOctave(4) < Note.a.inOctave(4), isFalse);
expect(Note.a.flat.inOctave(4) < Note.a.flat.inOctave(3), isFalse);
Expand All @@ -1393,6 +1398,7 @@ void main() {
expect(Note.a.inOctave(3) <= Note.a.inOctave(4), isTrue);
expect(Note.f.sharp.inOctave(4) <= Note.a.inOctave(4), isTrue);
expect(Note.a.inOctave(4) <= Note.a.inOctave(4), isTrue);
expect(Note.g.sharp.inOctave(4) <= Note.a.flat.inOctave(4), isTrue);

expect(Note.a.flat.inOctave(4) <= Note.a.flat.inOctave(3), isFalse);
expect(Note.a.inOctave(4) <= Note.f.inOctave(4), isFalse);
Expand All @@ -1403,6 +1409,11 @@ void main() {
test('returns whether this Pitch is higher than other', () {
expect(Note.a.inOctave(4) > Note.a.inOctave(3), isTrue);
expect(Note.a.inOctave(4) > Note.g.flat.inOctave(4), isTrue);
expect(
skip: 'See #477',
Note.a.flat.inOctave(4) > Note.g.sharp.inOctave(4),
isTrue,
);

expect(Note.a.inOctave(4) > Note.a.inOctave(4), isFalse);
expect(Note.a.flat.inOctave(3) > Note.a.flat.inOctave(4), isFalse);
Expand All @@ -1415,6 +1426,7 @@ void main() {
expect(Note.a.inOctave(4) >= Note.a.inOctave(3), isTrue);
expect(Note.a.inOctave(4) >= Note.f.sharp.inOctave(4), isTrue);
expect(Note.a.inOctave(4) >= Note.a.inOctave(4), isTrue);
expect(Note.a.flat.inOctave(4) >= Note.g.sharp.inOctave(3), isTrue);

expect(Note.a.flat.inOctave(3) >= Note.a.flat.inOctave(4), isFalse);
expect(Note.f.inOctave(4) >= Note.a.inOctave(4), isFalse);
Expand Down

0 comments on commit 64a8f89

Please sign in to comment.