YAML !omap

Why did we use an !omap in the source YAML? This Wiki will eventually support any kind of YAML. Short-term, we only need pages that present lists of test cases, and !omaps are the only ordered maps in YAML. So, short-term, this project will only use !omap nodes containing !omap and !str nodes. Future iterations can easily add other types. This Short Cut focuses on Ajax, not elaborate HTML, and if we can convert two YAML types then the rest will be easy.

This new code passes those tests:

class YarWiki
  def initialize(page_name = 'FrontPage')
    @page_name = page_name.to_s
  end

  attr_reader :page_name

  def wiki_path
    wp = File.expand_path(File.join(RAILS_ROOT, 'wiki'))
    Dir.mkdir(wp) rescue nil
    return wp
  end

  def yaml_path
    File.join(wiki_path, page_name + '.yaml')
  end

  def save_page(contents)
    File.open(yaml_path, 'w'){|f|  f.write(contents)  }
  end

  def format_yaml(x)
    return unless File.exist?(yaml_path)
    seq = YAML::parse_file(yaml_path)

    x.ul do
      seq.children.each do |kid|
        x.li do
          hash = kid.value
          x.strong( hash.keys.first.value )
          x.text! ': ' + hash.values.first.value
        end
      end
    end
  end
end

YAML::Syck expresses an !omap as a Seq object containing a list of Map objects, so the method format_yaml works in two phases. We grab the Seq and iterate through its children; each one is a Map with only one key and one value. We print the key in strong markup, and we print the value after a colon.

Both the key and the value are Scalar objects, and we get their raw data from their .value members. Our preliminary formatting is soon to upgrade.

The new tests force edits inside index.rhtml. It fetches the current page name from the params data block into the YarWiki object, to render the page. I mark the relevant changes in bold, and hide the irrelevant code with ellipses:

    x.tr do
      x.td :id => 'wiki_panel',
...
        yar.format_yaml(x)
      end

The line File.join(RAILS_ROOT, 'wiki') points to a new subfolder of RAILS_ROOT called wiki/. We will stash our pages there, because our Wiki is an addition to Rails, outside its other systems. If you need different concepts, put your Wiki pages somewhere else.

assert_routing

Our Wiki's path is disturbing:

http://localhost:3000/wiki/index/WikiTestPage

It neglects the Web 2.0 ideal of "Pretty URIs." Fixing it allows us to briefly demonstrate another nonheinous Rails assertion:

  def test_clean_uri
    assert_routing '/wiki/WikiTestPage',
                    :controller => 'wiki',
                    :id => 'WikiTestPage'
  end

That new test with assert_routing fails, inspiring us to go into config/routes.rb and add this line:

  map.connect 'wiki/*id', :controller => 'wiki', :action => 'index'

That line works, but it breaks any old-fashioned actions. Our Wiki will need those to serve Ajax hits. If all our Wiki pages use WikiName format, and all our actions are rails_style, we can restrict our routing table to distinguish them. Hence:

  def test_dont_route_actions
    assert_routing '/wiki/action',
                   :controller => 'wiki',
                   :action => 'action'
  end

And:

  map.connect 'wiki/*id', :controller => 'wiki', :action => 'index',
    :requirements => { :id => /(?:[A-Z][a-z]+)+/ }

Now we can take the redundant "index/" out of our URI. A public Wiki would also take out the word "wiki". Our goal is a private administrative Wiki supporting some other web site, so we'll leave that in. (This Short Cut also leaves securing that Wiki with a password as an exercise for the reader.)

assert_routing is a good example of an assertion that targets semantics instead of just syntax. The first argument is an example of the URI path that our users should type, and the optional arguments declare how the routing system should decompose that URI. So assert_routing helps us play "what if" with our URIs, and detect how they match users' guesses and assumptions.

After an excursion into testing semantics, we will now learn a very good way to test more syntax!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.178.133