How to remove a group from Xcode project programmatically? - xcode

I need to manage an Xcode project from a batch process, partially remove certain groups.
As I understand, the only tool is xcodeproj. Or writing own pbxproj file parser.
So I have installed xcodeproj.
First of all, there is no reasonable documentation, that one that is new to it could understand it easily. I assume I need to write some rb file. And execute it as ruby xcodeproj_batch.rb
Here is what I have done. But this does not work. This script finds the needed group but it does not delete it.
xcodeproj_batch.rb:
require 'rubygems'
require 'xcodeproj'
project_path = '../TestProject/TestProject.xcodeproj'
project = Xcodeproj::Project.open(project_path)
groupToDelete = Xcodeproj::Project::PBXGroup
project.groups.each do |group|
if group.name == 'Test'
groupToDelete = group
puts 'cleared: '+group.name
groupToDelete.clear
end
end
project.groups.delete(groupToDelete)
project.save(project_path)
I assume this script has errors. I don't have xcodeproj and ruby background. I'm trying here to remove the group in two different ways. What am I missing?

I have found the problem, I needed to use remove_from_project and not clear:
require 'rubygems'
require 'xcodeproj'
project_path = '../TestProject/TestProject.xcodeproj'
project = Xcodeproj::Project.open(project_path)
groupToDelete = nil
project.groups.each do |group|
if group.name == 'Test'
groupToDelete = group
puts 'cleared: '+group.name
# add break;
end
end
groupToDelete.remove_from_project
project.save(project_path)

Related

How do you use cucumber with zeus?

