всеки. Имам объркващо взаимодействие между договори, pex и quickgraph и ще бъда много благодарен за съвет от по-осведомените. Сведох го до възпроизвеждащ случай, при който коментирането на един договор кара фалшивия отрицателен резултат да изчезне, но не успях да го диагностицирам с програмата за отстраняване на грешки в разрешеното време, тъй като кодът на темата (quickgraph) има странични ефекти в свойството- getters, което означава, че дебъгерът изпълнява страничните ефекти, когато показва стойностите на свойствата, нарушавайки действителния ред на изпълнение.
Първо малко предистория, след това спецификата, след това указател към проект, който да изтеглите и изпробвате, ако сте толкова склонни да се задълбочите!
Инсталирах Pex & Moles
http://research.microsoft.com/en-us/projects/pex/downloads.aspx
и CodeContracts за .NET 4.0
http://research.microsoft.com/en-us/projects/contracts/
Изтеглих чрез nuget най-новата версия на QuickGraph, която е създадена изцяло за .NET 3.5. Намалих го до минимума, от който се нуждаех, влязох в Project Properties за всички, актуализирах ги всички до .NET 4.0 от .NET 3.5 клиентски профил, поправих една промяна, нарушаваща източника (която беше тривиална и много, много малко вероятно да има връзка с моя проблем). След това отидох в раздела Кодови договори на всяка страница на проекта и активирах всички статични и динамични опции.
http://quickgraph.codeplex.com/releases/view/55262
Проектът има 192 модулни теста, много от тях генерирани от Pex (много хубаво!). За да изпълните тестовете, вземете zip файла на моя проект от
http://dl.dropbox.com/u/1997638/QuickGraph.zip
Уверете се, че имате Pex & Moles и Договори от връзките по-горе. Отворете решението, изградете отново всичко, след това на ниво решение „Изпълнете всички тестове в решение“ (control-R, A). Всичко ще мине. След това отидете на ред 49 от IImplicitUndirectedGraphContracts.cs и разкоментирайте договора под големия коментар (вмъкнат от мен). Един тест, Prim12240WithDelegate, ще се провали.
Този тест упражнява графичен конструктор, който изгражда ръбове в движение чрез извикване на предоставен от потребителя делегат в инструментите за получаване на свойства за Edges и EdgeCount. сладък Но нещо се обърка с договора на ред 49 на IImplicitUndirecteGraphContracts.cs.
Това е фалшиво отрицание, защото ако коментирам този договор, тестът преминава. Опитът да се следва това в програмата за отстраняване на грешки има нещо общо с времето на създаване на ръбовете в инструментите за получаване на свойства. Не успях обаче да разгадая това, тъй като дебъгерът извиква тези гетери, субектният код ги извиква, кодът на договорите ги извиква, може би статично, може би динамично, просто се изгубих, опитвайки се да го следвам, и си помислих, че Бих повдигнал въпроса на тези, които разбират подробностите за изпълнението на договора по-добре от мен.
Ето договора в нарушение; коментирането му прави единичния тест успешен:
[Pure]
IEnumerable<TEdge> IImplicitUndirectedGraph<TVertex, TEdge>.AdjacentEdges(TVertex v)
{
IImplicitUndirectedGraph<TVertex, TEdge> ithis = this;
Contract.Requires(v != null);
Contract.Requires(ithis.ContainsVertex(v));
Contract.Ensures(Contract.Result<IEnumerable<TEdge>>() != null);
~~~~~~> Contract.Ensures(
Enumerable.All(
Contract.Result<IEnumerable<TEdge>>(),
edge =>
edge != null &&
ithis.ContainsEdge(edge.Source, edge.Target) &&
(edge.Source.Equals(v) || edge.Target.Equals(v))
)
);
return default(IEnumerable<TEdge>);
}