Yet Another [à compléter]

Using Parallax for Fun and Profit

The idea of a parallax is to give the illusion of depth thanks to targets seemingly moving at a different pace. You have probably already noticed the effect in real life when riding on a straight line e.g. staring at individual scenery items from a train window.

The idea is basically that the closer an object is to you, the faster it seems to move to your eyes. The extreme being the background (like distant mountains) which doesn’t seem to move at all.

This effect, called Parallax, is used proficiently on iOS and Android launchers when scrolling through your apps to make it look like your wallpaper is further away from your icons as they move.

We can re-create parallax pretty easily on Android using the ViewPager class of the support package as a foundation for handling the touch events and displaying our content.

Our goal here is to create an awesome on-boarding screen to present your app. Each “slides” will have its own background and a couple of visual elements (text, device frame, other widgets) that will be arranged in different virtual layer (i.e. some will move faster than others).

Check out an example below of such a screen and the slightly different position offsets applied to each elements:

The core idea is to setup a ViewPager taking up all the screen space (you can even use the new KitKat translucent window chrome like in the screencast with the Holo.*.NoActionBar.Translucent style) and then create a generic FrameLayout-based layout (remember how FrameLayout is your friend?) for the page. You don’t need to add an ImageView for the background since we will directly use the background property of the FrameLayout.

It’s also not necessary to have pre-scaled those background images since setting them as the background drawable of the main FrameLayout will automatically make them fit but it’s better if their dimensions are close to the form factor of the device (16/9 portrait usually) so that they don’t appear squashed (if you want to get fancy you might want to dynamically blur those too).

Afterwards, just sprinkle the layout with TextView, ImageView or whatever other view you may want to showcase your app using the layout_gravity and layout_margin attributes to align them on the screen. Here is the example, very dumb, layout I’m using for the demo:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/backgroundFrame"
    android:background="@drawable/onboarding_bg_1">
    <TextView
        android:text="A Big Title About Something"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/bigTitle"
        android:layout_gravity="center_horizontal|top"
        android:layout_marginTop="64dp"
        android:textColor="#ffffffff"
        android:textSize="24sp"
        android:shadowColor="#ff000000"
        android:shadowDx="0"
        android:shadowDy="1"
        android:shadowRadius="0.5" />
    <TextView
        android:text="A Subtitle About the Thing"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/bigSubtitle"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="64dp"
        android:textColor="#ffffffff"
        android:textSize="20sp"
        android:shadowColor="#ff000000"
        android:shadowDx="0"
        android:shadowDy="1"
        android:shadowRadius="0.5" />
    <ImageView
        android:src="@android:drawable/ic_menu_gallery"
        android:layout_width="200dp"
        android:layout_height="300dp"
        android:id="@+id/centerImage"
        android:layout_gravity="center" />
</FrameLayout>

Once you have wired your ViewPager with an Adapter feeding the right content, we are going to create a PageTransformer which is where the parallax magic is gonna be created. Implementing this interface requires only one method which is called for every scroll offset of a given page View together with a value indicating its position relative to the center of the screen.

That relative position is very handy because it’s clamped between -1 (left of the screen) and +1 (right of the screen) with the zero value in the middle. That means we can derive a very simple parallax equation based on its value:

public class OnBoardingPageTransformer : Java.Lang.Object, ViewPager.IPageTransformer
{
	float parallaxCoefficient;
	float distanceCoefficient;
	IEnumerable<int>[] viewLayers;

	public OnBoardingPageTransformer (float parallaxCoefficient,
	                                  float distanceCoefficient,
	                                  params IEnumerable<int>[] viewLayers)
	{
		this.parallaxCoefficient = parallaxCoefficient;
		this.distanceCoefficient = distanceCoefficient;
		this.viewLayers = viewLayers;
	}

	public void TransformPage (View page, float position)
	{
		float coefficient = page.Width * parallaxCoefficient;
		foreach (var layer in viewLayers) {
			foreach (var viewID in layer) {
				var v = page.FindViewById (viewID);
				if (v != null)
					v.TranslationX = coefficient * position;
			}
			coefficient *= distanceCoefficient;
		}
	}
}

The trick is then to have a way to define layers and then let the user supply a couple of arguments to parametrize the effect. In the above class, we achieve this by letting the user gives a list of view IDs for each layer they want to create. You can then set the instance on your ViewPager by calling the SetPageTransformer method.

