<commit_before>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library rol_tests;

import 'dart:async';
import 'package:observe/observe.dart';
import 'package:nv/src/shared.dart';
import 'package:unittest/unittest.dart';
import '../src/observe_test_utils.dart';

void main() {
  // TODO(jmesserly): need all standard List API tests.

  StreamSubscription sub;

  sharedTearDown() { sub.cancel(); }

  group('observe length', () {

    ObservableList list;
    ReadOnlyObservableList rol;

    List<ChangeRecord> changes;

    setUp(() {
      list = toObservable([1, 2, 3]);
      rol = new ReadOnlyObservableList(list);
      changes = null;
      sub = rol.changes.listen((records) {
        changes = records.where((r) => r.changes(_LENGTH)).toList();
      });
    });

    tearDown(sharedTearDown);

    observeTest('add changes length', () {
      list.add(4);
      expect(list, [1, 2, 3, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('removeObject', () {
      list.remove(2);
      expect(list, orderedEquals([1, 3]));

      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('removeRange changes length', () {
      list.add(4);
      list.removeRange(1, 3);
      expect(list, [1, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('length= changes length', () {
      list.length = 5;
      expect(list, [1, 2, 3, null, null]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('[]= does not change length', () {
      list[2] = 9000;
      expect(list, [1, 2, 9000]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('clear changes length', () {
      list.clear();
      expect(list, []);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });
  });

  group('observe index', () {
    ObservableList list;
    ReadOnlyObservableList rol;
    List<ChangeRecord> changes;

    setUp(() {
      list = toObservable([1, 2, 3]);
      rol = new ReadOnlyObservableList(list);
      changes = null;
      sub = rol.changes.listen((records) {
        changes = records.where((r) => r.changes(1)).toList();
      });
    });

    tearDown(sharedTearDown);

    observeTest('add does not change existing items', () {
      list.add(4);
      expect(list, [1, 2, 3, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('[]= changes item', () {
      list[1] = 777;
      expect(list, [1, 777, 3]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_change(1, addedCount: 1, removedCount: 1)]);
    });

    observeTest('[]= on a different item does not fire change', () {
      list[2] = 9000;
      expect(list, [1, 2, 9000]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('set multiple times results in one change', () {
      list[1] = 777;
      list[1] = 42;
      expect(list, [1, 42, 3]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, addedCount: 1, removedCount: 1),
      ]);
    });

    observeTest('set length without truncating item means no change', () {
      list.length = 2;
      expect(list, [1, 2]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('truncate removes item', () {
      list.length = 1;
      expect(list, [1]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_change(1, removedCount: 2)]);
    });

    observeTest('truncate and add new item', () {
      list.length = 1;
      list.add(42);
      expect(list, [1, 42]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, removedCount: 2, addedCount: 1)
      ]);
    });

    observeTest('truncate and add same item', () {
      list.length = 1;
      list.add(2);
      expect(list, [1, 2]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, removedCount: 2, addedCount: 1)
      ]);
    });
  });

  observeTest('toString', () {
    var list = toObservable([1, 2, 3]);
    var rol = new ReadOnlyObservableList(list);
    expect(rol.toString(), '[1, 2, 3]');
  });

  group('change records', () {

    List<ChangeRecord> records;
    ObservableList list;
    ReadOnlyObservableList rol;

    setUp(() {
      list = toObservable([1, 2, 3, 1, 3, 4]);
      rol = new ReadOnlyObservableList(list);
      records = null;
      sub = rol.changes.listen((r) { records = r; });
    });

    tearDown(sharedTearDown);

    observeTest('read operations', () {
      expect(rol.length, 6);
      expect(rol[0], 1);
      expect(rol.indexOf(4), 5);
      expect(rol.indexOf(1), 0);
      expect(rol.indexOf(1, 1), 3);
      expect(rol.lastIndexOf(1), 3);
      expect(rol.last, 4);
      var copy = new List<int>();
      rol.forEach((i) { copy.add(i); });
      expect(copy, orderedEquals([1, 2, 3, 1, 3, 4]));
      performMicrotaskCheckpoint();

      // no change from read-only operators
      expectChanges(records, null);
    });

    observeTest('add', () {
      list.add(5);
      list.add(6);
      expect(list, orderedEquals([1, 2, 3, 1, 3, 4, 5, 6]));

      performMicrotaskCheckpoint();
      expectChanges(records, [<commit_msg>allow reuse of ROOL tests by implementors/extenders of ROOL<commit_after>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library rol_tests;

import 'dart:async';
import 'package:observe/observe.dart';
import 'package:nv/src/shared.dart';
import 'package:unittest/unittest.dart';
import '../src/observe_test_utils.dart';

typedef ReadOnlyObservableList<E> ROOLFactory<E>(ObservableList<E> source);

void main() {
  sharedMain(_simpleFactory);
}

ReadOnlyObservableList<int> _simpleFactory(ObservableList<int> source) {
  return new ReadOnlyObservableList(source);
}

void sharedMain(ROOLFactory factory) {
  // TODO(jmesserly): need all standard List API tests.

  StreamSubscription sub;

  sharedTearDown() { sub.cancel(); }

  group('observe length', () {

    ObservableList list;
    ReadOnlyObservableList rol;

    List<ChangeRecord> changes;

    setUp(() {
      list = toObservable([1, 2, 3]);
      rol = factory(list);
      changes = null;
      sub = rol.changes.listen((records) {
        changes = records.where((r) => r.changes(_LENGTH)).toList();
      });
    });

    tearDown(sharedTearDown);

    observeTest('add changes length', () {
      list.add(4);
      expect(list, [1, 2, 3, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('removeObject', () {
      list.remove(2);
      expect(list, orderedEquals([1, 3]));

      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('removeRange changes length', () {
      list.add(4);
      list.removeRange(1, 3);
      expect(list, [1, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('length= changes length', () {
      list.length = 5;
      expect(list, [1, 2, 3, null, null]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });

    observeTest('[]= does not change length', () {
      list[2] = 9000;
      expect(list, [1, 2, 9000]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('clear changes length', () {
      list.clear();
      expect(list, []);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_lengthChange]);
    });
  });

  group('observe index', () {
    ObservableList list;
    ReadOnlyObservableList rol;
    List<ChangeRecord> changes;

    setUp(() {
      list = toObservable([1, 2, 3]);
      rol = factory(list);
      changes = null;
      sub = rol.changes.listen((records) {
        changes = records.where((r) => r.changes(1)).toList();
      });
    });

    tearDown(sharedTearDown);

    observeTest('add does not change existing items', () {
      list.add(4);
      expect(list, [1, 2, 3, 4]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('[]= changes item', () {
      list[1] = 777;
      expect(list, [1, 777, 3]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_change(1, addedCount: 1, removedCount: 1)]);
    });

    observeTest('[]= on a different item does not fire change', () {
      list[2] = 9000;
      expect(list, [1, 2, 9000]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('set multiple times results in one change', () {
      list[1] = 777;
      list[1] = 42;
      expect(list, [1, 42, 3]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, addedCount: 1, removedCount: 1),
      ]);
    });

    observeTest('set length without truncating item means no change', () {
      list.length = 2;
      expect(list, [1, 2]);
      performMicrotaskCheckpoint();
      expectChanges(changes, []);
    });

    observeTest('truncate removes item', () {
      list.length = 1;
      expect(list, [1]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [_change(1, removedCount: 2)]);
    });

    observeTest('truncate and add new item', () {
      list.length = 1;
      list.add(42);
      expect(list, [1, 42]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, removedCount: 2, addedCount: 1)
      ]);
    });

    observeTest('truncate and add same item', () {
      list.length = 1;
      list.add(2);
      expect(list, [1, 2]);
      performMicrotaskCheckpoint();
      expectChanges(changes, [
        _change(1, removedCount: 2, addedCount: 1)
      ]);
    });
  });

  observeTest('toString', () {
    var list = toObservable([1, 2, 3]);
    var rol = factory(list);
    expect(rol.toString(), '[1, 2, 3]');
  });

  group('change records', () {

    List<ChangeRecord> records;
    ObservableList list;
    ReadOnlyObservableList rol;

    setUp(() {
      list = toObservable([1, 2, 3, 1, 3, 4]);
      rol = factory(list);
      records = null;
      sub = rol.changes.listen((r) { records = r; });
    });

    tearDown(sharedTearDown);

    observeTest('read operations', () {
      expect(rol.length, 6);
      expect(rol[0], 1);
      expect(rol.indexOf(4), 5);
      expect(rol.indexOf(1), 0);
      expect(rol.indexOf(1, 1), 3);
      expect(rol.lastIndexOf(1), 3);
      expect(rol.last, 4);
      var copy = new List<int>();
      rol.forEach((i) { copy.add(i); });
      expect(copy, orderedEquals([1, 2, 3, 1, 3, 4]));
      performMicrotaskCheckpoint();

      // no change from read-only operators
      expectChanges(records, null);
    });

    observeTest('add', () {
      list.add(5);
      list.add(6);
      expect(list, orderedEquals([1, 2, 3, 1, 3, 4, 5, 6]));

      performMicrotaskCheckpoint();
      expectChanges(records, [
{'fraction_non_alphanumeric': 0.158860538273331, 'fraction_numerical': 0.025340789933589652, 'mean_word_length': 2.870476834629692, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1880542', 'n_tokens_mistral': 3839, 'n_tokens_neox': 3559, 'n_words': 820}