0

The test should check when a train is assigned to a line he losts its previous line. The class Train should implement this test in the function public void AssignTo(ILine l) by following those steps (they need to be respected):

  1. Current assignment = l1
  2. l1.Trains contains THIS
  3. need to remove THIS from l1.trains
  4. need to change current line and add train to new line

    internal class Train : ITrain
    {
        internal Train(string name, Company company)
        {
            this.Name = name;
            this.Company = company;
        }

        public string Name
        {
            get;
        }

        public ICompany Company
        {
            get;
        }

        public ILine Assignment
        {
            get;
            private set;
        }

        public void AssignTo(ILine l)
        {
            //Current assignment = l1
            var l1 = Assignment;

            //l1,Trains contains THIS
            this.AssignTo(l1.train)

            //need to remove THIS from l1.trains
            ((List<Train>)l1.Trains).Remove(this);

            //need to change current line and add train to new line
            ((List<Train>)l.Trains).Add(this);
            Assignment = l;
           
        }
    }
}

[Test]
        public void T2_when_a_train_is_assigned_to_a_line_he_losts_its_previous_line()
        {
            ICity s = CityFactory.CreateCity("Paris");
            ICompany c = s.AddCompany("SNCF");
            ILine l1 = s.AddLine("RER A");
            ILine l2 = s.AddLine("RER B");
            ITrain t1 = c.AddTrain("RER1");

            t1.AssignTo(l1);
            t1.Assignment.Should().BeSameAs(l1);

            t1.AssignTo(l2);
            t1.Assignment.Should().BeSameAs(l2);
            l1.Trains.Count().Should().Be(0);
            l2.Trains.Single().Should().BeSameAs(t1);
        }
Badro Niaimi
  • 959
  • 1
  • 14
  • 28

1 Answers1

0

The problem with your current interfaces are that ILine.Trains is an IEnumerable, and you can't really remove something from an IEnumerable. In your code, you have assumed that it will always be a List, which you shouldn't really do, but if you can't change the type of ILine.Trains then I guess that's the only way.

Anyway, the reason why your code doesn't work is that you are recursively calling AssignTo for some reason. You should remove this call:

public void AssignTo(ILine l)
{
    var l1 = Assignment;

    // remove this line
    // this.AssignTo(l1.train)

    ((List<Train>)l1.Trains).Remove(this);

    ((List<Train>)l.Trains).Add(this);
    Assignment = l;

}

Although this isn't required, (it seems to be one of your requirements), you need to check whether l1.Trains contains this first:

var l1 = Assignment;

if (l1.Trains.Contains(this)) {
    ((List<Train>)l1.Trains).Remove(this);
}

((List<Train>)l.Trains).Add(this);
Assignment = l;
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • this part here ((List)l1.Trains).Remove(this); needs to have a previous step that l1.Trains contains THIS and after that can be removed. –  Dec 20 '19 at 10:05
  • @barbra Oh you mean you need to check that `l1.Trains` contains `this` before removing `this` from it? – Sweeper Dec 20 '19 at 10:06
  • @barbra See the edit. You don't actually need that, because `Remove` won't do anything anyway when `this` is not in the list. – Sweeper Dec 20 '19 at 10:11
  • There is more to it as there is previous tests that needs to be respected. Object reference not set to an instance of an object which is caused by the line "if (l1.Trains.Contains(this)) { ". It does pass the test part on this line " t1.AssignTo(l1);" –  Dec 20 '19 at 10:19
  • @barbra that error doesn’t seem to be related to my code, see https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it – Sweeper Dec 20 '19 at 10:33
  • Thanks for directing me to my answer. –  Dec 20 '19 at 10:47