I would like to enhance efficiency in our software department by providing a VS extension or add in to perform custom code coverage using VS 2013.
The special point in that enterprise is the coverage of special code snippet actually marked by a comment like //INDISPENSABLE_STUFF document comment that is defined as a task token.
I was thinking of introducing a new attribute RiskAttribute to qualify methods for instance but could not separate the corresponding code coverage result from the rest for reporting how much of the indispensable stuff has been covered.
/// <summary>
/// Risk Attribute
/// </summary>
public class RiskAttribute : Attribute
{
private readonly string _document;
private readonly string _comment;
/// <summary>
/// Constructor
/// </summary>
/// <param name="doc"></param>
/// <param name="comment"></param>
public RiskAttribute(string doc, string comment)
{
_document = doc;
_comment = comment;
}
/// <summary>
/// Document
/// </summary>
public string Document { get { return _document; } }
/// <summary>
/// Comment
/// </summary>
public string Comment { get { return _comment; } }
}
I turned to implement an add in but do not figure out in the 1. step how to launch the vs code coverage tool programmatically for a project using my add-in. The 2. step would be to customize the code coverage in order to parse the custom task token and return a result like xy% of defined task token INDISPENSABLE_STUFF is covered.
For development, I implemented a calculator class with unit test to exercise both variations:
The class
/// <summary>
/// Calculator
/// </summary>
public class Calculator
{
/// <summary>
/// Addition
/// INDISPENSABLE_STUFF (DOC #2150) Test
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static decimal Add(decimal a, decimal b) { return a + b; }
/// <summary>
/// Substraction
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
[RiskAttribute("DOC #2150", "Test")]
public static decimal Sub(decimal a, decimal b) { return a - b; }
}
The unit test
/// <summary>
/// Test class for Calculator
/// </summary>
[TestClass]
public class CalculatorTest
{
/// <summary>
/// Tests addition
/// </summary>
[TestMethod]
public void Test_Sub()
{
decimal a = 1;
decimal b = 2;
Assert.AreEqual((a - b), Calculator.Sub(a, b));
}
}
So now, for the question, I already have to add-in code for the integration but miss the main content to start the customized code coverage. Does anybody know :
how to adapt the code coverage to consider task token?
how to start the code coverage programmatically?
Sorry if these are "big" points for only "one" question.
Thanks
Related
When I'm writing functions for my project, and more specifically, their XML documentation comments, I find myself repeating the comments for a specific parameter often. This leads to misleading documentation sometimes (as copy pasting usually does...).
This is a simple example I thought of, which represents the real problem.
/// <summary>
/// The number that should be doubled
/// </summary>
private static float myNumber = 10f;
/// <summary>
/// Multiplies a number by 2
/// </summary>
/// <param name="number"><inheritdoc cref="myNumber"/></param>
/// <returns>The number multiplied by 2</returns>
private static float MultiplyByTwo(float number)
{
return number * 2f;
}
In this line /// <param name="number"><inheritdoc cref="myNumber"/></param>, I would like to have the text "The number that should be doubled", but it's not showing up. Maybe I don't understand the use of inheritdoc completely.
What I mean by showing up is this. Visual Studio should show the documentation of number in that box:
This is what it should look like (without copy pasting the text):
So, is there a way to reference a different variable in XML documentation comments?
In Visual Studio 16.8.4 I'm able to use <inheritdoc>'s path attribute to do this.
/// <summary>
/// The number that should be doubled
/// </summary>
private static float myNumber = 10f;
/// <summary>
/// Multiplies a number by 2
/// </summary>
/// <param name="number"><inheritdoc cref="myNumber" path="/summary"/></param>
/// <returns></returns>
private static float MultiplyByTwo(float number)
{
return number * 2f;
}
In the path attribute, / selects the 'root' node and then summary is the node to select within that node.
Result:
The path attribute uses XPath syntax, which you can find more about here.
You can use it to do some great stuff if you're careful; I regularly use it when implementing the Try[...] pattern.
For example:
/// <summary>
/// This throws!
/// </summary>
/// <param name="param1">This is a parameter.</param>
/// <param name="param2">This is another parameter!</param>
/// <exception cref="InvalidOperationException"/>
public string ExampleThatCanThrow(int param1, float param2)
{
throw new InvalidOperationException();
}
/// <summary>
/// This never throws!
/// </summary>
/// <inheritdoc cref="ExampleThatCanThrow(int, float)" path="/*[not(self::exception)]"/>
public bool TryExample(int param1, float param2, out string? result)
{
result = "No throwing here!";
return true;
}
Normally when using <inheritdoc> for the TryExample method in this way, it would show that it could throw InvalidOperationException. Using the path attribute, I've filtered it so only the nodes that don't match the name of exception will be inherited.
/: Matches the root node.
*: Matches any child node.
[ and ]: Matches any node that meets the conditions of the contained predicate.
not(): Matches any node that doesn't meet the conditions of the expression within the parentheses.
self::exception: Matches the current node if it has the name of exception.
This results in the below:
In addition, you can use this functionality to more easily show the exceptions that can be thrown by a method without typing them out explicitly:
/// <summary>
/// Validates a file in some way.
/// </summary>
/// <param name="filePath">A full path to the file to be validated.</param>
/// <inheritdoc cref="File.OpenRead(string)" path="/exception"/>
private static void ValidateFile(string filePath)
{
using FileStream file = File.OpenRead(filePath);
// Validation code...
}
This above use of <inheritdoc> will cause the tooltip on the method to show that it can throw all of the exceptions that the System.IO.File.OpenRead method can throw. Just be careful that you ensure necessary validation exceptions are actually thrown and accounted for.
I have a Powershell script that requires user interaction. I can call powershell.exe from C# using System.Diagnostics.Process and pass the scripts path as a parameter but I would like the script to be an embedded resource of the project. I tried creating a Runspace (see below) and running the script but because the script requires user interaction I receive an exception.
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "mynamespace.myscriptfile.ps1";
string result = "";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
result = reader.ReadToEnd();
Console.WriteLine(result);
}
//Create Powershell Runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
// Create pipeline and add commands
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(result);
// Execute Script
Collection<PSObject> results = new Collection<PSObject>();
try
{
results = pipeline.Invoke();
}
catch (Exception ex)
{
results.Add(new PSObject((object)ex.Message));
}
runspace.Close();
Console.ReadKey();
Is there a way to either pass the embedded resource to powershell.exe using System.Diagnostics.Process or is there a way to Invoke the script from C# where the user can interact?
UPDATE:
It seems to me that I may be able to use an implementation of the abstract class PSHost along with using the PSHostUserInterface property correctly, I may be able to create a Runspace that takes the PSHost implementation as a parameter to use the native Powershell console. I have been trying to test the idea but I'm not quite sure how to implement the abstract class.
Below is a sample of code that I obtained from Microsoft. I am confused with a couple of things. If it matters I will be creating the Runspace in a console application with a namespace called: WebRequirements in the Program class.
private Host01 program; (Would Host01 be Program?)
PSHostUserInterface (Is this where I would dictate that I want to use a native Powershell host and if so how would I do that?)
internal class MyHost : PSHost
{
///
/// A reference to the PSHost implementation.
///
private Host01 program;
/// <summary>
/// The culture information of the thread that created
/// this object.
/// </summary>
private CultureInfo originalCultureInfo =
System.Threading.Thread.CurrentThread.CurrentCulture;
/// <summary>
/// The UI culture information of the thread that created
/// this object.
/// </summary>
private CultureInfo originalUICultureInfo =
System.Threading.Thread.CurrentThread.CurrentUICulture;
/// <summary>
/// The identifier of this PSHost implementation.
/// </summary>
private Guid myId = Guid.NewGuid();
/// <summary>
/// Initializes a new instance of the MyHost class. Keep
/// a reference to the host application object so that it
/// can be informed of when to exit.
/// </summary>
/// <param name="program">
/// A reference to the host application object.
/// </param>
public MyHost(Host01 program)
{
this.program = program;
}
/// <summary>
/// Return the culture information to use. This implementation
/// returns a snapshot of the culture information of the thread
/// that created this object.
/// </summary>
public override System.Globalization.CultureInfo CurrentCulture
{
get { return this.originalCultureInfo; }
}
/// <summary>
/// Return the UI culture information to use. This implementation
/// returns a snapshot of the UI culture information of the thread
/// that created this object.
/// </summary>
public override System.Globalization.CultureInfo CurrentUICulture
{
get { return this.originalUICultureInfo; }
}
/// <summary>
/// This implementation always returns the GUID allocated at
/// instantiation time.
/// </summary>
public override Guid InstanceId
{
get { return this.myId; }
}
/// <summary>
/// Return a string that contains the name of the host implementation.
/// Keep in mind that this string may be used by script writers to
/// identify when your host is being used.
/// </summary>
public override string Name
{
get { return "MySampleConsoleHostImplementation"; }
}
/// <summary>
/// This sample does not implement a PSHostUserInterface component so
/// this property simply returns null.
/// </summary>
public override PSHostUserInterface UI
{
get { return null; }
}
/// <summary>
/// Return the version object for this application. Typically this
/// should match the version resource in the application.
/// </summary>
public override Version Version
{
get { return new Version(1, 0, 0, 0); }
}
/// <summary>
/// Not implemented by this example class. The call fails with
/// a NotImplementedException exception.
/// </summary>
public override void EnterNestedPrompt()
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// Not implemented by this example class. The call fails
/// with a NotImplementedException exception.
/// </summary>
public override void ExitNestedPrompt()
{
throw new NotImplementedException(
"The method or operation is not implemented.");
}
/// <summary>
/// This API is called before an external application process is
/// started. Typically it is used to save state so the parent can
/// restore state that has been modified by a child process (after
/// the child exits). In this example, this functionality is not
/// needed so the method returns nothing.
/// </summary>
public override void NotifyBeginApplication()
{
return;
}
/// <summary>
/// This API is called after an external application process finishes.
/// Typically it is used to restore state that a child process may
/// have altered. In this example, this functionality is not
/// needed so the method returns nothing.
/// </summary>
public override void NotifyEndApplication()
{
return;
}
/// <summary>
/// Indicate to the host application that exit has
/// been requested. Pass the exit code that the host
/// application should use when exiting the process.
/// </summary>
/// <param name="exitCode">The exit code to use.</param>
public override void SetShouldExit(int exitCode)
{
this.program.ShouldExit = true;
this.program.ExitCode = exitCode;
}
}
I have made a school project that my teacher will check later on.
I am trying to add some Documentation Comments in Visual Studio Code with the help of a plugin that allows me to write /// which makes the xml code automatically.
I have read from the Microsoft Docs about XML Documentation that you can make a seperate XML file rather than clutter the code with comments but i have been having a hard time getting it to work.
Here is an example:
///<include file='docs.xml' path='docs/members[#name="program"]/Select/*'/>
public static bool Select (ConsoleKey input) {
ConsoleKeyInfo key = Console.ReadKey (true);
if (key.Key == input) {
return true;
}
return false;
}
This is what the doc.xml file has about this method:
<doc>
<members name="program">
<Select>
<summary>
Summarizes a way to detect <paramref name ="input"/>.
</summary>
<returns>
true when <paramref name = "input"/> is detected.
</returns>
<param name="input"> Checks what key it should detect.</param>
<example>
<code>
string outputToConsole = "Hello World!";
void Main () {
if (Selecting.Select (ConsoleKey.Spacebar)) {
Console.WriteLine (outputToConsole);
//Prints "Hello World" when key "Spacebar" is pressed!
}
}
</code>
</example>
</Select>
It currently does not work (It does not show a description on the method at all) and i have been racking my head over this.
The documentation says (emphasis mine):
This is an alternative to placing documentation comments directly in your source code file. By putting the documentation in a separate file, you can apply source control to the documentation separately from the source code. One person can have the source code file checked out and someone else can have the documentation file checked out.
I do understand the motivation behind this, but if you decide to use a separate file you can no longer use Visual Studio autocomplete/intellisense to generate the XML elements for you, and you'll need to learn the schema/syntax of the XML documentation file.
Also, as the assembly gets bigger, so will the XML file. In the real world this file could have 1000s of lines of code. From a maintenance and source control perspective, I'd rather have the documentation in the c# source files. I honestly think it's not worth the trouble.
Anyway, if you still want to use the external files there are a few tricks you can use.
Consider a class library named FileDemo. Righ-click the project > Properties > Build and then tick the checkbox XML Documentation File:
This will generate the XML documentation file on build:
And now the funny part. As I mentioned before, the XML documentation file has a particular syntax you'll need to learn. The best way to do it is to add some XML documentation to existing classes, methods etc and check the generated XML. For example, considering the following namespaces and classes:
namespace FileDemo
namespace FileDemo
{
/// <summary>
/// This is a class
/// </summary>
public class Class1
{
/// <summary>
/// Does nothing
/// </summary>
/// <param name="text">Just some text</param>
public void DoNothing(string text)
{
}
}
/// <summary>
/// This is another class
/// </summary>
public class Class2
{
/// <summary>
/// Bla bla
/// </summary>
/// <param name="text">Just some text</param>
public void DoSomething(string text)
{
}
}
}
namespace FileDemo.AnotherNamespace
namespace FileDemo.AnotherNamespace
{
/// <summary>
/// Yet another class
/// </summary>
public class Class3
{
/// <summary>
/// Gets or sets something
/// </summary>
public string Foo { get; set; }
/// <summary>
/// Creates a new instance of <see cref="Class3"/>
/// </summary>
public Class3()
{
}
/// <summary>
/// This method is supposed to calculate something
/// </summary>
/// <param name="firstValue">First value</param>
/// <param name="secondValue">Second value</param>
/// <returns>The result of the calculation</returns>
public int Calculate(int firstValue, int secondValue)
{
return 1;
}
}
}
After building the project, the generated documentation file is the following:
<?xml version="1.0"?>
<doc>
<assembly>
<name>FileDemo</name>
</assembly>
<members>
<member name="T:FileDemo.AnotherNamespace.Class3">
<summary>
Yet another class
</summary>
</member>
<member name="P:FileDemo.AnotherNamespace.Class3.Foo">
<summary>
Gets or sets something
</summary>
</member>
<member name="M:FileDemo.AnotherNamespace.Class3.#ctor">
<summary>
Creates a new instance of <see cref="T:FileDemo.AnotherNamespace.Class3"/>
</summary>
</member>
<member name="M:FileDemo.AnotherNamespace.Class3.Calculate(System.Int32,System.Int32)">
<summary>
This method is supposed to calculate something
</summary>
<param name="firstValue">First value</param>
<param name="secondValue">Second value</param>
<returns>The result of the calculation</returns>
</member>
<member name="T:FileDemo.Class1">
<summary>
This is a class
</summary>
</member>
<member name="M:FileDemo.Class1.DoNothing(System.String)">
<summary>
Does nothing
</summary>
<param name="text">Just some text</param>
</member>
<member name="T:FileDemo.Class2">
<summary>
This is another class
</summary>
</member>
<member name="M:FileDemo.Class2.DoSomething(System.String)">
<summary>
Bla bla
</summary>
<param name="text">Just some text</param>
</member>
</members>
</doc>
As you can see, there is a particular schema/syntax that you need to learn for each element you're trying to document (classes, methods, properties, constructors, parameters, return types, etc).
I am developing an app in Xamarin for Iphone, android version of similar app is ready for Google play. I am using jabber-net library in my app for chat functionality. But having some issue on device(Iphone 5 - IOS 7.0.3). this issue doesn't occur in emulator following is the method code.
public class QnameType
{
/// <summary>
/// Element name
/// </summary>
protected internal string Name;
/// <summary>
/// Element namespace URI
/// </summary>
protected internal string NS;
/// <summary>
/// Type to create for NS/Name pair
/// </summary>
protected internal Type ElementType;
/// <summary>
/// Create a QnameType
/// </summary>
/// <param name="name"></param>
/// <param name="ns"></param>
/// <param name="typ"></param>
public QnameType(string name, string ns, Type typ)
{
this.Name = name;
this.NS = ns;
this.ElementType = typ;
}
/// <summary>
/// Is this the same qname by element name and namespace?
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object obj)
{
if (obj == (object)this)
return true;
QnameType other = obj as QnameType;
if (other == null)
return false;
return (other.Name == Name) && (other.NS == NS);
}
/// <summary>
/// Get a hash over the name and namespace.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return ToString().GetHashCode();
}
/// <summary>
/// Namespace|Name
/// </summary>
/// <returns></returns>
public override string ToString()
{
return NS + "|" + Name;
}
}
public interface IPacketTypes
{
/// <summary>
/// QName to type mappings.
/// </summary>
QnameType[] Types { get; }
}
public class ElementFactory
{
private Hashtable m_types = new Hashtable();
private static readonly Type[] s_constructorTypes =
new Type[] { typeof(string),
typeof(XmlQualifiedName),
typeof(XmlDocument) };
public void AddType(IPacketTypes list)
{
foreach (QnameType qn in list.Types)
{
this.AddType(qn.Name, qn.NS, qn.ElementType);
}
}
public void AddType(string localName, string ns, Type t)
{
Debug.Assert(t.IsSubclassOf(typeof(Element)));
ConstructorInfo ci = t.GetConstructor(s_constructorTypes);
Debug.Assert(ci != null);
AddType(new XmlQualifiedName(localName, ns), ci);
}
public Element GetElement(string prefix, XmlQualifiedName qname, XmlDocument doc)
{
ConstructorInfo ci = (ConstructorInfo) m_types[qname];
if (ci == null)
{
return new Element(prefix, qname, doc);
}
return (Element) ci.Invoke
(new object[] {prefix, qname, doc});
}
/// <summary>
/// Get a constructor for the appropriate type for the given qname.
/// </summary>
public ConstructorInfo this[XmlQualifiedName qname]
{
get { return (ConstructorInfo) m_types[qname]; }
}
}
t.GetConstructor() returns null on Iphone but works fine on simulator.
Edit: added more detail,
Any help will be highly appreciated.
Thanks
That's likely normal, depending on t itself - what type does it represent ?
By default the managed linker is disabled (Don't link) on the simulator builds. That means every type will be part of the application.
However the default for device builds is Link SDK. This means unused types (found using static analysis) are removed from the application. This allow reducing the size of the application (by not compiling/shipping the whole .NET BCL inside each app).
Static analysis cannot find detect dynamic use of code, e.g. reflection. If your application depends on reflection is needs to preserve the code: using the [Preserve] attribute, an XML file or adding some extra code that will give an hint to the linker to keep the required members.
See documentation for further details.
In addition to the answer from poupou:
If you're stumbling over this question because you have a similar issue with Unity3D then take a look onto this page: https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html
In general that page shows you how to make sure everything is included in IL2CPP builds:
Use [Preserve] keyword on you classes
or
Add a link.xml file into your Assets root
I use Rhino Mocks version 3.6 and the answer that I found here doesn't work in my case :
[TestMethod()]
public void Test()
{
IConnected connectable = MockRepository.GenerateStub<IConnected>();
connectable.Stub(c => c.Connect()).Do(new Action(() =>
{
bool test = false;
if (!test)
test = true;
})).Repeat.Any();
connectable.Stub(c => c.Connect()).Do(new Action(() => { })).Repeat.Any();
}
And I've got an InvalidOperationException: The result for IConnected.Connect(); has already been setup.
I tests it with stub and mock and I've got same results.
I made the same test with property and it doesn't work too.
[TestMethod()]
public void Test()
{
IConnected connectable = MockRepository.GenerateStub<IConnected>();
connectable.Stub(c => c.IsConnected).Return(true).Repeat.Any();
connectable.Stub(c => c.IsConnected).Return(false).Repeat.Any();
}
Is it a bad version of Rhino Mocks or is there a regression ?
The only method that work is to clear all expectation but I must reset to same value all aver expectations :
// clear expectations, an enum defines which
_stubRepository.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_stubRepository.Replay();
My IConnected interface :
/// <summary>
/// Represents connected component management interface.
/// </summary>
public interface IConnected
{
/// <summary>
/// Gets the connection status.
/// </summary>
ConnectionState ConnectionStatus { get; }
/// <summary>
/// Gets a value indicating whether this instance is connected.
/// </summary>
/// <value>
/// <c>true</c> if this instance is connected; otherwise, <c>false</c>.
/// </value>
bool IsConnected { get; }
/// <summary>
/// Occurs when [connection state changed].
/// </summary>
event EventHandler<ConnectionStateChangeEventArgs> ConnectionStateChanged;
/// <summary>
/// Connects this instance.
/// </summary>
void Connect();
/// <summary>
/// Disconnects this instance.
/// </summary>
void Disconnect();
/// <summary>
/// Occurs when [reconnect].
/// </summary>
event EventHandler<ConnectionRetryEventArgs> RetryConnection;
}
You can implement some behavior for stubs via Do() handler.
Here is a solution for your case:
var isConnected = false;
var stub = MockRepository.GenerateStub<IConnected>();
stub
.Stub(c => c.IsConnected)
.Do((Func<bool>)(() => isConnected))
.Return(false);
stub
.Stub(c => c.Connect())
.Do((Action)(() => { isConnected = true; }));
now just test:
Console.WriteLine(stub.IsConnected);
stub.Connect();
Console.WriteLine(stub.IsConnected);
But it would be much better if you redesign your tests to avoid cases when you need such a complex stub (of cource if it is possible). Probably split test into a few more tests might be suitable.