As a final piece of information, know that this technique only work on Android 3.0+ because ViewPager assumes you are using animatable properties.

Android Tip: ViewPager With Protruding Children

ViewPager is a widget part of the Support package that lets you display an horizontal list of “page”. In a nutshell, it’s to HorizontalScrollView what a ListView is to a vertical ScrollView.

By default pages are laid out to span the entire surface of the pager. In our case what we want to do is something akin to how the search results in the Apple’s AppStore iPhone app are displayed, a card-like style with adjacent items slightly taking over the surface edges:

Getting this to work with the default ViewPager class is a bit tricky. We have basically to change 3 things:

  • The global padding of the pager
  • The spacing between each page
  • The width of a single page

The first one might seem straightforward, you would just go and add both a android:paddingLeft and android:paddingRight onto the pager XML declaration. The problem is that by doing so, the clip rectangle is also moved by that same padding so it looks like the pages are cut in the middle of nowhere.

Fortunately, every ViewGroup subclass accept the android:clipToPadding attribute (doc) which allows to alter exactly that. By setting this one to false, the clip rect will remain equal to the container bounds but padding will still be taken into account during the layout phase.

The spacing between pages is a property settable on the pager itself, PageMargin (doc). This value should be about half the size of the left padding value.

Finally, to change the width of the pages, you override the GetPageWidth method of your PagerAdapter subclass (doc)). The right value you use depends on the sizing you put beforehand so slightly tune it until you find the desired effect.

Applying those 3 techniques we arrive at the following result:

For reference sake, here are the XML and code used for that output:

<android.support.v4.view.ViewPager
  	android:id="@+id/pager"
  	android:gravity="center"
  	android:layout_width="match_parent"
  	android:layout_height="0px"
  	android:paddingLeft="24dp"
  	android:paddingRight="12dp"
  	android:layout_weight="1" />
var pager = view.FindViewById<ViewPager> (Resource.Id.pager);
pager.SetClipToPadding (false);
pager.PageMargin = 12.ToPixels ();
pager.Adapter = new MyPageAdapter (ChildFragmentManager);

class MyPageAdapter : FragmentStatePagerAdapter
{
	public override float GetPageWidth (int position)
	{
		return 0.93f;
	}
	
	// ...
}

FrameLayout, Your Best UI Friend

You have probably already used FrameLayout (doc) for what it’s named, adding a decoration around other content element. It can actually be much more than that and is probably one of the most versatile container of all.

The secret of FrameLayout is how it layouts its children. Although normally designed to contain one item, it will happily stack up other element on top of each other. Thus FrameLayout is essentially a way to manipulate the Z-order of views on the screen.

This is super useful for a couple of UI tricks from HUD-like elements to sliding panels to more complex animated transitions. In this post we will see an example for each of those.

Overlay Elements

As I mentioned, FrameLayout will automatically stacks its children on top of each other. This makes it really easy to implement overlay or HUD element in your interface.

The idea is to wrap the part of the UI into an outer FrameLayout instance. Generally this will be the root element of your layout. You can then add below the main layout definition the other elements you want to overlay.

These elements will generally have a fixed size or be set as wrap_content. You can then place them at the right position on screen using the layout_gravity and layout_margin XML attributes.

In the following screenshot, my main content is a Google Map view. I have then added two overlays above it, one that replicate a toast message (center-bottom corner) and a TextView displaying the last time the data was loaded (upper-right corner).

This is simply achieved with the following layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content -->
    <com.google.android.gms.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- "Loaded" flash bar layout -->
    <FrameLayout
        android:id="@+id/FlashBarLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="72dp">
        <!-- flash bar content -->
    </FrameLayout>
    <!-- Last loaded time layout -->
    <TextView
        android:id="@+id/UpdateTimeText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|right"
        android:layout_marginTop="4dp"
        android:layout_marginRight="4dp" />
</FrameLayout>

Being just normal views, you can manipulate the overlays as usual. For instance you will probably want to implement some sort of animations for transition between visibility states if the overlay is transient.

Sliding Panels

Sliding panels (aka drawers, aka fly-out menus) are the rage these days. They mainly consist of a panel that is placed, depending on the desired spatial effect, above or below another piece of content. Again this falls back to placing elements using a FrameLayout object.

