# frozen_string_literal: true require_relative 'watcher' module PageMagic # module Watchers - contains methods for adding watchers and checking them module Watchers ELEMENT_MISSING_MSG = 'Unable to defined watcher: Element or method with the name %s can not be found' # @param [Symbol] name - the name of the watcher # @return [Boolean] true if a change is detected def changed?(name) watched_element = watcher(name) watched_element.observed_value != watched_element.check.observed_value end # register a new watcher # @overload watch(:price, context: object, method: :text) # @param [Symbol] name of the watcher/element # @param [Object] context the object that is being watched - defaults to self # @param [Symbol] method - the method on the watched element to check # @overload watch(:text) # @param [Symbol] method - the method on the watched element to check # @overload watch(:text, &blk) # @param [Symbol] name of the watcher/element # @yieldreturn [Object] the value that should be checked # @example # watch(:something) do # # more complicated code to get value # end def watch(name, context: self, method: nil, &blk) watcher = blk ? Watcher.new(name, context: context, &blk) : watch_method(name, context: context, method: method) watchers.delete_if { |w| w.name == name } watchers << watcher.check end # retrieve a watcher given its name # @param [Symbol] name the name of the watcher # @return [Watcher] watcher with the given name def watcher(name) watchers.find { |watcher| watcher.name == name } end # @return [Array] registered watchers def watchers @watchers ||= [] end private def watch_method(name, context:, method:) subject = method || name raise ElementMissingException, (ELEMENT_MISSING_MSG % subject) unless context.respond_to?(subject) Watcher.new(name, context: context) do public_send(subject) end end end end