#apple notes #evernote

Evernote recently changed their price plans, free accounts can only sync across 2 devices.

<img src=”https://images.kinopyo.com/images/evernote-price-change.png) alt=”Evernote free account sync limitation” width=”500”>

The change itself is okay, you can’t blame the company trying to make some money and make better products for their core users, but after using it for 7 years, and all the “improvements” the company has made during the time, I realized it’s not the right tool for me. I don’t need presentation mode, nor chat, or any other collaboration/business features; I just want to take notes. I did upgrade to Pro user before but I found I was never using any of those features heh. This change of prices gives me a perfect chance to look for alternatives.

Continue reading...

Use accept_alert to get the alert message.

  • Poltergeist ignores alerts/confirms by default(source)
  • Poltergeist has had support for Capybaras modal api since September 2015( source)

That means you can same syntax for Poltergeist or capybara-webkit.

expect(accept_alert).to eq("Javascript alert message")

# or with block syntax

# will fail if alert message doesn't match
accept_alert("Javascript alert message") do 
  # next expectation
end

The first one expect(accept_alert).to reads a bit weird, but that’s the return value of accept_alert.

#css

If you’re not happy with the default text-decoration: underline, want to tweak the thickness of the underline or vertical space between the text and the underline, then you may want to the background trick introduced in this post. Medium is also using this kind of technique.

// use background image to draw the underline
// this way we can tweak the vertical space between text and underline
a {
  text-decoration: none;

  background-image: linear-gradient(to bottom, rgba(0,0,0,0) 50%, rgba(0,0,0,.6) 50%);
  background-repeat: repeat-x;
  background-size: 2x 2x;
  background-position: 0 22px;
}

A quick demo of how it looks like:

text underline with background image demo

One caveat of this approach is, the position and thickness of the underline is depending on the font size. So if you’re using a different font-size as I do in the demo, you may need to change the background-position to fit your design.

Also if you want to apply it to different part of your page which all have different font-size, you will need to figure out the exact size for each part.

In my blog I’m using SCSS variables to document this behavior.

$post-font-size: 20px;
$underline-size: 2px;

background-size: $underline-size $underline-size;
background-position: 0 ($post-font-size + $underline-size);
#testing

When debugging if you want to check at some lines where you forget to put the binding.pry, you could use some help from pry-byebug’s break points feature.

You can set and adjust breakpoints directly from a Pry session using the break command: https://github.com/deivid-rodriguez/pry-byebug#breakpoints

break SomeClass#run            # Break at the start of `SomeClass#run`.
break app/models/user.rb:15    # Break at line 15 in user.rb.
...

Please bear with me with this example as a showcase.

scenario "Guest can't view draft post" do
  post = create(:post, title: 'Vim', published_at: nil)
  binding.pry
  visit post_path(post)
  expect(page).not_to have_content('Vim')
end

Suppose you put the first binding.pry there to check the creation of post, then somehow you also want to check what’s going on in the controller, normally you would stop/finish the spec and drop the binding.pry to controller and rerun the spec. With pry-byebug you could set the breakpoint in the runtime: when the execution is stopped before the visit post_path(post)

[1] pry(#<RSpec::ExampleGroups::Posts>)> break PostsController#show

  Breakpoint 1: PostsController#show (Enabled)

  10: def show
  11: end

Now the breakpoint is set, if you continue the spec then it’ll stop at the posts#show action.

This is also very useful when you check some codebase you’re not familiar with like gems, during the debugging you also want to check some local variables inside a block or so, with the break command now you don’t need to make changes to the library and restart your rails server.

#poltergeist #rspec

The default window size for poltergeist is 1024 x 768, in some cases you may want to change it to fit your specs.

Change Window Size Per Spec

page.driver.resize_window 1200, 768

Then you can check it this way.

page.driver.browser.client.window_size # => [1200, 768]

Note that this will not change the default window size for other specs, so no need to resize it back.

Change Window Size Globally

If you’re using RSpec, you may want to create a metadata tag for it.

RSpec.configure do |config|
  config.before(:example, :mobile, type: :feature) do
    page.driver.add_headers("User-Agent" => "iPhone")
    page.driver.resize_window 320, 568
  end
end

Here we registered a :mobile metadata tag to change the window size to 320, 568, also set the user agent to further simulate the request from a mobile.

scenario "Do something in mobile", :js, :mobile do
  page.driver.browser.client.window_size # => [320, 568]
end

Change Default Window Size

You could also customize the window size when register the poltergeist drive.

# spec/support/capybara.rb
require 'capybara/poltergeist'

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, window_size: [1600, 768])
end
Capybara.javascript_driver = :poltergeist
#ruby