The trick then is to use the translationX and translationY properties of the panel View to move the element back and forth.

Alternatively, View also exposes the OffsetTopAndBottom and OffsetLeftAndRight methods (working on display list directly) but those are not as easy to animate. Indeed, with the translation properties you can directly use ObjectAnimator or ViewPropertyAnimator.

The panel is initially “hidden” by setting its translationY property to its height (i.e. top side forced to the bottom of the screen). We create the initial appearing effect with the following code piece inside the panel class:

// As its name imply, this interpolator will let the view go slightly overboard
// and then spring it back to its place
var intp = new Android.Views.Animations.OvershootInterpolator ();
var d = Context.Resources.GetInteger (Android.Resource.Integer.ConfigMediumAnimTime);
// Only the header part of the view should be visible, we thus just make
// the bottom of the view translated off-screen
var tY = Height - FindViewById (Resource.Id.PaneHeaderView).Height;

this.Animate ().TranslationY (tY).SetDuration (d).SetInterpolator (intp).Start ();

A common idiom of those panel is also to draw a shadow on the edge where they meet the content. This can be implemented very efficiently by overriding the DispatchDraw method of the sliding panel View and drawing a black linear GradientDrawable at the right place (use the Translate method on Canvas for the right positioning).

protected override void DispatchDraw (Android.Graphics.Canvas canvas)
{
    base.DispatchDraw (canvas);
    if (shadowDrawable == null)
        shadowDrawable = new GradientDrawable (GradientDrawable.Orientation.BottomTop,
                                               new[] { Color.Argb (0x60, 0, 0, 0), Color.Argb (0, 0, 0, 0) });
    // The reserved area for the shadow is set with top padding on the view.
    shadowDrawable.SetBounds (0, 0, Width, PaddingTop);
    shadowDrawable.Draw (canvas);
}

Transitions

With the move to a Fragment world, everything becomes just another View to manage and thereby removing the need for Activity.

When you think about the different “screen” of you application as individual fragments it becomes very easy to manipulate them in fun ways. Notably, being just managed View objects, you can apply any of the animations techniques you are already familiar with to implement very nifty transition effects.

At the core of such system, you will find again the same idea of a central, expanded FrameLayout surface where your Fragment are added.

The idea is to pile the Fragment views on top of each other like a deck of card. The current screen is thus the first card of the pile and application transitions are then simply how you want the middle cards to be put on top.

I’m using this analogy of the card deck because the method we are going to use here is View.BringToFront. This method will move the view at the last position inside its parent array. The end result of that operation of course depends on the type of container but in the case of FrameLayout it will make the View be drawn on top.

Note that this method doesn’t force a relayout which is fine for FrameLayout since children individual bounds aren’t dependent on each other but in the case of e.g. LinearLayout you will have to call RequestLayout for the modification to happen.

We will assume the layout of our main Activity is a single full-size FrameLayout container. Our application is composed of two screens represented as two fragments.

Initially, we create and attach directly those fragments to our content frame, hiding the second one to get into an initial state:

FirstFragment fragment1;
SecondFragment fragment2;

Fragment currentFragment;

protected override void OnCreate (Bundle bundle)
{
	SetContentView (/* ... */);
	
	fragment1 = new FirstFragment (this);
	fragment2 = new SecondFragment (this);
	
	SupportFragmentManager.BeginTransation ()
		.Add (Resource.Id.content_frame, fragment2, SecondFragment.Name)
		.Hide (fragment2)
		.Add (Resource.Id.content_frame, fragment1, FirstFragment.Name)
		.Commit ();
	currentFragment = fragment1;
}

When we want to change the Fragment that is shown, we will make sure that both views are on top of the drawing pile with the current one being on top of the other using BringToFront. We then swap the two fragments in a FragmentTransaction:

void SwitchTo (Fragment fragment, string name)
{
	if (fragment.IsVisible)
		return;
	var t = SupportFragmentManager.BeginTransaction ();
	t.SetCustomAnimations (Resource.Animator.frag_slide_in,
	                       Resource.Animator.frag_slide_out);

	// Make sure the next view is below the current one
	fragment.View.BringToFront ();
	// And bring the current one to the very top
	currentFragment.View.BringToFront ();

	// Hide the current fragment
	t.Hide (currentFragment);
	t.Show (existingFragment);
	currentFragment = existingFragment;

	// You probably want to add the transaction to the backstack
	// so that user can use the back button
	t.AddToBackStack (null);
	t.Commit ();
}