When I start up zeus, it does not offer zeus cucumber as one of the possible commands. Others seem to get this by default; At least I have seen a couple zeus write-ups that show the output from zeus start including zeus cucumber, and they don't say anything about that having been special or required extra configuration.
I don't really even know where to start to troubleshoot this; I have googled and searched here for "use cucumber with zeus." I get no setup discussions. The only results I get are from people who seem to take for granted that it should be there, and are investigating problems with it not functioning correctly.
You should use this custom plan file from Zeus. Save it as custom_plan.rb at the root of your application:
require 'zeus/rails'
# 1. Add the cucumber methods (below) to your custom plan (or take this file if
# you don't have an existing custom_plan).
#
# 2. Add the following line to the test_environment section of your zeus.json:
#
# "cucumber_environment": {"cucumber": []}
class CucumberPlan < Zeus::Rails
def cucumber_environment
::Rails.env = ENV['RAILS_ENV'] = 'test'
require 'cucumber/rspec/disable_option_parser'
require 'cucumber/cli/main'
#cucumber_runtime = Cucumber::Runtime.new
end
def cucumber(argv=ARGV)
cucumber_main = Cucumber::Cli::Main.new(argv.dup)
had_failures = cucumber_main.execute!(#cucumber_runtime)
exit_code = had_failures ? 1 : 0
exit exit_code
end
end
Zeus.plan = CucumberPlan.new

How do you open a zip file using watir-webdriver?

My test suite has a cucumber front end with a ruby backend, running the latest version of watir-webdriver and its dependencies atop the latest version of OSX. My cucumber environment is setup to execute in Firefox.
The export feature of our app creates a zip file but to test the import feature, I need the contents of the zip file.
My actual test needs to unpack that zip file and select the individual files in it for use in testing the import feature of our web application.
Can anyone point me to a reference that can help me figure out how to write that?
Based off my experience, you download this file the same way that a normal user might. So first off, you just click the download button or whatever and then can access the file wherever it is and check out its contents.
Assuming the downloads just go to your Downloads folder by default, there is some simple code you can use to select the most recently downloaded item:
fn = Dir.glob("~/Downloads/*.zip").max { |a,b| File.ctime(a) <=> File.ctime(b)}
Then just use the unzip shell command to unzip the file. No reason to add another gem into the mix when you can just use generic shell commands.
`unzip #{fn}`
Then, you'd use Dir.glob again to get the filenames of everything inside the unzipped files folder. Assuming the file was named "thing.zip", you do this:
files = Dir.glob("~/Downloads/thing/*")
If you want to files to be downloaded directly to your project folder, you can try this. This also prevents the popup from asking you if you really want to save the file which is handy. I think this still works but haven't used it in some time. The above stuff works for sure though.
profile = Selenium::WebDriver::Firefox::Profile.new
download_dir = Dir.pwd + "/test_downloads"
profile['browser.download.dir'] = download_dir
profile['browser.helperApps.neverAsk.saveToDisk'] = "application/zip"
b = Watir::Browser.new. :firefox, :profile => profile
I ended up adding the rubyzip gem at https://github.com/rubyzip/rubyzip
the solution is on that link but i modified mine a little bit. I added the following to my common.rb file. see below:
require 'Zip'
def unpack_zip
test_home='/Users/yournamegoeshere/SRC/watir_testing/project files'
sleep(5) #<--manually making time to hit the save download dialog
zip_file_paths = []
Find.find(test_home) do |path|
zip_file_paths << path if path =~ /.*\.zip$/
end
file_name=zip_file_paths[0]
Zip::File.open(file_name) do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file/directory/symlink
puts "Extracting #{entry.name}"
entry.extract(test_home + "/" + entry.name)
# Read into memory
content = entry.get_input_stream.read
end
# Find specific entry
entry = zip_file.glob('*.csv').first
puts entry.get_input_stream.read
end
end
This solution works great!

include file to ruby testScript

I have multiple ruby test cases for selenium-webdriver and all the files are sharing the same user name and password to login to my account. Is there a way to create a global file and include that file in these test cases instead of typing them over and over again, something like #include?
Here is the part of the code that needs to be shared between other test cases:
def setup
#driver = Selenium::WebDriver.for :firefox
#base_url = "http://localhost:3000/"
#driver.manage.timeouts.implicit_wait = 30
#verification_errors = []
#facebook_ID = "xxxxxxxxxx#xxx.xxx"
#facebook_password = "xxxxxxx"
#facebook_receiver_friend = "John Smith"
end
There are multiple ways to do it.
You could use
require 'setup'
where setup.rb is the common file that has all the setting up variables/functions.
You could also use a YAML file. More information here. Where all your config attributes can be defined.
Also put this is at the top of the file $:.unshift '.' . This is so that your test file can "discover" your setup.rb file which is routable from the home directory.
Note - Even though you will save the file as setup.rb you will require as only setup.
I got my answer:
eval File.open('setup.dat').read
This will insert what I have in setup.dat as a text wherever I need it.

How to add a page to RDoc?

Noob here trying to figure out the simple task of adding a page to my RDoc documentation. If I do rake doc:app and view a page, then there is a sidebar that says "Pages" with README_FOR_APP listed. All I want to do is create a page named "Cheatsheet" that will appear under "Pages." How do I create a documentation page and tell RDoc to include the new page?
IMO it's a bit convoluted. Here's the references I used:
http://rake.rubyforge.org/classes/Rake/RDocTask.html
How to Rename or Move Rails's README_FOR_APP
Nutshell version:
Take the "app" task from your rails library directory, for example I tested using:
~/.rvm/gems/ruby-1.9.2-p0#foo/gems/railties-3.0.9/lib/rails/tasks/documentation.rake
The part you need looks (approximately) like this:
namespace :doc do
def gem_path(gem_name)
path = $LOAD_PATH.grep(/#{gem_name}[\w.-]*\/lib$/).first
yield File.dirname(path) if path
end
RDocTaskWithoutDescriptions.new("app2") { |rdoc|
rdoc.rdoc_dir = 'doc/app'
rdoc.template = ENV['template'] if ENV['template']
rdoc.title = ENV['title'] || "Rails Application Documentation"
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.options << '--charset' << 'utf-8'
rdoc.rdoc_files.include('doc/*_FOR_APP') # Modified this line
rdoc.rdoc_files.include('app/**/*.rb')
rdoc.rdoc_files.include('lib/**/*.rb')
}
end
Put this in your app's lib/tasks directory in a .rake file, e.g., doc2.rake.
Update the task name if you want to keep the original, e.g., "app2".
Update the "doc/README_FOR_APP" string to a wider pattern, or add new file(s) to process.
Create doc/Cheatsheet_FOR_APP and the new rake doc:app2 task will pick it up.

How to test a script that generates files

I am creating a Rubygem that will let me generate jekyll post files. One of the reasons I am developing this project is to learn TDD. This gem is strictly functional on the command line, and it has to make a series of checks to make sure that it finds the _posts directory. This depends on two things:
Wether or not a location option was passed
Is that location option valid?
A location option was not passed
Is the posts dir in the current directory?
Is the posts dir the current working directory?
At that point, I am really having a hard time testing that part of the application. So I have two questions:
is it acceptable/okay to skip tests for small parts of the application like the one described above?
If not, how do you test file manipulation in ruby using minitest?
Some projects I've seen implement their command line tools as Command objects (for example: Rubygems and my linebreak gem). These objects are initialized with the ARGV simply have a call or execute method which then starts the whole process. This enables these projects to put their command line applications into a virtual environment. They could, for example hold the input and output stream objects in instance variables of the command object to make the application independant of using STDOUT/STDIN. And thus, making it possible to test the input/output of the command line application. In the same way I imagine, you could hold your current working directory in an instance variable to make your command line application independent of your real working directory. You could then create a temporary directory for each test and set this one as the working directory for your Command object.
And now some code:
require 'pathname'
class MyCommand
attr_accessor :input, :output, :error, :working_dir
def initialize(options = {})
#input = options[:input] ? options[:input] : STDIN
#output = options[:output] ? options[:output] : STDOUT
#error = options[:error] ? options[:error] : STDERR
#working_dir = options[:working_dir] ? Pathname.new(options[:working_dir]) : Pathname.pwd
end
# Override the puts method to use the specified output stream
def puts(output = nil)
#output.puts(output)
end
def execute(arguments = ARGV)
# Change to the given working directory
Dir.chdir(working_dir) do
# Analyze the arguments
if arguments[0] == '--readfile'
posts_dir = Pathname.new('posts')
my_file = posts_dir + 'myfile'
puts my_file.read
end
end
end
end
# Start the command without mockups if the ruby script is called directly
if __FILE__ == $PROGRAM_NAME
MyCommand.new.execute
end
Now in your test's setup and teardown methods you could do:
require 'pathname'
require 'tmpdir'
require 'stringio'
def setup
#working_dir = Pathname.new(Dir.mktmpdir('mycommand'))
#output = StringIO.new
#error = StringIO.new
#command = MyCommand.new(:working_dir => #working_dir, :output => #output, :error => #error)
end
def test_some_stuff
#command.execute(['--readfile'])
# ...
end
def teardown
#working_dir.rmtree
end
(In the example I'm using Pathname, which is a really nice object oriented file system API from Ruby's standard library and StringIO, which is useful for for mocking STDOUT as it's an IO object which streams into a simple String)
In the acutal test you could now use the #working_dir variable to test for existence or content of files:
path = #working_dir + 'posts' + 'myfile'
path.exist?
path.file?
path.directory?
path.read == "abc\n"
From my experience (and thus this is VERY subjective), I think it's ok sometimes to skip unit testing in some areas which are difficult to test. You need to find out what you get in return and the cost for testing or not. My rule of thumb is that the decision to not test a class should be very unusual (around less than 1 in 300 classes)
If what you're trying to test is very difficult, because of the dependencies with the file system, I think you could try to extract all the bits that interact with the file system.

Resources