A pleasant walk through computing

Comment for me? Send an email. I might even update the post!

Tabs vs Spaces is Dumb. Convert Tabs INTO Spaces.

^t => "    " = ♥

A part of me thinks this is so obvious I shouldn't need to post about it. But I keep seeing "tabs vs spaces" articles by programmers and just...don't...get it.

Modern text editors let you choose in settings how to treat tabs. The significant choices are:

  1. How many spaces a tab represents
  2. Whether to save the tab character in the document or convert it to spaces

To me this has always been easy.

  1. Four spaces
  2. Convert tabs to spaces

When typing, it's faster to indent using the tab key. But when sharing with another person, there's no guarantee their tabs will use the same number of spaces as yours. So fidelity and consistency demand spaces.1

It doesn't matter what efficient keyboard shorcuts you take to generate the spaces, as long as the document ends up with only spaces.

The only argument for storing tabs in the document is being able to back "space" using them. But it's not enough of a timesaver to overcome the advantages of storing spaces.

There is no reasonable--or reason for a--tabs vs spaces debate.


  1. If you never share your work, then the entire question is moot. I don't care what you do.

What Is Cyclomatic Complexity In a Nutshell?

Imagine you're going to walk to a friend's house. If the house is a few doors down, you don't need to make any decisions. But if your friend is further away, you may come to an intersection. You choose a direction and come to another intersection, and so on. How many paths are there to your friend's house?

That's cyclomatic complexity in a nutshell.

The number of independent paths through a method.

Map1

Map2

Using FluentAssertions with xUnit Theory to Test for an Exception AND a Successful Return

I recently wanted to unit test a method that required significant setup, and where an invalid method argument would throw an exception while valid values returned easily testable results.

While I could have created a separate test, this really lent itself to using an xUnit Theory. The problem I faced was how to test for the exception but also test for a valid return. I didn't want to write duplicate code within the test itself, such as declaring the service twice.

Some research and experimentation led to the approach below. The trick is to declare a delegate function, then use FluentAssertions to either catch the invocation exception, or to invoke the function and return the value.

Here's a simple Class Library app to demonstrate the technique. I kind of love this because there's no wasted or duplicate code.

using System;
using FluentAssertions;
using Xunit;

namespace FluentAssertionsInvoking
{
    public class CustomerService_Should
    {
        [Theory]
        [InlineData(null)]
        [InlineData("Marcus Welby")]
        public void Return_a_customer_or_throw_an_exception(string name)
        {
            // arrange
            var expected = new Customer() { Name = name };
            var customerService = new CustomerService(expected);

            // act
            Func<CustomerService, Customer> action = service => service.GetCustomer();

            // assert
            // Exception condition
            if (name == null)
            {
                customerService.Invoking(action).Should().Throw<Exception>();
            }
            else
            // Valid condition
            {
                var result = action.Invoke(customerService);
                result.Should().BeEquivalentTo(expected);
            }
        }
    }

    public class Customer
    {
        public string Name { get; set; }
    }

    public class CustomerService
    {
        private Customer _customer;
        public CustomerService(Customer customer)
        {
            _customer = customer;
        }
        public Customer GetCustomer()
        {
            if (_customer.Name == null) { throw new Exception(); }
            return _customer;
        }
    }
}

References

Bonus

Here's the xunit.runner.json to show only method names in the Test Runner output. Remember to set the file to Copy to Output.

{
  "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
  "methodDisplay": "method"
}

   Older