class RUTL::View

Base view class. It's used to call the magical method_messing stuff to parse the view object files into actual objects.

Attributes

interface[W]

Written by Application and only used internally.

Public Class Methods

new(interface) click to toggle source

rubocop:enable Style/ClassVars

# File lib/rutl/view.rb, line 43
def initialize(interface)
  @interface = interface
  # Dirty trick because we're loading all of view classes from files and
  # then initializing them, calling their layout methods to do magic.
  # The view class knows what views are loaded.
  return if @@loaded_views.include?(self.class)
  layout
  @@loaded_views << self.class
end
url() click to toggle source

BUGBUG #1: Some view in a generic app should not have URL.

BUGBUG: Kludgy. What do I really want to do here? Make it easy to define a view's default url and also matchers for view urls for views with variable urls? rubocop:disable Style/TrivialAccessors

# File lib/rutl/view.rb, line 17
def self.url
  @url
end

Public Instance Methods

go_to_here() click to toggle source

rubocop:enable Style/TrivialAccessors

# File lib/rutl/view.rb, line 26
def go_to_here
  # Ovveride this in base view to have something more
  # complicated than this.
  @interface.driver.navigate.to(url)
end
loaded?() click to toggle source
# File lib/rutl/view.rb, line 32
def loaded?
  # Default to only checking url to see if view loaded.
  url == @interface.driver.current_url
end
method_missing(element, *args, &_block) click to toggle source

This creates a new element instance whenever it's called. Because of that we can't keep state in any element objects. That seems like a good thing, actually. Called by layout method on views.

Hard to make shorter. rubocop:disable Metrics/MethodLength

# File lib/rutl/view.rb, line 93
def method_missing(element, *args, &_block)
  name, selectors, rest = args
  context = RUTL::Element::ElementContext.new(destinations: rest,
                                              interface: @interface,
                                              selectors: selectors)
  case element
  when /button/, /checkbox/, /element/, /link/
    add_method(name: name, context: context, klass: element)
  when /text/
    add_method(name: name, context: context, klass: element)
    add_method(name: name, context: context, klass: element, setter: true)
  else
    # TODO: replace with a super call. This is useful for debugging for now.
    raise "#{element} NOT FOUND WITH ARGS #{args}!!!"
  end
end
respond_to_missing?(*args) click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/rutl/view.rb, line 111
def respond_to_missing?(*args)
  # Is this right at all???
  case args[0].to_s
  when /button/, /checkbox/, /element/, /link/, /text/,
       'driver', 'children', 'loaded?'
    true
  when 'ok_link'
    raise 'OK LINK WAY DOWN HERE IN BASE VIEW!!!'
  else
    # I think it's good to raise but change the message.
    raise 'TODO: BETTER ERROR MESSAGE, PLEASE. I AM SHOUTING!!!\n' \
          'Drew, you hit this most often when checking current view ' \
          "rather than current view class:\n\n #{args}"
    # I think I want to raise instead of returningn false.
  end
end
url() click to toggle source
# File lib/rutl/view.rb, line 21
def url
  self.class.url
end

Private Instance Methods

add_method(context:, klass:, name:, setter: false) click to toggle source

Dynamically add a method, :<name> (or :<name>= if setter) to the current class where that method creates an instance of klass. context is a RUTL::Element::ElementContext

As it is, this seems silly to break into pieces for Rubocop. rubocop:disable Metrics/MethodLength

# File lib/rutl/view.rb, line 68
def add_method(context:, klass:, name:, setter: false)
  name = "#{name}_#{klass.downcase}" if RUTL::HUNGARIAN
  constant = Module.const_get("RUTL::Element::#{klass.capitalize}")
  self.class.class_exec do
    if setter
      define_method("#{name}=") do |value|
        constant.new(context, value)
      end
    else
      define_method(name) do
        constant.new(context)
      end
    end
  end
end