diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 220b740a3..713e6b6ec 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,35 +1,23 @@
-# This configuration was generated by `rubocop --auto-gen-config`
-# on 2015-03-06 13:49:50 +0100 using RuboCop version 0.28.0.
+# This configuration was generated by
+# `rubocop --auto-gen-config`
+# on 2015-10-25 15:59:02 -0700 using RuboCop version 0.34.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 499
+# Offense count: 804
# Configuration parameters: AllowURI, URISchemes.
Metrics/LineLength:
Max: 186
-# Offense count: 66
-# Configuration parameters: CountComments.
-Metrics/MethodLength:
- Max: 46
-
# Offense count: 2
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 7
-# Offense count: 9
-Metrics/PerceivedComplexity:
- Max: 16
-
# Offense count: 94
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
Style/DotPosition:
Enabled: false
-
-# Offense count: 1
-Style/DoubleNegation:
- Enabled: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 982149f78..2ca312a60 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
##### Enhancements
+* Add accessors for working with Environment Variables in xcscheme files
+ [Justin Martin](https://github.com/justinseanmartin)
+ [Xcodeproj#326](https://github.com/CocoaPods/Xcodeproj/pull/326)
+
* Add method to create new variant groups (groups for localized versions of the same file)
[Tim Bodeit](https://github.com/timbodeit)
[Xcodeproj#315](https://github.com/CocoaPods/Xcodeproj/pull/315)
diff --git a/lib/xcodeproj/constants.rb b/lib/xcodeproj/constants.rb
index d08d925cb..431f390d7 100644
--- a/lib/xcodeproj/constants.rb
+++ b/lib/xcodeproj/constants.rb
@@ -8,7 +8,7 @@ module Constants
# @return [String] The last known OS X SDK (stable).
#
- LAST_KNOWN_OSX_SDK = '10.11'
+ LAST_KNOWN_OSX_SDK = '10.11'
# @return [String] The last known tvOS SDK (stable).
LAST_KNOWN_TVOS_SDK = '9.0'
diff --git a/lib/xcodeproj/scheme/environment_variables.rb b/lib/xcodeproj/scheme/environment_variables.rb
new file mode 100644
index 000000000..f6858a9ec
--- /dev/null
+++ b/lib/xcodeproj/scheme/environment_variables.rb
@@ -0,0 +1,117 @@
+require 'xcodeproj/scheme/xml_element_wrapper'
+
+module Xcodeproj
+ class XCScheme
+ VARIABLES_NODE = 'EnvironmentVariables'
+ VARIABLE_NODE = 'EnvironmentVariable'
+
+ # This class wraps the EnvironmentVariables node of a .xcscheme XML file. This
+ # is just a container of EnvironmentVariable objects. It can either appear on a
+ # LaunchAction or TestAction scheme group.
+ #
+ class EnvironmentVariables < XMLElementWrapper
+ # @param [REXML::Element,Array{EnvironmentVariable},Array{Hash{String => String}}] node_or_target
+ # The 'EnvironmentVariables' XML node that this object represents.
+ # If nil, it will create a default XML node to use.
+ #
+ def initialize(node_or_target = nil)
+ create_xml_element_with_fallback(node_or_target, VARIABLES_NODE) do
+ @all_variables = []
+ node_or_target.each { |var| add_variable(var) } unless node_or_target.nil?
+ end
+ end
+
+ # @return [Array{EnvironmentVariable}]
+ # The key value pairs currently set in @xml_element
+ #
+ def all_variables
+ @all_variables ||= @xml_element.get_elements(VARIABLE_NODE).map { |variable| EnvironmentVariable.new(variable) }
+ end
+
+ # @param [EnvironmentVariable,Hash{String => String}] variable
+ # The key value pairs currently set in @xml_element
+ #
+ # @return [Array{EnvironmentVariable}]
+ # The new set of environment variables after addition
+ #
+ def add_variable(variable)
+ env_var = variable.is_a?(EnvironmentVariable) ? variable : EnvironmentVariable.new(variable)
+ all_variables.each { |existing_var| remove_variable(existing_var) if existing_var.key == env_var.key }
+ @xml_element.add_element(env_var.xml_element)
+ @all_variables << env_var
+ end
+
+ # @param [EnvironmentVariable,Hash{String => String}] variable
+ # The key value pairs currently set in @xml_element
+ #
+ # @return [Array{EnvironmentVariable}]
+ # The new set of environment variables after removal
+ #
+ def remove_variable(variable)
+ env_var = variable.is_a?(EnvironmentVariable) ? variable : all_variables.select { |var| var.key == variable[:key] }[0]
+ raise "Unexpected parameter type: #{env_var.class}" unless env_var.is_a?(EnvironmentVariable)
+ @xml_element.delete_element(env_var.xml_element)
+ @all_variables -= [env_var]
+ end
+
+ # @param [EnvironmentVariable,Hash{String => String}] variable
+ # The key value pairs currently set in @xml_element
+ #
+ def to_a
+ all_variables.map(&:to_h)
+ end
+ end
+
+ # This class wraps the EnvironmentVariable node of a .xcscheme XML file.
+ # Environment variables are accessible via the NSDictionary returned from
+ # [[NSProcessInfo processInfo] environment] in your app code.
+ #
+ class EnvironmentVariable < XMLElementWrapper
+ # @param [REXML::Element,EnvironmentVariable,Hash{String => String}] value
+ # The 'EnvironmentVariable' XML node that this object represents.
+ # If nil, it will create a default XML node to use. If a hash, it
+ # must contain keys 'key' and 'value', and optionally have 'enabled'.
+ # If not supplied, it will default to being enabled.
+ #
+ def initialize(value)
+ create_xml_element_with_fallback(value, VARIABLE_NODE) do
+ raise "Must pass a Hash with 'key' and 'value'!" unless value.is_a?(Hash) && value.key?(:key) && value.key?(:value)
+
+ @xml_element.attributes['key'] = value[:key]
+ @xml_element.attributes['value'] = value[:value]
+ @xml_element.attributes['isEnabled'] = value.key?(:enabled) ? bool_to_string(value[:enabled]) : bool_to_string(true)
+ end
+ end
+
+ def key
+ @xml_element.attributes['key']
+ end
+
+ def key=(key)
+ @xml_element.attributes['key'] = key
+ end
+
+ def value
+ @xml_element.attributes['value']
+ end
+
+ def value=(value)
+ @xml_element.attributes['value'] = value
+ end
+
+ def enabled
+ string_to_bool(@xml_element.attributes['isEnabled'])
+ end
+
+ def enabled=(enabled)
+ @xml_element.attributes['isEnabled'] = bool_to_string(enabled)
+ end
+
+ # @return [Hash{:key => String, :value => String, :enabled => Boolean}]
+ # The environment variable XML node with attributes converted to Hash keys
+ def to_h
+ { :key => key, :value => value, :enabled => enabled }
+ end
+ end
+ end
+end
diff --git a/lib/xcodeproj/scheme/launch_action.rb b/lib/xcodeproj/scheme/launch_action.rb
index 8427f3382..6e51502c9 100644
--- a/lib/xcodeproj/scheme/launch_action.rb
+++ b/lib/xcodeproj/scheme/launch_action.rb
@@ -62,6 +62,28 @@ def buildable_product_runnable=(runnable)
@xml_element.add_element(runnable.xml_element) if runnable
end
+ # @return [EnvironmentVariables]
+ # Returns the set of environment variables that are currently set at test runtime
+ # NOTE: If this creates a new node, it will not automatically be added to the xml document
+ #
+ def environment_variables
+ env_vars_nodes = @xml_element.get_elements(XCScheme::VARIABLES_NODE)
+ raise 'Unexpected number of EnvironmentVariables nodes found!' if env_vars_nodes.count > 1
+
+ env_vars_nodes.count == 0 ? nil : EnvironmentVariables.new(env_vars_nodes[0])
+ end
+
+ # @param [EnvironmentVariables] env_vars
+ # Overwrites the set of environment variables that should be set at test runtime
+ #
+ def environment_variables=(env_vars)
+ @xml_element.get_elements(XCScheme::VARIABLES_NODE).each { |node| node.parent.delete_element(node) }
+
+ raise "Unexpected parameter type: #{env_vars.class}" unless env_vars.nil? || env_vars.is_a?(EnvironmentVariables)
+ @xml_element.add_element(env_vars.xml_element) unless env_vars.nil?
+ environment_variables
+ end
+
# @todo handle 'AdditionalOptions' tag
end
end
diff --git a/lib/xcodeproj/scheme/test_action.rb b/lib/xcodeproj/scheme/test_action.rb
index f339a1360..01566c999 100644
--- a/lib/xcodeproj/scheme/test_action.rb
+++ b/lib/xcodeproj/scheme/test_action.rb
@@ -1,4 +1,5 @@
require 'xcodeproj/scheme/abstract_scheme_action'
+require 'xcodeproj/scheme/environment_variables'
module Xcodeproj
class XCScheme
@@ -84,6 +85,28 @@ def add_macro_expansion(macro_expansion)
@xml_element.add_element(macro_expansion.xml_element)
end
+ # @return [EnvironmentVariables]
+ # Returns the set of environment variables that are currently set at test runtime
+ # NOTE: If this creates a new node, it will not automatically be added to the xml document
+ #
+ def environment_variables
+ env_vars_nodes = @xml_element.get_elements(XCScheme::VARIABLES_NODE)
+ raise 'Unexpected number of EnvironmentVariables nodes found!' if env_vars_nodes.count > 1
+
+ env_vars_nodes.count == 0 ? nil : EnvironmentVariables.new(env_vars_nodes[0])
+ end
+
+ # @param [EnvironmentVariables] env_vars
+ # Overwrites the set of environment variables that should be set at test runtime
+ #
+ def environment_variables=(env_vars)
+ @xml_element.get_elements(XCScheme::VARIABLES_NODE).each { |node| node.parent.delete_element(node) }
+
+ raise "Unexpected parameter type: #{env_vars.class}" unless env_vars.nil? || env_vars.is_a?(EnvironmentVariables)
+ @xml_element.add_element(env_vars.xml_element) unless env_vars.nil?
+ environment_variables
+ end
+
#-------------------------------------------------------------------------#
class TestableReference < XMLElementWrapper
diff --git a/spec/fixtures/SharedSchemes/SharedSchemes.xcodeproj/xcshareddata/xcschemes/SharedSchemes.xcscheme b/spec/fixtures/SharedSchemes/SharedSchemes.xcodeproj/xcshareddata/xcschemes/SharedSchemes.xcscheme
index aa4abb0b3..15a103895 100644
--- a/spec/fixtures/SharedSchemes/SharedSchemes.xcodeproj/xcshareddata/xcschemes/SharedSchemes.xcscheme
+++ b/spec/fixtures/SharedSchemes/SharedSchemes.xcodeproj/xcshareddata/xcschemes/SharedSchemes.xcscheme
@@ -38,6 +38,18 @@
ReferencedContainer = "container:SharedSchemes.xcodeproj">
+
+
+
+
+
+
-
+
+
+
+
+
+
+
@@ -66,7 +91,8 @@
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
-
+
{ 'a hash' => 'in a hash' },
+ 'hash' => { 'a hash' => 'in a hash' },
'string' => 'string',
'true_bool' => '1',
'false_bool' => '0',
diff --git a/spec/scheme/environment_variables_spec.rb b/spec/scheme/environment_variables_spec.rb
new file mode 100644
index 000000000..0a34a069a
--- /dev/null
+++ b/spec/scheme/environment_variables_spec.rb
@@ -0,0 +1,230 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+module Xcodeproj
+ @xml_formatter = REXML::Formatters::Pretty.new(0)
+ @xml_formatter.compact = true
+
+ def self.xml_for_object(object)
+ xml_out = ''
+ @xml_formatter.write(object.xml_element, xml_out)
+ xml_out.lines.each(&:strip!).join('')
+ end
+
+ describe XCScheme::EnvironmentVariables do
+ describe '#initialize' do
+ describe 'creates a new EnvironmentVariable object' do
+ it 'when passed nothing' do
+ subject = XCScheme::EnvironmentVariables.new
+ Xcodeproj.xml_for_object(subject).should == ''
+ end
+
+ it 'when passed an array of hashes with key and value' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key', :value => 'value' }])
+ Xcodeproj.xml_for_object(subject).should ==
+ ""
+ end
+
+ it 'when passed an existing EnvironmentVariable XML node' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key', :value => 'value' }])
+ copy = XCScheme::EnvironmentVariables.new(subject.xml_element)
+ subject.should.not.be.same_as copy
+ Xcodeproj.xml_for_object(copy).should ==
+ ""
+ end
+
+ it 'when passed an array of XML nodes' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key', :value => 'value' }])
+ copy = XCScheme::EnvironmentVariables.new(subject.all_variables)
+ Xcodeproj.xml_for_object(copy).should ==
+ ""
+ end
+ end
+ end
+
+ describe '#all_variables' do
+ it 'returns an empty array' do
+ subject = XCScheme::EnvironmentVariables.new
+ subject.all_variables.should == []
+ end
+
+ it 'returns all items, regardless of enabled state' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key1', :value => 'value1' },
+ { :key => 'key2', :value => 'value2', :enabled => false }])
+ subject.all_variables.count.should == 2
+ subject.all_variables.each { |var| var.should.is_a? XCScheme::EnvironmentVariable }
+ subject.all_variables[0].to_h.should == { :key => 'key1', :value => 'value1', :enabled => true }
+ subject.all_variables[1].to_h.should == { :key => 'key2', :value => 'value2', :enabled => false }
+ end
+ end
+
+ describe '#add_variable' do
+ it 'adds a new environment variable by Hash' do
+ subject = XCScheme::EnvironmentVariables.new
+ subject.add_variable(:key => 'key1', :value => 'value1')
+
+ subject.all_variables.count.should == 1
+ subject.all_variables[0].to_h.should == { :key => 'key1', :value => 'value1', :enabled => true }
+ Xcodeproj.xml_for_object(subject).should ==
+ ""
+ end
+
+ it 'adds a new variable by object using the same object' do
+ subject = XCScheme::EnvironmentVariables.new
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key1', :value => 'value1')
+ subject.add_variable(new_var)
+
+ subject.all_variables.count.should == 1
+ subject.all_variables[0].to_h.should == { :key => 'key1', :value => 'value1', :enabled => true }
+ subject.all_variables[0].should.equal?(new_var)
+ end
+
+ it 'adds a new variable by node using the same xml_element' do
+ subject = XCScheme::EnvironmentVariables.new
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key1', :value => 'value1')
+ subject.add_variable(new_var.xml_element)
+
+ subject.all_variables.count.should == 1
+ subject.all_variables[0].to_h.should == { :key => 'key1', :value => 'value1', :enabled => true }
+ subject.all_variables[0].xml_element.should.equal?(new_var.xml_element)
+ end
+
+ it 'merges in a new entry if a matching key does not exist' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ subject.add_variable(:key => 'key2', :value => 'value2')
+ subject.to_a.should == [{ :key => 'key1', :value => 'value1', :enabled => true },
+ { :key => 'key2', :value => 'value2', :enabled => true }]
+ end
+
+ it 'updates an existing variable value if one already exists with that key' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ subject.add_variable(:key => 'key1', :value => 'value3')
+ subject.to_a.should == [:key => 'key1', :value => 'value3', :enabled => true]
+ end
+
+ it 'updates an existing variable enabled state if one already exists with that key' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key1', :value => 'value1' },
+ { :key => 'key2', :value => 'value2', :enabled => false }])
+ subject.add_variable(:key => 'key1', :value => 'value1', :enabled => false)
+ subject.add_variable(:key => 'key2', :value => 'value2')
+
+ subject.to_a.should == [{ :key => 'key1', :value => 'value1', :enabled => false },
+ { :key => 'key2', :value => 'value2', :enabled => true }]
+ end
+ end
+
+ describe '#remove_variable' do
+ it 'returns the new set of environment variables after removal' do
+ subject = XCScheme::EnvironmentVariables.new([{ :key => 'key1', :value => 'value1' },
+ { :key => 'key2', :value => 'value2' }])
+ subject.remove_variable(:key => 'key1')[0].to_h.should == { :key => 'key2', :value => 'value2', :enabled => true }
+ subject.to_a.should == [:key => 'key2', :value => 'value2', :enabled => true]
+ Xcodeproj.xml_for_object(subject).should ==
+ ""
+ end
+
+ it 'removes an existing entry with same EnvironmentVariable object' do
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key1', :value => 'value1')
+ subject = XCScheme::EnvironmentVariables.new([new_var])
+ subject.remove_variable(new_var)
+ subject.to_a.should == []
+ Xcodeproj.xml_for_object(subject).should == ''
+ end
+
+ it 'removes an existing entry with matching EnvironmentVariable object' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ subject.remove_variable(:key => 'key1')
+ subject.to_a.should == []
+ end
+
+ it 'does nothing if the the EnvironmentVariable isn\'t in all' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key2', :value => 'value2')
+ subject.remove_variable(new_var)
+ subject.to_a.should == [:key => 'key1', :value => 'value1', :enabled => true]
+ end
+
+ it 'does nothing if the variable does not exist' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key2', :value => 'value2')
+ subject.remove_variable(new_var)
+ subject.to_a.should == [:key => 'key1', :value => 'value1', :enabled => true]
+ end
+
+ it 'does nothing if the enabled state does not match' do
+ subject = XCScheme::EnvironmentVariables.new([:key => 'key1', :value => 'value1'])
+ new_var = XCScheme::EnvironmentVariable.new(:key => 'key1', :value => 'value2')
+ new_var2 = XCScheme::EnvironmentVariable.new(:key => 'key1', :value => 'value1', :enabled => true)
+ subject.remove_variable(new_var)
+ subject.remove_variable(new_var2)
+ subject.to_a.should == [:key => 'key1', :value => 'value1', :enabled => true]
+ end
+ end
+ end
+
+ describe XCScheme::EnvironmentVariable do
+ describe '#initialize' do
+ describe 'raises an initialization error nil' do
+ init_exception = /Must pass a Hash with 'key' and 'value'!/
+
+ it 'when passed nil' do
+ lambda { XCScheme::EnvironmentVariable.new(nil) }.should.raise(RuntimeError).message
+ .should.match(init_exception)
+ end
+
+ it 'when Hash is empty' do
+ lambda { XCScheme::EnvironmentVariable.new({}) }.should.raise(RuntimeError).message
+ .should.match(init_exception)
+ end
+
+ it 'when Hash is missing key' do
+ lambda { XCScheme::EnvironmentVariable.new(:value => 'value') }.should.raise(RuntimeError)
+ .message.should.match(init_exception)
+ end
+
+ it 'when Hash is missing value' do
+ lambda { XCScheme::EnvironmentVariable.new(:key => 'key') }.should.raise(RuntimeError)
+ .message.should.match(init_exception)
+ end
+ end
+
+ describe 'creates a new EnvironmentVariable object' do
+ it 'when passed an array of hashes with key and value' do
+ subject = XCScheme::EnvironmentVariable.new(:key => 'key', :value => 'value')
+ Xcodeproj.xml_for_object(subject).should == ""
+ end
+
+ it 'when passed an array of hashes with key, value and enabled state' do
+ subject = XCScheme::EnvironmentVariable.new(:key => 'key', :value => 'value', :enabled => false)
+ Xcodeproj.xml_for_object(subject).should == ""
+ end
+
+ it 'when passed an XML node' do
+ var = XCScheme::EnvironmentVariable.new(:key => 'copykey', :value => 'copyvalue')
+ subject = XCScheme::EnvironmentVariable.new(var.xml_element)
+ Xcodeproj.xml_for_object(subject).should == ""
+ Xcodeproj.xml_for_object(subject).should == Xcodeproj.xml_for_object(var)
+ subject.should.not.equal?(var)
+ end
+ end
+
+ describe 'EnvironmentVariable accessors return values from the XML' do
+ subject = XCScheme::EnvironmentVariable.new(:key => 'key', :value => 'value', :enabled => false)
+ subject.key.should == 'key'
+ subject.value.should == 'value'
+ subject.enabled.should == false
+ end
+
+ describe 'EnvironmentVariable modifiers mutate the XML' do
+ subject = XCScheme::EnvironmentVariable.new(:key => 'key', :value => 'value')
+ Xcodeproj.xml_for_object(subject).should == ""
+ before_modifiers = subject.xml_element
+
+ subject.key = 'key2'
+ subject.value = 'value2'
+ subject.enabled = false
+ Xcodeproj.xml_for_object(subject).should == ""
+ subject.should.equal?(before_modifiers)
+ end
+ end
+ end
+end
diff --git a/spec/scheme/launch_action_spec.rb b/spec/scheme/launch_action_spec.rb
index 78da97463..70237f0e5 100644
--- a/spec/scheme/launch_action_spec.rb
+++ b/spec/scheme/launch_action_spec.rb
@@ -55,6 +55,65 @@ module Xcodeproj
@sut.xml_element.elements['BuildableProductRunnable'].should == bpr.xml_element
end
end
+
+ describe '#environment_variables' do
+ vars_node_name = XCScheme::VARIABLES_NODE
+ var_node_name = XCScheme::VARIABLE_NODE
+
+ it 'starts as nil if no xml exists' do
+ @sut.xml_element.elements[vars_node_name].should.equal nil
+ @sut.environment_variables.should.equal nil
+ end
+
+ it 'picks up an existing node if exists in the XML' do
+ env_vars_xml = @sut.xml_element.add_element(vars_node_name)
+ env_vars_xml.add_element(var_node_name, 'isEnabled' => 'YES', 'key' => 'a', 'value' => '1')
+ env_vars_xml.add_element(var_node_name, 'isEnabled' => 'NO', 'key' => 'b', 'value' => '2')
+
+ # Reload content from XML
+ @sut = XCScheme::LaunchAction.new(@sut.xml_element)
+
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => true },
+ { :key => 'b', :value => '2', :enabled => false }]
+ end
+
+ it 'reflects direct changes to xml' do
+ @sut.environment_variables = XCScheme::EnvironmentVariables.new([{ :key => 'a', :value => '1', :enabled => false },
+ { :key => 'b', :value => '2', :enabled => true },
+ { :key => 'c', :value => '3', :enabled => true }])
+ node_to_delete = @sut.environment_variables.xml_element.elements["#{var_node_name}[@key='b']"]
+ @sut.environment_variables.xml_element.delete(node_to_delete)
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => false },
+ { :key => 'c', :value => '3', :enabled => true }]
+ end
+
+ it 'can be assigned nil' do
+ @sut.xml_element.get_elements(vars_node_name).count.should == 0
+
+ @sut.environment_variables = XCScheme::EnvironmentVariables.new
+ @sut.environment_variables.should.not.equal nil
+ @sut.xml_element.get_elements(vars_node_name).count.should == 1
+
+ @sut.environment_variables = nil
+ @sut.environment_variables.should.equal nil
+ @sut.xml_element.get_elements(vars_node_name).count.should == 0
+ end
+
+ it 'assigning an EnvironmentVariables object updates the xml' do
+ env_var = Xcodeproj::XCScheme::EnvironmentVariables.new([{ :key => 'a', :value => '1' }])
+ env_var.xml_element.elements.count.should == 1
+
+ @sut.environment_variables = env_var
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => true }]
+ @sut.environment_variables.xml_element.should == env_var.xml_element
+
+ xml_out = ''
+ xml_formatter = REXML::Formatters::Pretty.new(0)
+ xml_formatter.compact = true
+ xml_formatter.write(@sut.environment_variables.xml_element, xml_out)
+ xml_out.should == "\n\n"
+ end
+ end
end
end
end
diff --git a/spec/scheme/test_action_spec.rb b/spec/scheme/test_action_spec.rb
index 48c376855..984302c56 100644
--- a/spec/scheme/test_action_spec.rb
+++ b/spec/scheme/test_action_spec.rb
@@ -83,6 +83,7 @@ module Xcodeproj
it '#add_macro_expansion' do
project = Xcodeproj::Project.new('/foo/bar/baz.xcodeproj')
+ @sut.xml_element.add_element('Testables')
target1 = project.new_target(:application, 'FooApp', :ios)
macro1 = XCScheme::MacroExpansion.new(target1)
@@ -96,6 +97,65 @@ module Xcodeproj
@sut.xml_element.elements['MacroExpansion[1]'].should == macro1.xml_element
@sut.xml_element.elements['MacroExpansion[2]'].should == macro2.xml_element
end
+
+ describe '#environment_variables' do
+ vars_node_name = XCScheme::VARIABLES_NODE
+ var_node_name = XCScheme::VARIABLE_NODE
+
+ it 'starts as nil if no xml exists' do
+ @sut.xml_element.elements[vars_node_name].should.equal nil
+ @sut.environment_variables.should.equal nil
+ end
+
+ it 'picks up an existing node if exists in the XML' do
+ env_vars_xml = @sut.xml_element.add_element(vars_node_name)
+ env_vars_xml.add_element(var_node_name, 'isEnabled' => 'YES', 'key' => 'a', 'value' => '1')
+ env_vars_xml.add_element(var_node_name, 'isEnabled' => 'NO', 'key' => 'b', 'value' => '2')
+
+ # Reload content from XML
+ @sut = XCScheme::TestAction.new(@sut.xml_element)
+
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => true },
+ { :key => 'b', :value => '2', :enabled => false }]
+ end
+
+ it 'reflects direct changes to xml' do
+ @sut.environment_variables = XCScheme::EnvironmentVariables.new([{ :key => 'a', :value => '1', :enabled => false },
+ { :key => 'b', :value => '2', :enabled => true },
+ { :key => 'c', :value => '3', :enabled => true }])
+ node_to_delete = @sut.environment_variables.xml_element.elements["#{var_node_name}[@key='b']"]
+ @sut.environment_variables.xml_element.delete(node_to_delete)
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => false },
+ { :key => 'c', :value => '3', :enabled => true }]
+ end
+
+ it 'can be assigned nil' do
+ @sut.xml_element.get_elements(vars_node_name).count.should == 0
+
+ @sut.environment_variables = XCScheme::EnvironmentVariables.new
+ @sut.environment_variables.should.not.equal nil
+ @sut.xml_element.get_elements(vars_node_name).count.should == 1
+
+ @sut.environment_variables = nil
+ @sut.environment_variables.should.equal nil
+ @sut.xml_element.get_elements(vars_node_name).count.should == 0
+ end
+
+ it 'assigning an EnvironmentVariables object updates the xml' do
+ env_var = Xcodeproj::XCScheme::EnvironmentVariables.new([{ :key => 'a', :value => '1' }])
+ env_var.xml_element.elements.count.should == 1
+
+ @sut.environment_variables = env_var
+ @sut.environment_variables.to_a.should == [{ :key => 'a', :value => '1', :enabled => true }]
+ @sut.environment_variables.xml_element.should == env_var.xml_element
+
+ xml_out = ''
+ xml_formatter = REXML::Formatters::Pretty.new(0)
+ xml_formatter.compact = true
+ xml_formatter.write(@sut.environment_variables.xml_element, xml_out)
+ xml_out.should == "\n\n"
+ end
+ end
end
describe XCScheme::TestAction::TestableReference do
diff --git a/spec/scheme_spec.rb b/spec/scheme_spec.rb
index 905c46e46..faa22d033 100644
--- a/spec/scheme_spec.rb
+++ b/spec/scheme_spec.rb
@@ -55,6 +55,10 @@ module ProjectSpecs
ref.target_uuid.should == '632143E8175736EE0038D40D'
ref.buildable_name.should == 'SharedSchemes.app'
ref.target_referenced_container.should == 'container:SharedSchemes.xcodeproj'
+
+ @scheme.test_action.environment_variables.to_a.should ==
+ [{ :key => 'testkey', :value => 'testval', :enabled => true },
+ { :key => 'testkeydisabled', :value => 'testvaldisabled', :enabled => false }]
end
it 'Properly map the scheme\'s LaunchAction' do
@@ -69,6 +73,10 @@ module ProjectSpecs
ref.target_uuid.should == '632143E8175736EE0038D40D'
ref.buildable_name.should == 'SharedSchemes.app'
ref.target_referenced_container.should == 'container:SharedSchemes.xcodeproj'
+
+ @scheme.launch_action.environment_variables.to_a.should ==
+ [{ :key => 'launchkey', :value => 'launchval', :enabled => true },
+ { :key => 'launchkeydisabled', :value => 'launchvaldisabled', :enabled => false }]
end
it 'Properly map the scheme\'s ProfileAction' do