Project Fare is an effort to bring a DFA/NFA (finite-state automata) implementation from Java to .NET. There are quite a few implementations available in other languages today. This project aims to fill the gap in .NET.
Fare is a .NET port of the well established Java library dk.brics.automaton with API as close as possible to the corresponding dk.brics.automaton classes. It also includes a port of Xeger which is a Java library for generating random text from regular expressions. The latter is possible in .NET using the Rex tool.
There are currently integration tests utilizing xUnit.net data theories using the [ClassData] attribute. This way, the same test cases can be used across the ported code, the Java code and even compared to the output of Rex.
The source code is here.
Recently I needed to use a DFA/NFA (finite-state automata) implementation from a Java package in .NET. I could not find a port of this particular package and IKVMC was not an option since I preferred to depend only on the standard library (BCL). So, I decided to port the code myself.
In my case, the Java package didn't have unit tests (at least not publicly available on the website). How could I know that the results of the ported code are the same with the original code?
The solution I came up with was the following:
- Write integration tests, one for the ported code and one for the Java code.
- Both tests should have the same, deterministic, input.
- Keep porting enough code from the Java source in order to make the test pass.
- Verify that results are the same with the test in Java.
- Recursively repeat this process until all tests pass and yield correct results.
During the process of porting I came across a few differences between Java and .NET and particularly:
- Multi-dimensional arrays syntax is slightly different.
- Substring method parameteres have different meaning.
- In C# we pass StartIndex, Length.
- In Java we pass StartIndex, EndIndex.
- In Java, the list and set implementations override equals, etc. The equivalent doesn't happen in .NET.
- Java LinkedList Add method appends the specified element to the end of the list. The equivalent in .NET is the AddLast method.
- Java LinkedList Remove(int) method removes the element at the specified position in the list and returns the element that was removed from the list. The equivalent in .NET exists only with the use of an extension method.
- What are major differences between C# and Java?
- Why should I bother about serialVersionUID?
- C# equivalent to Java's charAt()?
- Working with multidimensional arrays in C# similar to Java
- .NET port with Java's Map, Set, HashMap
- What is the difference between instanceof and Class.isAssignableFrom
- Why you should not implement ICloneable in C#?
Java SE 6 Documentation
There are times where we need to use a library written in a different platform than the one we are currently on. Most of the times a port already exists and we can choose to go with that. Before using a port there are some good considerations:
- The size of the original codebase.
- The kind of project (is it a logger, an ORM, etc).
- The current version of the original compared with the ported one. It depends on the activity of the original but if the ported is left 1+ year behind this is not a good sign.
- The quality of the ported codebase, framework usage, coding conventions. Does it use recommeded guidelines for the target framework?
- The activity of the ported project. If it's low that's a sign that future versions might now show up. However, consider contributing.
Besides ported code, there are cases where we can use a tool that allows us to use the original library from a different platform. For example, when working in .NET we can use Java class libraries through IKVM.NET which has a bytecode compiler called IKVMC.
Continuing the support of DataAnnotations as described here, there is now added support for the StringLengthAttribute class. Starting with version 2.4.0, when this attribute is applied on a data field it can specify the maximum length of characters that are allowed.
Let's take as an example the following type:
Prior to version 2.4.0 if we request an anonymous instance from AutoFixture, by default we would get back an instance of the above type with it's Property containing a value similar to the one below.
However, after version 2.4.0 AutoFixture can handle requests with string length constraints through the StringLengthAttribute class by issuing a new request for a constrained string.
Support for types from the System.ComponentModel.DataAnnotations namespace is one of the most voted features for AutoFixture. Starting with version 2.3.1 AutoFixture supports the RangeAttribute class. When this attribute is applied on a data field it can specify the numeric range constraints for it's value.
Let's take as an example the following type:
Prior to version 2.3.1 if we request an anonymous instance from AutoFixture (or better, a specimen from AutoFixture's kernel) we would get back an instance of the above type with it's Property containing a value probably out of the specified numeric range.
However, after version 2.3.1 AutoFixture can handle requests with numeric range constraints through the RangeAttribute class by issuing a new request for a value inside the specified range.
subscribe via RSS