To add a bit of woosh, we are using customs animations to mark the transition between the two fragments to get this result:

These animations need to be defined in an XML resource using either property animator (aka from Android.Animations) if you are using framework Fragment or using view animations (aka from Android.View.Animations) if you are using Fragment from the support package.

To register custom animations, we call the SetCustomAnimations method on FragmentTransaction like so:

t.SetCustomAnimations (Resource.Animator.frag_slide_in,
                       Resource.Animator.frag_slide_out);

The first animation will be run on any fragment added/attached/shown while the second animation will be played on fragments hidden/detached/removed. Both are ran at the same time but you can use the animation startOffset attribute to delay one or the other.

For instance in my example, my frag_slide_out animation is defined like so:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:interpolator/accelerate_cubic">
   <translate
      android:fromXDelta="0"
      android:toXDelta="100%"
      android:duration="300" />
   <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.3"
        android:duration="300" />
</set>

Conclusion

Everything I have presented here is part of a big refresh to Moyeu. You can view the full source code on the GitHub repository at garuma/Moyeu.

XamSvg, Managed SVG Support for Android

As part of the new release of Moyeu, I’m also finally publishing a library that I have been using for some time.

This library is called XamSvg and in a nutshell it’s a managed (partial) implementation of an SVG parser/renderer for, currently only, Xamarin.Android.

The idea stems from the fact that Android has by default no serious way to do scalable graphics in a world with an exploding amount of device densities.

SVG appeared as a good fit because it’s easy to parse (XML), text-based (compress well) and fit well with the Android graphics API. It’s also incidentally the format used by the lovely Inkscape which makes my work even easier.

Before anyone gets their hopes high and starts throwing fancy SVG tigers at the library, know that this is by no mean meant to be a complete implementation of the standard.

As described in the README, the goal is to provide a minimum viable product™ to support traditional shape-based icons.

Still, I haven’t had any problem parsing all the SVG that I have created as almost all the icons in Moyeu are entirely SVG based. In general, if you follow the exporting guide in the README you should be fine.

The other good thing about the library is that it’s very simple to use. You will generally use only one class, SvgFactory and its two methods GetBitmap / GetDrawable:

var bmp = SvgFactory.GetBitmap (Activity.Resources, Resource.Raw.ic_svg, 48, 48);
var drawable = SvgFactory.GetDrawable (Activity.Resources, Resource.Raw.ic_svg);

I recommend the second form as the returned drawable will automatically scale depending on the bounds requested. This means that if you have an ImageView set up using dp units like this:

<ImageView
    android:layout_width="14dp"
    android:layout_height="9dp"
    android:scaleType="fitXY" />

The displayed image will look the same crispy crispness on every devices no matter how many pixel per inches they have.

Another cool thing about the library is that it lets you dynamically adapt colors at runtime. To do so, you need to provide an implementation of the ISvgColorMapper interface which sports the single method Color MapColor (Color c) (instance that can also be retrieved from a Func<Color, Color>).

I use this tricks for the pins that are displayed by Moyeu on the map. Concretely, the pins are all the same base SVG:

On which I can apply tinting with my color mapper:

Color ColorReplacer (Color inColor, float ratio)
{
	Color tone = InterpolateColor (baseLightRedColor, baseLightGreenColor, ratio);
	Color result = inColor;

	if (inColor == fillColor)
		result = tone;
	else if (inColor == borderColor)
		result = Lighten (tone, 0x20);
	else if (inColor == bottomFillColor)
		result = InterpolateColor (baseDarkRedColor, baseDarkGreenColor, ratio);

	return result;
}

In order to have a multi-colored view of the world:

You can find more usage sample of the library in Moyeu source code.

A Big Refresh to Moyeu

Moyeu is an Android application that hopes to provide a better alternative to Boston’s Hubway bike sharing system. You can view the introductory post I made at the time.

This new version sports a good number of new features and general UI refresh.

For starter, the navigation is now exposed as a drawer that also lets you visualize stations that are near you.

