I am trying to use optionparse of ruby to parse the arguments to my ruby script. Problem is when I am running the script like this
bundler exec ruby generation.rb --help
I am getting error
"uninitialized constant OpenStruct (NameError)"
I believe since I am running the script using bundle exec I should not be getting this error. What am I doing wrong.
require 'optparse'
def parse(args)
options = OpenStruct.new
options.dir = '../somerepo'
opts = OptionParser.new do |opts|
opts.banner = "Usage: generation.rb [options]"
opts.separator ""
opts.separator "Options:"
opts.on("--temp c_name", "abcddd") { |abc|
options.temp = abc
}
opts.separator ""
opts.on_tail("-h", "--help", "Show this message") {
puts opts
exit
}
opts.parse!(args)
return options
end
end
inputOpts = parse(ARGV)
You should require OpenStruct source manually:
require 'ostruct'
Related
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
I have a tool that I'm updating and need to have an argument require another argument, for example:
require 'optparse'
OPTIONS = {}
OptionParser.new do |opts|
opts.on('-t', '--type INPUT', String, 'Verify a type'){ |o| OPTIONS[:type] = o }
end.parse!
def help_page
puts 'ruby test.rb -t dev'
end
def gather_type
case OPTIONS[:type]
when /dev/
unlock(OPTIONS[:type])
else
help_page
end
end
def unlock(type)
if type == 'unlock' #Find out what type by passing argument another argument
puts 'Unlock account'
else
puts 'Reset account'
end
end
def start
case
when OPTIONS[:type]
gather_type
else
help_page
end
end
start
When this is run you get the following:
C:\Users\bin\ruby>ruby test.rb -t dev=unlock
Reset account
C:\Users\bin\ruby>ruby test.rb -t dev=reset
Reset account
Now that's all well and dandy but what I want to do is give the dev part an argument and go from there to decide if it's an unlock or if it's a reset:
ruby test.rb -t dev=unlock OR ruby test.rb -t dev=reset
After that I want the unlock(type) method to determine what argument was given to the flags argument and output the correct information, so
C:\Users\bin\ruby>ruby test.rb -t dev=unlock
Unlock account
C:\Users\bin\ruby>ruby test.rb -t dev=reset
Reset account
How can I go about to determine if an argument was given to the argument of the flag?
I figured out that if you put an options in parenthesis you can get what I'm asking:
require 'optparse'
OPTIONS = {}
OptionParser.new do |opts|
opts.on('-t', '--type INPUT[=INPUT]', String, 'Verify a type'){ |o| OPTIONS[:type] = o }
end.parse!
def help_page
puts 'ruby test.rb -t dev'
end
def gather_type
case OPTIONS[:type]
when /dev/
unlock(OPTIONS[:type])
else
help_page
end
end
def unlock(type)
if type =~ /unlock/ #Find out what type by passing argument another argument
puts 'Unlock account'
elsif type =~ /reset/
puts 'Reset account'
else
puts 'No flag given defaulting to unlock'
end
end
def start
case
when OPTIONS[:type]
gather_type
else
help_page
end
end
start
C:\Users\bin\ruby>ruby test.rb -t dev
No flag given defaulting to unlock
C:\Users\bin\ruby>ruby test.rb -t dev=unlock
Unlock account
C:\Users\bin\ruby>ruby test.rb -t dev=reset
Reset account
Issue: I have researched online on how to verify if text exists on my page, but I keep getting error messages. I have attempted using "expect" and one without "expect". For something that seems basic, I am not sure why this is not asserting correctly.
Ruby File:
require "rubygems"
require "watir-webdriver"
require "rspec"
require "selenium-webdriver"
require "rspec/expectations"
#browser = Watir::Browser.new :internet_explorer
begin
if expect(#browser.text.include?("Welcome")).to be_true
##browser.text.include?("Welcome").should == true
puts "Test passed!"
else
puts "Test failed!"
end
end
Error:
test2.rb:61:in <main>': undefined methodexpect' for main:Object (NoMethodError)
You should have your expectations defined inside a test case
describe "IE" do
it "should have test 'Welcome'" do
expect(#browser.text.include("Welcome")).to be_true
end
end
Or if you just want your script to print pass or fail, just do
begin
if #browser.text.include?("Welcome")
puts "Test passed!"
else
puts "Test failed!"
end
end
"Minimal example" of OptionParser from http://ruby-doc.org/stdlib-2.1.5/libdoc/optparse/rdoc/OptionParser.html:
require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV
Main questions:
What exactly is the content of opts there? Is it the new OptionParser instance, or is it all of the /-\w/ or /--\w+/-looking things passed to the script? As a corollary, is that do block a loop or not?
What does parse! do? Why is it called on the whole do block?
Also wondering:
What is the OptionParser#banner method? In what context would you see that text?
In what context would you see the third parameter passed to OptionParser in that example, that little description of the flag's effect?
How can you create a custom error message if the script is run with an unknown option?
opts is just the new instance of OptionParser. The block supplied to .new is run with this line:
yield self if block_given?
parse! is the same thing as parse but it is destructive, meaning that it will remove used switches from ARGV. It is called on the entire do ... end block because the value returned is the new OptionParser instance.
banner gets the heading of the summary, which can be set with opts.banner = "foo"
The description is shown when the help is displayed (-h flag):
Usage: example.rb [options]
-v, --[no-]verbose Run verbosely
You could rescue the OptionParser::InvalidOption exception:
parser = OptionParser.new ...
begin
parser.parse!
rescue OptionParser::InvalidOption
puts 'Invalid args!'
end
I have tried :
#CONF[:PROMPT_MODE] = :SIMPLE
but it does not change my prompt. I am using rvm and ruby 1.9.2 Linux.
#!/usr/bin/env ruby
# encoding: utf-8
require 'irb'
module IRB # :nodoc:
def self.start_session(binding)
unless #__initialized
args = ARGV
ARGV.replace(ARGV.dup)
IRB.setup(nil)
ARGV.replace(args)
#__initialized = true
end
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
#CONF[:IRB_RC].call(irb.context) if #CONF[:IRB_RC]
#CONF[:MAIN_CONTEXT] = irb.context
#CONF[:AUTO_INDENT] = true
#CONF[:PROMPT_MODE] = :SIMPLE
catch(:IRB_EXIT) do
irb.eval_input
end
end
end
IRB.start_session(binding)
The configuration assignment:
#CONF[:PROMPT_MODE] = :SIMPLE
needs to come before creating the Irb object:
irb = Irb.new(workspace)
I am not sure how early the other settings have to be done, but in general it's better to do this as soon as possible. The code below has these modifications.
#!/usr/bin/env rub
# encoding: utf-8
require 'irb'
module IRB # :nodoc:
def self.start_session(binding)
unless #__initialized
args = ARGV
ARGV.replace(ARGV.dup)
IRB.setup(nil)
ARGV.replace(args)
#__initialized = true
end
#CONF[:IRB_RC].call(irb.context) if #CONF[:IRB_RC]
#CONF[:AUTO_INDENT] = true
#CONF[:PROMPT_MODE] = :SIMPLE
IRB.run_config
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
#CONF[:MAIN_CONTEXT] = irb.context
catch(:IRB_EXIT) do
irb.eval_input
end
end
end
IRB.start_session(binding)
Sorry, I didn't see this sooner.