I am trying to play around with the RODA Ruby web framework based on Rack. However, I am having issues with using Minitest with the framework. RSpec was hectic with it too unlike Rails. I tried to reproduce the error with pry, but I couldn't make sense of it. How should I fix this? I am getting
undefined method `entry_mapping' for nil:NilClass.
Below is the associated code:
Gemfile
gem 'contentful_model', '~> 1.3' # ActiveModel-like wrapper for the Contentful SDKs
group :test do
gem 'capybara'
gem 'minitest', '>= 5.7.0'
gem 'minitest-hooks', '>= 1.1.0'
gem "minitest-global_expectations"
gem "warning"
gem 'pry'
end
models/recipe.rb
require 'contentful_model'
class Recipe < ContentfulModel::Base
self.content_type_id = 'recipe'
def self.all_recipes
all.load!
end
end
app.rb | Tree Routing
require './.env' if File.exist?(".env.rb")
require './config/initializers/contentful_model'
require 'roda'
require './models/recipe'
require 'tilt/sass'
class App < Roda
hash_routes do
view '', 'index'
end
route do |r|
#recipes = Recipe.all_recipes
r.public
r.assets
check_csrf!
r.hash_routes('')
r.get String do |id|
#recipe_details = Recipe.find(id)
next unless #recipe_details
view 'show'
end
end
end
spec/models/spec_helper.rb
ENV["RACK_ENV"] = "test"
require_relative '../../models/recipe'
require_relative '../minitest_helper'
spec/models/recipe_spec.rb
require_relative 'spec_helper'
describe Recipe do
let(:recipes) { Recipe.all_recipes }
describe '.all_recipes' do
it 'return all records with content type recipe' do
recipes = Recipe.all_recipes # undefined method `entry_mapping' for nil:NilClass
expect(recipes).to all must_be Recipe
end
end
end
pry debug
From: /Users/tiwa/RubymineProjects/marley-spoon-roda/spec/models/recipe_spec.rb:27 .all_recipes#test_0001_return all records with content type recipe:
24: it 'return all records with content type recipe' do
25: recipes = Recipe.all_recipes # undefined method `entry_mapping' for nil:NilClass
26: binding.pry
=> 27: expect(recipes).to all must_be Recipe
28: end
[1] pry(#<.all_recipes>)> Recipe.all_recipes
NoMethodError: undefined method `entry_mapping' for nil:NilClass
from /Users/tiwa/.gem/ruby/2.7.1/gems/contentful_model-1.3.0/lib/contentful_model/base.rb:124:in `mapping?'
I see the code in contentful_model-1.3.0/lib/contentful_model/base.rb:124 is:
ContentfulModel.configuration.entry_mapping.key?(#content_type_id)
If error msg is undefined method `entry_mapping' for nil:NilClass then
ContentfulModel.configuration
Is nil
To fix this you need configure ContentfulModel. Something like that:
ContentfulModel.configure do |config|
config.access_token = "your access token in here" # Required
config.preview_access_token = "your preview token in here" # Optional - required if you want to use the preview API
config.management_token = "your management token in here" # Optional - required if you want to update or create content
config.space = "your space id in here" # Required
config.environment = "master" # Optional - defaults to 'master'
config.default_locale = "en-US" # Optional - defaults to 'en-US'
config.options = { # Optional
# Extra options to send to the Contentful::Client and Contentful::Management::Client
# See https://github.com/contentful/contentful.rb#configuration
# Optional:
# Use `delivery_api` and `management_api` keys to limit to what API the settings
# will apply. Useful because Delivery API is usually visitor facing, while Management
# is used in background tasks that can run much longer. For example:
delivery_api: {
timeout_read: 6
},
management_api: {
timeout_read: 100
}
}
end
With this config this call is not more nil
ContentfulModel.configuration
See https://github.com/contentful/contentful_model
When I run rails c, I can call the following class and the method works:
test = SlackService::BoardGameNotifier
test.create_alert("test")
>>method works
I'm trying to set this up in rspec like this:
require 'spec_helper'
require 'slack-notifier'
RSpec.describe SlackService::BoardGameNotifier do
describe '#notify' do
#notifier = SlackService::BoardGameNotifier
it 'pings Slack' do
error = nil
message = "test"
expect(notifier).to receive(:ping).with(message)
notifier.send_message()
end
end
end
But I keep getting the error:
NameError:
uninitialized constant SlackService
Does this have to do with how I set up the module?
My current setup:
slack_service/board_game_notifier.rb
module SlackService
class BoardGameNotifier < BaseNotifier
WEBHOOK_URL = Rails.configuration.x.slack.url
DEFAULT_OPTIONS = {
channel: "board-games-channel",
text: "board games alert",
username: "bot",
}
def create_alert(message)
message #testing
end
end
end
slack_service/base_notifier.rb
module SlackService
class BaseNotifier
include Singleton
def initialize
webhook_url = self.class::WEBHOOK_URL
options = self.class::DEFAULT_OPTIONS
#notifier = Slack::Notifier.new(webhook_url, options)
end
def self.send_message
message = instance.create_alert("test")
instance.notify(message)
end
def notify(message)
#notifier.post blocks: message
end
end
end
Add this to your spec_helper.rb
# spec_helper.rb
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../config/environment", __dir__)
When running RSpec, Rails doesn't automatically boot up, and therefore doesn't automatically load all the libraries.
Also, I'd suggest creating a .rspec in your app's root folder with the following lines so that spec_helper is automatically loaded for all your RSpec tests:
# .rspec
--format documentation
--color
--require spec_helper
I would use the described_class from Rspec
require 'spec_helper'
require 'slack-notifier'
RSpec.describe ::SlackService::BoardGameNotifier do
describe '#notify' do
it 'pings Slack' do
error = nil
message = "test"
expect(described_class).to receive(:ping).with(message)
notifier.send_message()
end
end
end
Whatever that I try to do is generating the error message below:
/home/diogodalla/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require': Could not load 'active_record/connection_adapters/sqlite3_adapter'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile. (LoadError)
I'm using PG on my gemFile, I don't know why it keep looking for sqlite3.
My Gem File:
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
"https://github.com/#{repo_name}.git"
end
gem 'rails', '~> 5.1.4'
gem 'pg', '~> 0.18'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'bootstrap-sass', '~> 3.3.6'
gem 'jquery-rails'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'font-awesome-sass', '~> 4.6.2'
gem "paperclip", "~> 5.0.0"
gem 'geocoder', '~> 1.4'
gem 'searchkick'
gem 'chartkick'
group :development, :test do
gem 'byebug', platform: :mri
end
group :development do
gem 'web-console', '>= 3.3.0'
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Also my DataBase.yml:
# PostgreSQL. Versions 9.1 and up are supported.
#
# Install the pg driver:
# gem install pg
# On OS X with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On OS X with MacPorts:
# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem 'pg'
#
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
# The specified database role being used to connect to postgres.
# To create additional roles in postgres see `$ createuser --help`.
# When left blank, postgres will use the default role. This is
# the same name as the operating system user that initialized the database.
#username: TaskManager
# The password associated with the postgres role (username).
#password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
# domain sockets, so uncomment these lines.
#host: localhost
# The TCP port the server listens on. Defaults to 5432.
# If your server runs on a different port number, change accordingly.
#port: 5432
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
# Minimum log levels, in increasing order:
# debug5, debug4, debug3, debug2, debug1,
# log, notice, warning, error, fatal, and panic
# Defaults to warning.
#min_messages: notice
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: TaskManager_test
# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
# DATABASE_URL="postgres://myuser:mypass#localhost/somedatabase"
#
# You can use this database configuration with:
#
# production:
# url: <%= ENV['DATABASE_URL'] %>
#
production:
<<: *default
database: TaskManager_production
username: TaskManager
password: <%= ENV['TASKMANAGER_DATABASE_PASSWORD'] %>
And my dependecies.rb
require "set"
require "thread"
require "concurrent/map"
require "pathname"
require "active_support/core_ext/module/aliasing"
require "active_support/core_ext/module/attribute_accessors"
require "active_support/core_ext/module/introspection"
require "active_support/core_ext/module/anonymous"
require "active_support/core_ext/object/blank"
require "active_support/core_ext/kernel/reporting"
require "active_support/core_ext/load_error"
require "active_support/core_ext/name_error"
require "active_support/core_ext/string/starts_ends_with"
require "active_support/dependencies/interlock"
require "active_support/inflector"
module ActiveSupport #:nodoc:
module Dependencies #:nodoc:
extend self
mattr_accessor :interlock
self.interlock = Interlock.new
# :doc:
# Execute the supplied block without interference from any
# concurrent loads.
def self.run_interlock
Dependencies.interlock.running { yield }
end
# Execute the supplied block while holding an exclusive lock,
# preventing any other thread from being inside a #run_interlock
# block at the same time.
def self.load_interlock
Dependencies.interlock.loading { yield }
end
# Execute the supplied block while holding an exclusive lock,
# preventing any other thread from being inside a #run_interlock
# block at the same time.
def self.unload_interlock
Dependencies.interlock.unloading { yield }
end
# :nodoc:
# Should we turn on Ruby warnings on the first load of dependent files?
mattr_accessor :warnings_on_first_load
self.warnings_on_first_load = false
# All files ever loaded.
mattr_accessor :history
self.history = Set.new
# All files currently loaded.
mattr_accessor :loaded
self.loaded = Set.new
# Stack of files being loaded.
mattr_accessor :loading
self.loading = []
# Should we load files or require them?
mattr_accessor :mechanism
self.mechanism = ENV["NO_RELOAD"] ? :require : :load
# The set of directories from which we may automatically load files. Files
# under these directories will be reloaded on each request in development mode,
# unless the directory also appears in autoload_once_paths.
mattr_accessor :autoload_paths
self.autoload_paths = []
# The set of directories from which automatically loaded constants are loaded
# only once. All directories in this set must also be present in +autoload_paths+.
mattr_accessor :autoload_once_paths
self.autoload_once_paths = []
# An array of qualified constant names that have been loaded. Adding a name
# to this array will cause it to be unloaded the next time Dependencies are
# cleared.
mattr_accessor :autoloaded_constants
self.autoloaded_constants = []
# An array of constant names that need to be unloaded on every request. Used
# to allow arbitrary constants to be marked for unloading.
mattr_accessor :explicitly_unloadable_constants
self.explicitly_unloadable_constants = []
# The WatchStack keeps a stack of the modules being watched as files are
# loaded. If a file in the process of being loaded (parent.rb) triggers the
# load of another file (child.rb) the stack will ensure that child.rb
# handles the new constants.
#
# If child.rb is being autoloaded, its constants will be added to
# autoloaded_constants. If it was being `require`d, they will be discarded.
#
# This is handled by walking back up the watch stack and adding the constants
# found by child.rb to the list of original constants in parent.rb.
class WatchStack
include Enumerable
# #watching is a stack of lists of constants being watched. For instance,
# if parent.rb is autoloaded, the stack will look like [[Object]]. If
# parent.rb then requires namespace/child.rb, the stack will look like
# [[Object], [Namespace]].
def initialize
#watching = []
#stack = Hash.new { |h, k| h[k] = [] }
end
def each(&block)
#stack.each(&block)
end
def watching?
!#watching.empty?
end
# Returns a list of new constants found since the last call to
# <tt>watch_namespaces</tt>.
def new_constants
constants = []
# Grab the list of namespaces that we're looking for new constants under
#watching.last.each do |namespace|
# Retrieve the constants that were present under the namespace when watch_namespaces
# was originally called
original_constants = #stack[namespace].last
mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
next unless mod.is_a?(Module)
new_constants = mod.constants(false) - original_constants
#stack[namespace].each do |namespace_constants|
namespace_constants.concat(new_constants)
end
# Normalize the list of new constants, and add them to the list we will return
new_constants.each do |suffix|
constants << ([namespace, suffix] - ["Object"]).join("::".freeze)
end
end
constants
ensure
# A call to new_constants is always called after a call to watch_namespaces
pop_modules(#watching.pop)
end
def watch_namespaces(namespaces)
#watching << namespaces.map do |namespace|
module_name = Dependencies.to_constant_name(namespace)
original_constants = Dependencies.qualified_const_defined?(module_name) ?
Inflector.constantize(module_name).constants(false) : []
#stack[module_name] << original_constants
module_name
end
end
private
def pop_modules(modules)
modules.each { |mod| #stack[mod].pop }
end
end
# An internal stack used to record which constants are loaded by any block.
mattr_accessor :constant_watch_stack
self.constant_watch_stack = WatchStack.new
# Module includes this module.
module ModuleConstMissing #:nodoc:
def self.append_features(base)
base.class_eval do
# Emulate #exclude via an ivar
return if defined?(#_const_missing) && #_const_missing
#_const_missing = instance_method(:const_missing)
remove_method(:const_missing)
end
super
end
def self.exclude_from(base)
base.class_eval do
define_method :const_missing, #_const_missing
#_const_missing = nil
end
end
def const_missing(const_name)
from_mod = anonymous? ? guess_for_anonymous(const_name) : self
Dependencies.load_missing_constant(from_mod, const_name)
end
def guess_for_anonymous(const_name)
if Object.const_defined?(const_name)
raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name
else
Object
end
end
def unloadable(const_desc = self)
super(const_desc)
end
end
# Object includes this module.
module Loadable #:nodoc:
def self.exclude_from(base)
base.class_eval do
define_method(:load, Kernel.instance_method(:load))
private :load
end
end
def require_or_load(file_name)
Dependencies.require_or_load(file_name)
end
def require_dependency(file_name, message = "No such file to load -- %s.rb")
file_name = file_name.to_path if file_name.respond_to?(:to_path)
unless file_name.is_a?(String)
raise ArgumentError, "the file name must either be a String or implement #to_path -- you passed #{file_name.inspect}"
end
Dependencies.depend_on(file_name, message)
end
def load_dependency(file)
if Dependencies.load? && Dependencies.constant_watch_stack.watching?
Dependencies.new_constants_in(Object) { yield }
else
yield
end
rescue Exception => exception # errors from loading file
exception.blame_file! file if exception.respond_to? :blame_file!
raise
end
def unloadable(const_desc)
Dependencies.mark_for_unload const_desc
end
private
def load(file, wrap = false)
result = false
load_dependency(file) { result = super }
result
end
def require(file)
result = false
load_dependency(file) { result = super }
result
end
end
# Exception file-blaming.
module Blamable #:nodoc:
def blame_file!(file)
(#blamed_files ||= []).unshift file
end
def blamed_files
#blamed_files ||= []
end
def describe_blame
return nil if blamed_files.empty?
"This error occurred while loading the following files:\n #{blamed_files.join "\n "}"
end
def copy_blame!(exc)
#blamed_files = exc.blamed_files.clone
self
end
end
def hook!
Object.class_eval { include Loadable }
Module.class_eval { include ModuleConstMissing }
Exception.class_eval { include Blamable }
end
def unhook!
ModuleConstMissing.exclude_from(Module)
Loadable.exclude_from(Object)
end
def load?
mechanism == :load
end
def depend_on(file_name, message = "No such file to load -- %s.rb")
path = search_for_file(file_name)
require_or_load(path || file_name)
rescue LoadError => load_error
if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
load_error.message.replace(message % file_name)
load_error.copy_blame!(load_error)
end
raise
end
def clear
Dependencies.unload_interlock do
loaded.clear
loading.clear
remove_unloadable_constants!
end
end
def require_or_load(file_name, const_path = nil)
file_name = $` if file_name =~ /\.rb\z/
expanded = File.expand_path(file_name)
return if loaded.include?(expanded)
Dependencies.load_interlock do
# Maybe it got loaded while we were waiting for our lock:
return if loaded.include?(expanded)
loaded << expanded
loading << expanded
begin
if load?
# Enable warnings if this file has not been loaded before and
# warnings_on_first_load is set.
load_args = ["#{file_name}.rb"]
load_args << const_path unless const_path.nil?
if !warnings_on_first_load || history.include?(expanded)
result = load_file(*load_args)
else
enable_warnings { result = load_file(*load_args) }
end
else
result = require file_name
end
rescue Exception
loaded.delete expanded
raise
ensure
loading.pop
end
# Record history *after* loading so first load gets warnings.
history << expanded
result
end
end
# Is the provided constant path defined?
def qualified_const_defined?(path)
Object.const_defined?(path, false)
end
def loadable_constants_for_path(path, bases = autoload_paths)
path = $` if path =~ /\.rb\z/
expanded_path = File.expand_path(path)
paths = []
bases.each do |root|
expanded_root = File.expand_path(root)
next unless expanded_path.start_with?(expanded_root)
root_size = expanded_root.size
next if expanded_path[root_size] != ?/.freeze
nesting = expanded_path[(root_size + 1)..-1]
paths << nesting.camelize unless nesting.blank?
end
paths.uniq!
paths
end
# Search for a file in autoload_paths matching the provided suffix.
def search_for_file(path_suffix)
path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb".freeze)
autoload_paths.each do |root|
path = File.join(root, path_suffix)
return path if File.file? path
end
nil # Gee, I sure wish we had first_match ;-)
end
def autoloadable_module?(path_suffix)
autoload_paths.each do |load_path|
return load_path if File.directory? File.join(load_path, path_suffix)
end
nil
end
def load_once_path?(path)
# to_s works around a ruby issue where String#starts_with?(Pathname)
# will raise a TypeError: no implicit conversion of Pathname into String
autoload_once_paths.any? { |base| path.starts_with? base.to_s }
end
def autoload_module!(into, const_name, qualified_name, path_suffix)
return nil unless base_path = autoloadable_module?(path_suffix)
mod = Module.new
into.const_set const_name, mod
autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
mod
end
def load_file(path, const_paths = loadable_constants_for_path(path))
const_paths = [const_paths].compact unless const_paths.is_a? Array
parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object }
result = nil
newly_defined_paths = new_constants_in(*parent_paths) do
result = Kernel.load path
end
autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
autoloaded_constants.uniq!
result
end
def qualified_name_for(mod, name)
mod_name = to_constant_name mod
mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
end
def load_missing_constant(from_mod, const_name)
unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
end
qualified_name = qualified_name_for from_mod, const_name
path_suffix = qualified_name.underscore
file_path = search_for_file(path_suffix)
if file_path
expanded = File.expand_path(file_path)
expanded.sub!(/\.rb\z/, "".freeze)
if loading.include?(expanded)
raise "Circular dependency detected while autoloading constant #{qualified_name}"
else
require_or_load(expanded, qualified_name)
raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
return from_mod.const_get(const_name)
end
elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
return mod
elsif (parent = from_mod.parent) && parent != from_mod &&
! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
return parent.const_missing(const_name)
rescue NameError => e
raise unless e.missing_name? qualified_name_for(parent, const_name)
end
end
name_error = NameError.new("uninitialized constant #{qualified_name}", const_name)
name_error.set_backtrace(caller.reject { |l| l.starts_with? __FILE__ })
raise name_error
end
# Remove the constants that have been autoloaded, and those that have been
# marked for unloading. Before each constant is removed a callback is sent
# to its class/module if it implements +before_remove_const+.
#
# The callback implementation should be restricted to cleaning up caches, etc.
# as the environment will be in an inconsistent state, e.g. other constants
# may have already been unloaded and not accessible.
def remove_unloadable_constants!
autoloaded_constants.each { |const| remove_constant const }
autoloaded_constants.clear
Reference.clear!
explicitly_unloadable_constants.each { |const| remove_constant const }
end
class ClassCache
def initialize
#store = Concurrent::Map.new
end
def empty?
#store.empty?
end
def key?(key)
#store.key?(key)
end
def get(key)
key = key.name if key.respond_to?(:name)
#store[key] ||= Inflector.constantize(key)
end
alias :[] :get
def safe_get(key)
key = key.name if key.respond_to?(:name)
#store[key] ||= Inflector.safe_constantize(key)
end
def store(klass)
return self unless klass.respond_to?(:name)
raise(ArgumentError, "anonymous classes cannot be cached") if klass.name.empty?
#store[klass.name] = klass
self
end
def clear!
#store.clear
end
end
Reference = ClassCache.new
# Store a reference to a class +klass+.
def reference(klass)
Reference.store klass
end
# Get the reference for class named +name+.
# Raises an exception if referenced class does not exist.
def constantize(name)
Reference.get(name)
end
# Get the reference for class named +name+ if one exists.
# Otherwise returns +nil+.
def safe_constantize(name)
Reference.safe_get(name)
end
# Determine if the given constant has been automatically loaded.
def autoloaded?(desc)
return false if desc.is_a?(Module) && desc.anonymous?
name = to_constant_name desc
return false unless qualified_const_defined?(name)
return autoloaded_constants.include?(name)
end
# Will the provided constant descriptor be unloaded?
def will_unload?(const_desc)
autoloaded?(const_desc) ||
explicitly_unloadable_constants.include?(to_constant_name(const_desc))
end
# Mark the provided constant name for unloading. This constant will be
# unloaded on each request, not just the next one.
def mark_for_unload(const_desc)
name = to_constant_name const_desc
if explicitly_unloadable_constants.include? name
false
else
explicitly_unloadable_constants << name
true
end
end
# Run the provided block and detect the new constants that were loaded during
# its execution. Constants may only be regarded as 'new' once -- so if the
# block calls +new_constants_in+ again, then the constants defined within the
# inner call will not be reported in this one.
#
# If the provided block does not run to completion, and instead raises an
# exception, any new constants are regarded as being only partially defined
# and will be removed immediately.
def new_constants_in(*descs)
constant_watch_stack.watch_namespaces(descs)
success = false
begin
yield # Now yield to the code that is to define new constants.
success = true
ensure
new_constants = constant_watch_stack.new_constants
return new_constants if success
# Remove partially loaded constants.
new_constants.each { |c| remove_constant(c) }
end
end
# Convert the provided const desc to a qualified constant name (as a string).
# A module, class, symbol, or string may be provided.
def to_constant_name(desc) #:nodoc:
case desc
when String then desc.sub(/^::/, "")
when Symbol then desc.to_s
when Module
desc.name ||
raise(ArgumentError, "Anonymous modules have no name to be referenced by")
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
end
end
def remove_constant(const) #:nodoc:
# Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
normalized = const.to_s.sub(/\A::/, "")
normalized.sub!(/\A(Object::)+/, "")
constants = normalized.split("::")
to_remove = constants.pop
# Remove the file path from the loaded list.
file_path = search_for_file(const.underscore)
if file_path
expanded = File.expand_path(file_path)
expanded.sub!(/\.rb\z/, "")
loaded.delete(expanded)
end
if constants.empty?
parent = Object
else
parent_name = constants.join("::")
return unless qualified_const_defined?(parent_name)
parent = constantize(parent_name)
end
# In an autoloaded user.rb like this
#
# autoload :Foo, 'foo'
#
# class User < ActiveRecord::Base
# end
#
# we correctly register "Foo" as being autoloaded. But if the app does
# not use the "Foo" constant we need to be careful not to trigger
# loading "foo.rb" ourselves. While #const_defined? and #const_get? do
# require the file, #autoload? and #remove_const don't.
#
# We are going to remove the constant nonetheless ---which exists as
# far as Ruby is concerned--- because if the user removes the macro
# call from a class or module that were not autoloaded, as in the
# example above with Object, accessing to that constant must err.
unless parent.autoload?(to_remove)
begin
constantized = parent.const_get(to_remove, false)
rescue NameError
# The constant is no longer reachable, just skip it.
return
else
constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
end
end
begin
parent.instance_eval { remove_const to_remove }
rescue NameError
# The constant is no longer reachable, just skip it.
end
end
end
end
ActiveSupport::Dependencies.hook!
Any tips abut it?
thank you all.
Where do you install libraries ? Try following procedure before running Rails, please.
Remove local libraries and re-install
$ rm -rf ./vendor/bundle
$ bundle install --path ./vendor/bundle
$ bundle exec rails server
I've been playing around with Rails for some time. But now I am attempting to build a ruby gem. And I am using rubymine which builds a gem template for you. In my case it looks like this:
$ ls
bin Gemfile lib Rakefile test
binarytree.gemspec Gemfile.lock LICENSE.txt README.md
merlino#johnmerlino:~/Documents/github/binarytree$
Inside the lib directory, I have a file called binarytree.rb, which contains the following contents:
require "binarytree/version"
module Binarytree
class BinaryNode
attr_accessor :value, :left, :right
def initialize(value=nil)
#value = value
#left = nil
#right = nil
end
def add(value)
if value <= #value
if #left
#left.add value
else
#left = BinaryNode.new value
end
else
if #right
#right.add value
else
#right = BinaryNode.new value
end
end
end
end
class BinaryTree
attr_accessor :root
def initialize
#root = nil
end
def add(value)
if !#root
#root = BinaryNode.new value
else
#root.add value
end
end
def contains(value)
node = #root
while node
if value == node.value
return true
elsif value < node.value
node = node.left
else
node = node.right
end
end
false
end
end
end
What I want to be able to do is run an irb (interactive ruby shell) session, and then be able to require 'binarytree' and have this code inside scope of irb, so I could start playing with it e.g. BinaryTree.new.
Right now I am not sure how to require this in irb:
require 'binarytree'
LoadError: cannot load such file -- binarytree
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in require'
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:inrequire'
from (irb):1
from /home/merlino/.rvm/rubies/ruby-2.0.0-p0/bin/irb:13:in `'
I am on Ubuntu and I am using rvm to manage gems.
Any ideas?
You have two options:
Go into catalog of your gem and run require './lib/binarytree.rb'
Run rake install inside catalog of your gem - this will build and install this gem into system gems.
I got it working the following way:
1) You first need to edit the gemspec:
binarytree.gemspec
And edit the description and summary lines as so:
spec.description = "binary tree"
spec.summary = "binary tree summary"
Otherwise you will get the following error:
gem build doctor_toons.gemspec
ERROR: While executing gem ... (Gem::InvalidSpecificationException)
"FIXME" or "TODO" is not a description
2) Then run the gemspec as so:
gem build binarytree.gemspec
This should output something that looks like this:
binarytree-0.0.1.gem
3) Now if you are using rvm, make sure you are using the version you want, and run the following:
gem install ./binarytree-0.0.1.gem
The output should look something like this:
Successfully installed binarytree-0.0.1
Parsing documentation for binarytree-0.0.1
Installing ri documentation for binarytree-0.0.1
Done installing documentation for binarytree after 0 seconds
Done installing documentation for binarytree (0 sec).
1 gem installed
4) Then launch irb and require the new gem:
irb(main):001:0> require 'binarytree'
When I run rspec tests via rake task I get
1) Whois::Record::Parser::WhoisUa status_available.expected#created_on
Failure/Error: lambda { #parser.created_on }.should raise_error(Whois::PropertyNotSupported)
But my status_available_spec.rb looks like this:
# encoding: utf-8
# This file is autogenerated. Do not edit it manually.
# If you want change the content of this file, edit
#
# /spec/fixtures/responses/whois.ua/status_available.expected
#
# and regenerate the tests with the following rake task
#
# $ rake spec:generate
#
require 'spec_helper'
require 'whois/record/parser/whois.ua.rb'
describe Whois::Record::Parser::WhoisUa, "status_available.expected" do
before(:each) do
file = fixture("responses", "whois.ua/status_available.txt")
part = Whois::Record::Part.new(:body => File.read(file))
#parser = klass.new(part)
end
describe "#status" do
it do
#parser.status.should == :available
end
end
describe "#available?" do
it do
#parser.available?.should == true
end
end
describe "#registered?" do
it do
#parser.registered?.should == false
end
end
describe "#created_on" do
it do
#parser.created_on.should == nil
end
end
describe "#updated_on" do
it do
#parser.updated_on.should == nil
end
end
describe "#expires_on" do
it do
#parser.expires_on.should == nil
end
end
describe "#nameservers" do
it do
#parser.nameservers.should be_a(Array)
#parser.nameservers.should == []
end
end
end
and as you can see there is no .should raise_error(Whois::PropertyNotSupported) instead it was changed to .should == nil.
Is rake caching that stuff or what?