Today I Learned

A Hashrocket project

21 posts by gabrielreis @greis

Message order constraint in RSpec

Sometimes you need to make sure your code is executing in a specific order. In the example below we have a Payment double that needs to first call processing! and then approved!. So you write a test like this:

it "approves the payment" do
  payment = double("Payment")

  expect(payment).to receive(:processing!)
  expect(payment).to receive(:approved!)

  payment.processing!
  payment.approved!
end

If you change the order of the method calls your test will still pass:

...
  payment.approved!
  payment.processing!
...

Finished in 0.01601 seconds (files took 0.20832 seconds to load)
1 example, 0 failures

To guarantee the order, RSpec has an option to specify an order constraint. So we want to make sure processing! is called before approved! :

 expect(payment).to receive(:processing!).ordered
 expect(payment).to receive(:approved!).ordered

Now if you run the test with the wrong order, you will see the error:

it "approves the payment" do
  payment = double("Payment")

  expect(payment).to receive(:processing!).ordered
  expect(payment).to receive(:approved!).ordered

  payment.approved!
  payment.processing!
end

Failure/Error: payment.approved!
   #<Double "Payment"> received :approved! out of order

Invisible components in React Native

Sometimes you want a component to be rendered but not visible to the user and in React Native 0.42 and below, you could accomplish that by setting the component’s height and width to 0.

The good news is that React Native 0.43 will make it easier and introduce the CSS property you are already familiar with: display: 'none'.

You can already try it installing the pre-release version 0.43.0-rc.4.

Making your JS files prettier on Vim

We all use VIM at Hashrocket and we can run prettier everytime we save a JS file:

yarn global add prettier
autocmd FileType javascript set formatprg=prettier\ --single-quote\ --trailing-comma\ es5\ --stdin
autocmd BufWritePre *.js :normal gggqG
autocmd BufWritePre *.js exe "normal! gggqG\<C-o>\<C-o>"

And yes. I like trailing comma,

** Update: There is an open issue on Github when prettier fails to parse the JS file but there is a workaround for it.

Pipe | after | grep

The grep command may not work properly if you want to pipe another command after it, specially when you are tailing a file for example. Just call grep with --line-buffered

heroku logs -t | grep --line-buffered "heroku\[router\]" | awk '{print $11" "$5}'

This command outputs an easy-to-read performance log for each HTTP request:

service=266ms path="/api/posts"
service=142ms path="/api/users"

TouchableHighlight with custom component

Usually in React Native when you want to add touch events to a custom component you just wrap it with a Touchable* component.

If you want to use TouchableOpacity there is no need to change anything on the custom component, but if you want to use TouchableHighlight you have to change the component and implement setNativeProps and delegate to the container View:

class CustomComponent extends Component {
  render() {
    return (
      <View ref='container'>
        ...
      </View>
    )
  }

  setNativeProps(nativeProps) {
    this.refs.container.setNativeProps(nativeProps);
  }
}

And then you are ready to go:

<TouchableHighlight onPress={this._onPress} underlayColor="#fc0">
  <CustomComponent />
</TouchableHighlight>