anchor.diff:      });
     });
     group('fraction', () {
  +    Matcher isFraction(Fraction other) {
  +      return isA<Fraction>()
  +          .having((each) => each.numerator, 'numerator', other.numerator)
  +          .having((each) => each.denominator, 'denominator', other.denominator)
  +          .having((each) => each.isFinite, 'isFinite', other.isFinite)
  +          .having((each) => each.isInfinite, 'isInfinite', other.isInfinite)
  +          .having((each) => each.isNegative, 'isNegative', other.isNegative)
  +          .having((each) => each.isNaN, 'isNaN', other.isNaN);
  +    }
  +
       group('construction', () {
         test('irreducible', () {
           final fraction = Fraction(3, 7);
  
positive.code:         });
          test('negativeInfinity', () {
            final fraction = Fraction.fromDouble(double.negativeInfinity);
            expect(fraction, Fraction.negativeInfinity);
            expect(fraction.isNaN, isFalse);
            expect(fraction.isInfinite, isTrue);
            expect(fraction.isNegative, isTrue);
            expect(fraction.isFinite, isFalse);
          });
        });
        test('zero', () {
          expect(Fraction.zero, Fraction(0));
          expect(Fraction(1, 2) + Fraction.zero, Fraction(1, 2));
        });
        test('one', () {
          expect(Fraction.one, Fraction(1));
          expect(Fraction(1, 2) * Fraction.one, Fraction(1, 2));
        });
        group('tryParse', () {
          test('basic', () {
            expect(Fraction.tryParse('1/2'), Fraction(1, 2));
            expect(Fraction.tryParse(' 1/2'), Fraction(1, 2));
            expect(Fraction.tryParse('1 /2'), Fraction(1, 2));
            expect(Fraction.tryParse('1/ 2'), Fraction(1, 2));
            expect(Fraction.tryParse('1/2 '), Fraction(1, 2));
          });
          test('negative', () {
            expect(Fraction.tryParse('-1/2'), Fraction(-1, 2));
            expect(Fraction.tryParse('1/-2'), Fraction(-1, 2));
            expect(Fraction.tryParse('-1/-2'), Fraction(1, 2));
          });
          test('integer', () {
            expect(Fraction.tryParse('3'), Fraction(3));
            expect(Fraction.tryParse(' 3'), Fraction(3));
            expect(Fraction.tryParse('3 '), Fraction(3));
          });
          test('error', () {
            expect(Fraction.tryParse(''), isNull);
  
negative.code:         expect(Fraction(1, 2).closeTo(Fraction(1, 3), 0.1), isFalse);
          expect(Fraction(1, 2).closeTo(Fraction(2, 4), 0.1), isTrue);
          expect(Fraction(1, 2).closeTo(Fraction(3, 5), 0.2), isTrue);
          expect(Fraction.nan.closeTo(Fraction(1, 2), 0.1), isFalse);
          expect(Fraction(1, 2).closeTo(Fraction.nan, 0.1), isFalse);
          expect(Fraction.nan.closeTo(Fraction.nan, 0.1), isFalse);
          expect(Fraction.infinity.closeTo(Fraction(1, 2), 0.1), isFalse);
          expect(Fraction(1, 2).closeTo(Fraction.infinity, 0.1), isFalse);
          expect(Fraction.infinity.closeTo(Fraction.infinity, 0.1), isFalse);
          expect(Fraction.negativeInfinity.closeTo(Fraction(1, 2), 0.1), isFalse);
          expect(Fraction(1, 2).closeTo(Fraction.negativeInfinity, 0.1), isFalse);
          expect(
              Fraction.negativeInfinity.closeTo(Fraction.negativeInfinity, 0.1),
              isFalse);
        });
        test('equals', () {
          expect(Fraction(2, 3) == Fraction(2, 3), isTrue);
          expect(Fraction(2, 3) == Fraction(4, 5), isFalse);
          expect(Fraction(4, 5) == Fraction(2, 3), isFalse);
          expect(Fraction.nan == Fraction(2, 3), isFalse);
          expect(Fraction(2, 3) == Fraction.nan, isFalse);
          expect(Fraction.nan == Fraction.nan, isFalse);
          expect(Fraction.infinity == Fraction.infinity, isTrue);
          expect(Fraction.negativeInfinity == Fraction.negativeInfinity, isTrue);
        });
        test('hash', () {
          expect(Fraction(2, 3).hashCode, Fraction(2, 3).hashCode);
  