Ruby Module is an easy and great way to encapsulate related methods/constants and extend a class, but sometimes I find myself really want to tell it something about the current class.

A pseudo code of my “wish” looks like this: of course it’s invalid, Ruby doesn’t allow us to do so.

class Post < ApplicationRecord
  include Publishable(column_name: :published_at)
end

Recently I read a blog post about how the author learned from reading some ruby gems’ implementation to allow including a module with argument. Sounds fun so I gave it a try.

When you may want to include a module with arguments?

Let’s first see an example, this may not be practical but at the moment I couldn’t think of other great ones so please bear with me.

module Publishable
  def publish
    update(published_at: Time.now)
  end
end

class Post < ApplicationRecord
  include Publishable
end

There’s nothing wrong with this code but some may argue that the Publishable module depends on the published_at column name, if someone renames the column to published_on then it’ll be broken, it’s coupled to the Post class.

One way to solve it may look like this:

module Publishable
  def publish
    update(publishable_column_name => Time.now)
  end

  private

  def publishable_column_name
    raise NotImplementedError
  end
end

class Post < ApplicationRecord
  include Publishable

  private

  def publishable_column_name
    :published_at
  end
end

Now the Publishable is relying on its “host”(Post) to define the method publishable_column_name to explicitly tell it the column name, otherwise it will raise the not implemented error. But the downside is the module’s requirement leaks to Post, and that’s arguably break the purpose to use a module, which is to group all methods of a concept in one place.

I’m thinking this could be a use case for the technique I’m gonna show you in this blog post.

Trick: A Class Inherits From Module

How the trick work is already introduced in the article above, let’s fast forward to the end result now.

class Publishable < Module
  def initialize(column_name)
    @column_name = column_name
  end

  def included(base)
    column_name = @column_name

    base.class_eval do # self is Post class
      define_method(:publish) do  
        update(column_name => Time.now) # self is Post object
      end
    end
  end
end

class Post < ApplicationRecord
  include Publishable.new(:published_at)
end

The notable things are

  • class Publishable < Module, we’re not declaring a module, instead we’re making a class that inherits from module
  • When we include this module, we can now initialize it with any arguments
  • The arguments will be available inside the Publishable “module”, hence no the knowledge is decoupled
  • Use define_method(:publish) { } instead of def publish, latter will make you lose the context and you can’t access column_name variable anymore

Why It Works?

I’m gonna borrow the code from the article, this is how Rubinius handles module and is identical to MRI Ruby:

def include?(mod)
  if !mod.kind_of?(Module) or mod.kind_of?(Class)
    raise TypeError, "wrong argument type #{mod.class} (expected Module)"
  end
  # snip
end

When we do include SomeModule, this code will be executed to check if the target is a valid module. The trick is how we could manage to pass that check, that is “something is kind of Module and not kind of Class”.

class Publishable < Module
end

Publishable.kind_of?(Module) # => true
Publishable.kind_of?(Class) # => true

Publishable.new(:published_at).kind_of?(Module) # => true
Publishable.new(:published_at).kind_of?(Class) # => false

With this trick you can pass whatever dependencies from the host to the module. Hope you find it useful, and let me know if you find a good use case with it in real world 😁Not sure if it’s yet another case of abusing Ruby’s flexibility to driver it too far, I do concern about its possible confusion when bring to teams in which people are most likely not aware of this kind of hack.

Further Reading

These 2 gems are using the same technique, and their full implementations are really easy to read and follow.