Instead of the old info window style, information about a station are presented with a sliding info view in the same fashion than the new Google Maps application. That info view when expanded also shows you a Google Street View shot of the station surroundings for easier pinpointing.

The pins displayed on the map are also now showing the number of bikes available at each station. They also have a better tinting system to provide a direct feedback on each station bike availability.

Just for fun, I also made a little featurette page for the app. Check it out at moyeuapp.net.

For installation, head to the usual corner of the web:

Get it on Google Play

Similardio, Rdio Meets Lastfm

What?

An experiment in bridging Rdio and Lastfm together.

The idea is to gather your most listened to artists on Rdio and generously gather similar talents from Lastfm comprehensive database.

All of this straight from your Android phone.

What does it look like?

It has pretty animations. It has blurring. It has large images.

What should I do with it

Use it as an example for bduncavage/RdioSdkBindings or scavenge any other part of it. All under Apache 2.0 license.

GitHub repository: garuma/Similardio

Android app on Google Play

Blurring Images on Android

One of the most underused Android feature is probably RenderScript (do you even remember what it is?).

As a reminder, RenderScript is essentially Google’s version of OpenCL in that it allows you to write small general-purpose piece of code (called kernel) that executes on the GPU.

As such, it’s very efficient when doing parallelizable work on large data-set. The main hindrance as with any GPGPU scenario is that to interoperate with the CPU, data needs to be copied back and forth between RAM and GPU memory.

One of the main area where RenderScript is useful is with images and pixel-oriented algorithms. Since with recent Android version View instances are hardware-accelerated by default, showing up these GPU-processed images on screen is efficient as they don’t even need to be piggy backed to main memory.

Out of the box, Android ships with a couple of pre-made kernels, mainly picture-related. In that sense it can be considered equivalent to iOS CoreGraphics albeit much less rich in available filters.

One of those default script, ScriptIntrinsicBlur, allows you to blur the content of an image very easily:

Bitmap BlurImage (Bitmap input)
{
	var rsScript = RenderScript.Create (Context);
	var alloc = Allocation.CreateFromBitmap (rsScript, input);

	var blur = ScriptIntrinsicBlur.Create (rsScript, alloc.Element);
	blur.SetRadius (12);
	blur.SetInput (alloc);

	var result = Bitmap.CreateBitmap (input.Width, input.Height, input.GetConfig ());
	var outAlloc = Allocation.CreateFromBitmap (rsScript, result);
	blur.ForEach (outAlloc);
	outAlloc.CopyTo (result);

	rsScript.Destroy ();
	return result;
}

The code will certainly look familiar to those of you who have already used OpenCL. You basically create a context (RenderScript), setup typed buffers (Allocation), create the kernel (ScriptIntrinsicBlur), define its entry point (SetInput) and execute it (ForEach).

Below is the result in a small app to select different blur radius:

You can read up Android basic guide on RenderScript for a more in-depth explanation of each step.

Blur effects are becoming more and more trendy these days, being one of the design focus of iOS 7 and also used extensively by apps such as Rdio. With RenderScript you can now cheaply use that trick in your Android app too.

The Very Basic Guide to Contribute to Mono BCL

Here a short how-to start coding and contributing to the Mono Base Class Library.

First thing you need to do if you haven’t already is to go read the coding guidelines.

General Directory Structure

Mono’s BCL implementation is located in mono/mono under the mcs/class subdirectory.

Each folder in this directory represent an assembly and is named like it. Inside each of those directory you will find 4 kinds of folders:

Namespace folders
Those are where the actual BCL class will live, obviously based on their namespace.
Test
This folder mirrors the parent namespace hierarchy for unit tests.
Documentation
This folder contains the ECMA documentation for the assembly classes.
Assembly
This is mainly for the AssemblyInfo.cs file.

Following a standard practice, every type and every test of this type must be in its own file e.g. the String type will be in class/corlib/System/String.cs and its tests in class/corlib/Test/System/StringTest.cs.

Build System

The build system for class libraries has been heavily abstracted in Makefile and is thus very simple to work with.

At the top-level, every assembly directory is registered in the mcs/class/Makefile file. This files contains several _dirs-suffixed variables for each type of framework (.NET 2, .NET 4, mobile, …) and a common one when the assembly is part of all framework versions. To add a new assembly to the build, you will simply add it to the correct variable.

