mickm
mickm

Reputation: 391

ruby, rspec, and json.erb: unit testing a JSON template

I'm having some trouble unit testing some windy json.erb logic. The below ERB template builds the required JSON file:

Fig1:

"api": {
<% unless @GLANCE_IMAGE_API_WORKERS_NUM.nil? %>
  "workers": <%= @GLANCE_IMAGE_API_WORKERS_NUM %>
<% if @GLANCE_BACKEND == 'ceph' %>
  <% unless @GLANCE_IMAGE_API_WORKERS_NUM.to_s.empty? %>,<% end %>
  "default_store": "rbd"
<% end %>
<% if !@IMAGE_CACHE_MAX_SIZE.to_s.empty? %>
  <% unless @GLANCE_IMAGE_API_WORKERS_NUM.to_s.empty? && @GLANCE_BACKEND != 'ceph' %>,<% end %>
  "cache" : {
    "image_cache_max_size": <%= @IMAGE_CACHE_MAX_SIZE %>
  }
<% end %>

To build the JSON it adds trailing commas if and when they are required. For example, if glance_backend is set to 'ceph', a comma is required after glance.image.api_workers to allow for a following entry and make the JSON valid - example:

Fig 2.

 "api": {
          "workers": 8,
          "cache": {
            "image_cache_max_size": 10000000000
          }
        },

I'm trying to test all the potential scenarios for the logic in Fig 1. I believe them to be something like this (pseudo-code):

So far, my rspec logic looks like this - Fig3:

context 'comma appended to "glance.api.workers" in correct circumstances' do

    before do
      data_bag['IMAGE_CACHE_MAX_SIZE'] = 10000
      data_bag['GLUSTER_BACKEND'] = 'ceph'
      data_bag['GLUSTER_IMAGE_API_WORKERS'] = 'not_empty'
    end

    it 'sets default_store attributes' do
      expect(override_attr['openstack']['image']['api']['workers'])
        .to include(",")
    end

    before do
      data_bag['IMAGE_CACHE_MAX_SIZE'] = 10000
      data_bag['GLUSTER_BACKEND'] = 'local'
      data_bag['GLUSTER_IMAGE_API_WORKERS'] = ''
    end

    it 'sets default_store attributes' do
      expect(override_attr['openstack']['image']['api']['workers'])
        .to_not include(",")
    end

    before do
      data_bag['IMAGE_CACHE_MAX_SIZE'] = 10000
      data_bag['GLUSTER_BACKEND'] = 'local'
      data_bag['GLUSTER_IMAGE_API_WORKERS'] = 'not_empty'
    end

    it 'sets default_store attributes' do
      expect(override_attr['openstack']['image']['api']['workers'])
        .to_not include(",")
    end
  end

This may be the completely wrong way to go about this. Looking forward to hearing some suggestions. Thanks.

Upvotes: 0

Views: 294

Answers (1)

retgoat
retgoat

Reputation: 2464

I suggest yo use jbuilder gem. It allows to build any valid JSON structures you'd like. This way will allow you do get rid of complicated erb logic.

To test it's validness you may use json_spec.

Here is an example:

# example_controller.rb

def workers
  @GLANCE_IMAGE_API_WORKERS_NUM = 8
  @GLANCE_BACKEND = "ceph"
  @IMAGE_CACHE_MAX_SIZE = 10000000000
  @GLUSTER_BACKEND = "ceph"
end

# app/views/whatever.jbuilder

json.api do |json|
  json.workers @GLANCE_IMAGE_API_WORKERS_NUM if @GLANCE_IMAGE_API_WORKERS_NUM
  json.cache do |nest|
    nest.image_cache_max_size @IMAGE_CACHE_MAX_SIZE
  end
end

It will produce

{
    "api": {
        "workers": 8,
        "cache": {
            "image_cache_max_size": 10000000000
        }
    }
}

Please be noted I have no idea how is your controller works. If you'll provide more details, I'll do ny best to help you better.

Upvotes: 1

Related Questions