At the assembly level, a Makefile is also present which always contains a couple of standard information like its current path and then includes the default rules.make and library.make that contains all the library building logic.

In this Makefile, the build can be customized using several Make variables among which the most important are:

  • LIBRARY to give the final DLL output name e.g. “System.Core.dll”.
  • LIB_MCS_FLAGS to append build arguments (like references) to the compiler when building the assembly.
  • TEST_MCS_FLAGS similarly when building the unit test assembly.
  • RESOURCE_FILES for files to add as embedded resources.

The Makefile can then contain custom processing if needs be or if the library build is more complicated than the default allows. Generally though you shouldn’t have to mess with it.

Here is a canonical example with the Makefile that builds the System.Net.Http assembly:

thisdir = class/System.Net.Http
SUBDIRS = 
include ../../build/rules.make

LIBRARY = System.Net.Http.dll

LIB_MCS_FLAGS = -r:System.Core.dll -r:System.dll

TEST_MCS_FLAGS = -r:System.dll -r:System.Core.dll

include ../../build/library.make

The most common interaction you will have with the build system is to add files and tests to it. For that purpose you don’t need to touch the Makefiles at all since the class list for each assembly is contained into dedicated files.

These files will always be named in the form of 'assembly name'[_test].dll.sources. Sometimes, they are also optionally prefixed with a profile name (like net_4_0) if relevant in which case its the content is appended when that profile is built.

In our System.Net.Http case, the assembly file list is stored in the System.Net.Http.dll.sources file and its unit tests in the System.Net.Http_test.dll.sources file

If your contribution is only for a specific framework version, you can use a couple of defines automatically declared by the build system.

There are defines for each framework version in the form of NET_{major version}_{minor version} like NET_2_0 or NET_4_5. You can use these defines in code with #if ... #endif blocks to add members that are specific to a .NET version.

Note that these defines are inclusive i.e. when building the 4.5 version of the assembly, all 4.0 and 2.0 #if blocks will also be included so that you only need to specify the framework version when the member was introduced.

For example, the System.IO.Path.Combine (params string[]) method was made public in .NET 4.0 when it was an internal implementation in Mono before. It’s thus declared like the following in the source:

#if NET_4_0
		public
#else
		internal
#endif
		static string Combine (params string [] paths)
		{

Building and Running the Tests

To build an individual assembly, simply cd to its directory and type make to build it with the latest profile available.

If you want to build a specific framework version of the assembly, you can use the PROFILE variable e.g. to build the 2.0 version of System.dll you would do:

cd mcs/class/System && make PROFILE=net_2_0

By default the build will shave most of the output but if you need to see what the final compilation command line looks like, you can activate verbose mode with the V variable like so:

cd mcs/class/System && make PROFILE=net_2_0 V=1

To execute the unit-tests for the assembly, you use the run-test Makefile target which will automatically compile NUnit, your assembly test and then run it. It also accepts the PROFILE variable to execute test in a specific profile.

By default the run-test target will run all the fixture for the assembly. If you are only interested in executing one fixture, you can use the aptly named FIXTURE variable like so:

cd mcs/class/System.Core && make run-test FIXTURE=System.Linq.EnumerableTest

If you need to further customize how NUnit runner is executed, you can use the TEST_HARNESS_FLAGS variable to directly pass argument to the process. This can be useful if you want to execute a single test case:

cd mcs/class/System.Core && make run-test TEST_HARNESS_FLAGS='-run=MonoTests.System.Linq.EnumerableTest.TestSelect'

Notice that in this case, you need to prefix the test namespace with MonoTests. as every tests in Mono is contained into a namespace of the form MonoTests.The.Assembly.Namespace (hint: your tests should too).

Check-list Before the Pull-Request

Before submitting your pull-request, make sure of the following:

  • Your code comply with the coding guidelines mentioned at the top of this how-to. This is most often the cause of initial refusal of the PR.
  • With your code included, you can do a full Mono build and running the entire test suite doesn’t exhibit new regressions (use make check at the top of your Mono checkout).
  • All new code added has corresponding unit tests. This is especially important if you are contributing a bugfix as it’s the only way you’ll know it won’t reappear.

That’s basically it, have fun!