rox-rollout 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +45 -0
  3. data/.gitignore +8 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE +50 -0
  6. data/README_DEVELOP.md +19 -0
  7. data/Rakefile +16 -0
  8. data/_archive/.document +5 -0
  9. data/_archive/.rspec +1 -0
  10. data/_archive/Gemfile +15 -0
  11. data/_archive/Gemfile.lock +87 -0
  12. data/_archive/README.md +32 -0
  13. data/_archive/README.rdoc +19 -0
  14. data/_archive/Rakefile +50 -0
  15. data/_archive/lib/expr_function_definition.rb +52 -0
  16. data/_archive/lib/function_definition.rb +48 -0
  17. data/_archive/lib/function_token.rb +12 -0
  18. data/_archive/lib/object_extends.rb +12 -0
  19. data/_archive/lib/ruby_interpreter.rb +292 -0
  20. data/_archive/lib/stack.rb +48 -0
  21. data/_archive/lib/string_extends.rb +14 -0
  22. data/_archive/spec/ruby_interpreter_spec.rb +203 -0
  23. data/_archive/spec/spec_helper.rb +30 -0
  24. data/_archive/spec/stack_spec.rb +77 -0
  25. data/bin/console +14 -0
  26. data/bin/setup +8 -0
  27. data/e2e/container.rb +38 -0
  28. data/e2e/custom_props.rb +55 -0
  29. data/e2e/rox_e2e_test.rb +159 -0
  30. data/e2e/test_vars.rb +24 -0
  31. data/lib/rox.rb +5 -0
  32. data/lib/rox/core/client/buid.rb +82 -0
  33. data/lib/rox/core/client/device_properties.rb +45 -0
  34. data/lib/rox/core/client/internal_flags.rb +20 -0
  35. data/lib/rox/core/client/sdk_settings.rb +5 -0
  36. data/lib/rox/core/configuration/configuration.rb +5 -0
  37. data/lib/rox/core/configuration/configuration_fetched_args.rb +23 -0
  38. data/lib/rox/core/configuration/configuration_fetched_invoker.rb +37 -0
  39. data/lib/rox/core/configuration/configuration_parser.rb +85 -0
  40. data/lib/rox/core/configuration/fetcher_error.rb +13 -0
  41. data/lib/rox/core/configuration/fetcher_status.rb +10 -0
  42. data/lib/rox/core/configuration/models/experiment_model.rb +5 -0
  43. data/lib/rox/core/configuration/models/target_group_model.rb +5 -0
  44. data/lib/rox/core/consts/build.rb +8 -0
  45. data/lib/rox/core/consts/environment.rb +42 -0
  46. data/lib/rox/core/consts/property_type.rb +29 -0
  47. data/lib/rox/core/context/merged_context.rb +16 -0
  48. data/lib/rox/core/core.rb +131 -0
  49. data/lib/rox/core/entities/flag.rb +26 -0
  50. data/lib/rox/core/entities/flag_setter.rb +39 -0
  51. data/lib/rox/core/entities/variant.rb +56 -0
  52. data/lib/rox/core/impression/impression_args.rb +5 -0
  53. data/lib/rox/core/impression/impression_invoker.rb +41 -0
  54. data/lib/rox/core/impression/models/experiment.rb +14 -0
  55. data/lib/rox/core/impression/models/reporting_value.rb +5 -0
  56. data/lib/rox/core/logging/logging.rb +17 -0
  57. data/lib/rox/core/logging/no_op_logger.rb +11 -0
  58. data/lib/rox/core/network/configuration_fetch_result.rb +5 -0
  59. data/lib/rox/core/network/configuration_fetcher.rb +38 -0
  60. data/lib/rox/core/network/configuration_fetcher_base.rb +25 -0
  61. data/lib/rox/core/network/configuration_fetcher_roxy.rb +29 -0
  62. data/lib/rox/core/network/configuration_source.rb +9 -0
  63. data/lib/rox/core/network/request.rb +46 -0
  64. data/lib/rox/core/network/request_configuration_builder.rb +48 -0
  65. data/lib/rox/core/network/request_data.rb +5 -0
  66. data/lib/rox/core/network/response.rb +16 -0
  67. data/lib/rox/core/properties/custom_property.rb +18 -0
  68. data/lib/rox/core/properties/custom_property_type.rb +18 -0
  69. data/lib/rox/core/properties/device_property.rb +11 -0
  70. data/lib/rox/core/register/registerer.rb +35 -0
  71. data/lib/rox/core/reporting/error_reporter.rb +152 -0
  72. data/lib/rox/core/repositories/custom_property_repository.rb +61 -0
  73. data/lib/rox/core/repositories/experiment_repository.rb +21 -0
  74. data/lib/rox/core/repositories/flag_repository.rb +49 -0
  75. data/lib/rox/core/repositories/roxx/experiments_extensions.rb +82 -0
  76. data/lib/rox/core/repositories/roxx/properties_extensions.rb +26 -0
  77. data/lib/rox/core/repositories/target_group_repository.rb +17 -0
  78. data/lib/rox/core/roxx/core_stack.rb +22 -0
  79. data/lib/rox/core/roxx/evaluation_result.rb +28 -0
  80. data/lib/rox/core/roxx/node.rb +11 -0
  81. data/lib/rox/core/roxx/parser.rb +143 -0
  82. data/lib/rox/core/roxx/regular_expression_extensions.rb +33 -0
  83. data/lib/rox/core/roxx/string_tokenizer.rb +68 -0
  84. data/lib/rox/core/roxx/symbols.rb +14 -0
  85. data/lib/rox/core/roxx/token_type.rb +30 -0
  86. data/lib/rox/core/roxx/tokenized_expression.rb +119 -0
  87. data/lib/rox/core/roxx/value_compare_extensions.rb +137 -0
  88. data/lib/rox/core/security/signature_verifier.rb +18 -0
  89. data/lib/rox/core/utils/periodic_task.rb +12 -0
  90. data/lib/rox/core/utils/type_utils.rb +9 -0
  91. data/lib/rox/server/client/sdk_settings.rb +5 -0
  92. data/lib/rox/server/client/server_properties.rb +20 -0
  93. data/lib/rox/server/flags/rox_flag.rb +19 -0
  94. data/lib/rox/server/flags/rox_variant.rb +8 -0
  95. data/lib/rox/server/logging/server_logger.rb +35 -0
  96. data/lib/rox/server/rox_options.rb +27 -0
  97. data/lib/rox/server/rox_server.rb +83 -0
  98. data/lib/rox/version.rb +3 -0
  99. data/rox.gemspec +29 -0
  100. metadata +184 -0
@@ -0,0 +1,30 @@
1
+ require 'simplecov'
2
+
3
+ module SimpleCov::Configuration
4
+ def clean_filters
5
+ @filters = []
6
+ end
7
+ end
8
+
9
+ SimpleCov.configure do
10
+ clean_filters
11
+ load_adapter 'test_frameworks'
12
+ end
13
+
14
+ ENV["COVERAGE"] && SimpleCov.start do
15
+ add_filter "/.rvm/"
16
+ end
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+
20
+ require 'rspec'
21
+ require 'ruby_interpreter'
22
+ require 'stack'
23
+
24
+ # Requires supporting files with custom matchers and macros, etc,
25
+ # in ./support/ and its subdirectories.
26
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
27
+
28
+ RSpec.configure do |config|
29
+
30
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'Stack' do
4
+ let(:stack) { Stack.new }
5
+
6
+ it 'should push item' do
7
+ stack.push 'a'
8
+ stack.push 'b'
9
+ expect(stack.to_s).to eq('a,b')
10
+ end
11
+
12
+ it 'should pop item' do
13
+ stack.push 'a'
14
+ stack.push 'b'
15
+ item = stack.pop
16
+
17
+ expect(stack.to_s).to eq('a')
18
+ expect(item).to eq('b')
19
+ end
20
+
21
+ it 'should raise exception on poping from emtpy stack' do
22
+ stack.clear
23
+ expect{ stack.pop }.to raise_error(Stack::EmptyError)
24
+ end
25
+
26
+ it 'can be cleared' do
27
+ stack.push 'a'
28
+ stack.clear
29
+ expect(stack.empty?).to eq(true)
30
+ end
31
+
32
+ it 'to_s display valid' do
33
+ stack.push 'a'
34
+ stack.push 'b'
35
+ stack.push 'c'
36
+ expect(stack.to_s).to eq('a,b,c')
37
+ end
38
+
39
+ it 'empty? handles' do
40
+ stack.clear
41
+ expect(stack.empty?).to eq(true)
42
+
43
+ stack.push 'a'
44
+ expect(stack.empty?).to eq(false)
45
+ end
46
+
47
+ it 'can return size' do
48
+ stack.clear
49
+ expect(stack.size).to eq(0)
50
+
51
+ stack.push 'a'
52
+ expect(stack.size).to eq(1)
53
+ end
54
+
55
+ it 'can poke at specific index' do
56
+ stack.push 'a'
57
+ stack.push 'b'
58
+ stack.poke 'c', 0
59
+ expect(stack.to_s).to eq('c,b')
60
+ end
61
+
62
+ it 'can insert value at index' do
63
+ stack.push 'a'
64
+ stack.push 'b'
65
+ stack.insert 'c', 1
66
+
67
+ expect(stack.to_s).to eq('a,c,b')
68
+ end
69
+
70
+ it 'can invert order of stack' do
71
+ stack.push 'a'
72
+ stack.push 'b'
73
+ stack.invert
74
+
75
+ expect(stack.to_s).to eq('b,a')
76
+ end
77
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rox"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/e2e/container.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'rox/server/flags/rox_flag'
2
+ require 'rox/server/flags/rox_variant'
3
+
4
+ module E2E
5
+ class Container
6
+ attr_accessor :simple_flag, :simple_flag_overwritten
7
+ attr_accessor :flag_for_impression, :flag_for_impression_with_experiment_and_context
8
+ attr_accessor :flag_custom_properties
9
+ attr_accessor :flag_target_groups_all, :flag_target_groups_any, :flag_target_groups_none
10
+ attr_accessor :variant_with_context
11
+ attr_accessor :variant, :variant_overwritten
12
+ attr_accessor :flag_for_dependency, :flag_colors_for_dependency, :flag_dependent, :flag_color_dependent_with_context
13
+
14
+ def initialize
15
+ @simple_flag = Rox::Server::RoxFlag.new(true)
16
+ @simple_flag_overwritten = Rox::Server::RoxFlag.new(true)
17
+
18
+ @flag_for_impression = Rox::Server::RoxFlag.new(false)
19
+ @flag_for_impression_with_experiment_and_context = Rox::Server::RoxFlag.new(false)
20
+
21
+ @flag_custom_properties = Rox::Server::RoxFlag.new
22
+
23
+ @flag_target_groups_all = Rox::Server::RoxFlag.new
24
+ @flag_target_groups_any = Rox::Server::RoxFlag.new
25
+ @flag_target_groups_none = Rox::Server::RoxFlag.new
26
+
27
+ @variant_with_context = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
28
+
29
+ @variant = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
30
+ @variant_overwritten = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
31
+
32
+ @flag_for_dependency = Rox::Server::RoxFlag.new(false)
33
+ @flag_colors_for_dependency = Rox::Server::RoxVariant.new('White', ['White', 'Blue', 'Green', 'Yellow'])
34
+ @flag_dependent = Rox::Server::RoxFlag.new(false)
35
+ @flag_color_dependent_with_context = Rox::Server::RoxVariant.new('White', ['White', 'Blue', 'Green', 'Yellow'])
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ module E2E
2
+ class CustomProps
3
+ def self.create_custom_props
4
+ Rox::Server::RoxServer.set_custom_string_property('string_prop1', 'Hello')
5
+ Rox::Server::RoxServer.set_custom_string_property('string_prop2') do |context|
6
+ TestVars.is_computed_string_prop_called = true
7
+ 'World'
8
+ end
9
+
10
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop1', true)
11
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop2') do |context|
12
+ TestVars.is_computed_boolean_prop_called = true
13
+ false
14
+ end
15
+
16
+ Rox::Server::RoxServer.set_custom_int_property('int_prop1', 6)
17
+ Rox::Server::RoxServer.set_custom_int_property('int_prop2') do |context|
18
+ TestVars.is_computed_int_prop_called = true
19
+ 28
20
+ end
21
+
22
+ Rox::Server::RoxServer.set_custom_float_property('float_prop1', 3.14)
23
+ Rox::Server::RoxServer.set_custom_float_property('float_prop2') do |context|
24
+ TestVars.is_computed_float_prop_called = true
25
+ 1.618
26
+ end
27
+
28
+ Rox::Server::RoxServer.set_custom_semver_property('smvr_prop1', '9.11.2001')
29
+ Rox::Server::RoxServer.set_custom_semver_property('smvr_prop2') do |context|
30
+ TestVars.is_computed_semver_prop_called = true
31
+ '20.7.1969'
32
+ end
33
+
34
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_variant') do |context|
35
+ context['isDuckAndCover']
36
+ end
37
+
38
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand1') do |context|
39
+ TestVars.target_group1
40
+ end
41
+
42
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand2') do |context|
43
+ TestVars.target_group2
44
+ end
45
+
46
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_dependency') do |context|
47
+ TestVars.is_prop_for_target_group_for_dependency
48
+ end
49
+
50
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_variant_dependency') do |context|
51
+ context['isDuckAndCover']
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,159 @@
1
+ require "minitest/autorun"
2
+ require 'rox/server/rox_options'
3
+ require 'rox/server/rox_server'
4
+ require_relative 'container'
5
+ require_relative 'custom_props'
6
+ require_relative 'test_vars'
7
+
8
+ module E2E
9
+ class Logger
10
+ def debug(message, ex = nil)
11
+ puts 'Before Rox.Setup', message
12
+ end
13
+
14
+ def error(message, ex = nil)
15
+ puts 'Before Rox.Setup', message
16
+ end
17
+
18
+ def warn(message, ex = nil)
19
+ puts 'Before Rox.Setup', message
20
+ end
21
+ end
22
+
23
+ class RoxE2ETest < Minitest::Test
24
+ ENV['ROLLOUT_MODE'] = 'QA'
25
+
26
+ configuration_fetched_handler = proc do |e|
27
+ if !e.nil? && e.fetcher_status == Rox::Core::FetcherStatus::APPLIED_FROM_NETWORK
28
+ TestVars.configuration_fetched_count += 1
29
+ end
30
+ end
31
+
32
+ impression_handler = proc do |e|
33
+ if !e.nil? && !e.reporting_value.nil?
34
+ TestVars.is_impression_raised = true if e.reporting_value.name == 'flag_for_impression'
35
+ end
36
+ TestVars.impression_returned_args = e
37
+ end
38
+
39
+ option = Rox::Server::RoxOptions.new(
40
+ configuration_fetched_handler: configuration_fetched_handler,
41
+ impression_handler: impression_handler,
42
+ dev_mode_key: '67e39e708444aa953414e444',
43
+ logger: Logger.new
44
+ )
45
+
46
+ @@container = Container.new
47
+ Rox::Server::RoxServer.register('', @@container)
48
+ CustomProps.create_custom_props
49
+ Rox::Server::RoxServer.setup('5b82864ebc3aec37aff1fdd5', option).join
50
+
51
+ def test_simple_flag
52
+ assert_equal true, @@container.simple_flag.enabled?
53
+ end
54
+
55
+ def test_simple_flag_overwritten
56
+ assert_equal false, @@container.simple_flag_overwritten.enabled?
57
+ end
58
+
59
+ def test_variant
60
+ assert_equal 'red', @@container.variant.value
61
+ end
62
+
63
+ def test_variant_overwritten
64
+ assert_equal 'green', @@container.variant_overwritten.value
65
+ end
66
+
67
+ def test_all_custom_properties
68
+ assert_equal true, @@container.flag_custom_properties.enabled?
69
+
70
+ assert_equal true, TestVars.is_computed_boolean_prop_called
71
+ assert_equal true, TestVars.is_computed_float_prop_called
72
+ assert_equal true, TestVars.is_computed_int_prop_called
73
+ assert_equal true, TestVars.is_computed_semver_prop_called
74
+ assert_equal true, TestVars.is_computed_string_prop_called
75
+ end
76
+
77
+ def test_fetch_within_timeout
78
+ number_of_config_fetches = TestVars.configuration_fetched_count
79
+ timeout = 5
80
+ thread = Rox::Server::RoxServer.fetch
81
+ res = thread.join(timeout)
82
+
83
+ if res.nil?
84
+ flunk('timeout')
85
+ else
86
+ assert number_of_config_fetches < TestVars.configuration_fetched_count
87
+ end
88
+ end
89
+
90
+ def test_variant_with_context
91
+ some_positive_context = {'isDuckAndCover' => true}
92
+ some_negative_context = {'isDuckAndCover' => false}
93
+
94
+ assert_equal 'red', @@container.variant_with_context.value
95
+
96
+ assert_equal 'blue', @@container.variant_with_context.value(some_positive_context)
97
+ assert_equal 'red', @@container.variant_with_context.value(some_negative_context)
98
+ end
99
+
100
+ def test_target_groups_all_any_none
101
+ TestVars.target_group1 = true
102
+ TestVars.target_group2 = true
103
+
104
+ assert_equal true, @@container.flag_target_groups_all.enabled?
105
+ assert_equal true, @@container.flag_target_groups_any.enabled?
106
+ assert_equal false, @@container.flag_target_groups_none.enabled?
107
+
108
+ TestVars.target_group1 = false
109
+ assert_equal false, @@container.flag_target_groups_all.enabled?
110
+ assert_equal true, @@container.flag_target_groups_any.enabled?
111
+ assert_equal false, @@container.flag_target_groups_none.enabled?
112
+
113
+ TestVars.target_group2 = false
114
+ assert_equal false, @@container.flag_target_groups_all.enabled?
115
+ assert_equal false, @@container.flag_target_groups_any.enabled?
116
+ assert_equal true, @@container.flag_target_groups_none.enabled?
117
+ end
118
+
119
+ def test_impression_handler
120
+ @@container.flag_for_impression.enabled?
121
+ assert_equal true, TestVars.is_impression_raised
122
+ TestVars.is_impression_raised = false
123
+
124
+ context = {'var' => 'val'}
125
+ flag_impression_value = @@container.flag_for_impression_with_experiment_and_context.enabled?(context)
126
+ refute_nil TestVars.impression_returned_args
127
+ refute_nil TestVars.impression_returned_args.reporting_value
128
+ assert_equal 'true', TestVars.impression_returned_args.reporting_value.value
129
+ assert_equal true, flag_impression_value
130
+ assert_equal 'flag_for_impression_with_experiment_and_context', TestVars.impression_returned_args.reporting_value.name
131
+
132
+ refute_nil TestVars.impression_returned_args
133
+ refute_nil TestVars.impression_returned_args.experiment
134
+ assert_equal '5b8f85ecbc3aec37aff20841', TestVars.impression_returned_args.experiment.identifier
135
+ assert_equal 'flag for impression with experiment and context', TestVars.impression_returned_args.experiment.name
136
+
137
+ assert_equal 'val', TestVars.impression_returned_args.context['var']
138
+ end
139
+
140
+ def test_flag_dependency
141
+ TestVars.is_prop_for_target_group_for_dependency = true
142
+ assert_equal true, @@container.flag_for_dependency.enabled?
143
+ assert_equal false, @@container.flag_dependent.enabled?
144
+
145
+ TestVars.is_prop_for_target_group_for_dependency = false
146
+ assert_equal true, @@container.flag_dependent.enabled?
147
+ assert_equal false, @@container.flag_for_dependency.enabled?
148
+ end
149
+
150
+ def test_variant_dependency_with_context
151
+ some_positive_context = {'isDuckAndCover' => true}
152
+ some_negative_context = {'isDuckAndCover' => false}
153
+
154
+ assert_equal 'White', @@container.flag_color_dependent_with_context.value
155
+ assert_equal 'White', @@container.flag_color_dependent_with_context.value(some_negative_context)
156
+ assert_equal 'Yellow', @@container.flag_color_dependent_with_context.value(some_positive_context)
157
+ end
158
+ end
159
+ end
data/e2e/test_vars.rb ADDED
@@ -0,0 +1,24 @@
1
+ module E2E
2
+ module TestVars
3
+ class << self
4
+ attr_accessor :is_computed_boolean_prop_called, :is_computed_string_prop_called, :is_computed_int_prop_called, :is_computed_float_prop_called, :is_computed_semver_prop_called
5
+ attr_accessor :target_group1, :target_group2
6
+ attr_accessor :is_impression_raised, :is_prop_for_target_group_for_dependency
7
+
8
+ attr_accessor :configuration_fetched_count, :impression_returned_args
9
+ end
10
+
11
+ @is_computed_boolean_prop_called = false
12
+ @is_computed_string_prop_called = false
13
+ @is_computed_int_prop_called = false
14
+ @is_computed_float_prop_called = false
15
+ @is_computed_semver_prop_called = false
16
+ @target_group1 = false
17
+ @target_group2 = false
18
+ @is_impression_raised = false
19
+ @is_prop_for_target_group_for_dependency = false
20
+
21
+ @configuration_fetched_count = 0
22
+ @impression_returned_args = nil
23
+ end
24
+ end
data/lib/rox.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'rox/version'
2
+
3
+ module Rox
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,82 @@
1
+ require 'digest'
2
+ require 'json'
3
+ require 'rox/core/consts/property_type'
4
+
5
+ module Rox
6
+ module Core
7
+ class BUID
8
+ BUID_GENERATORS = [
9
+ PropertyType::PLATFORM,
10
+ PropertyType::APP_KEY,
11
+ PropertyType::LIB_VERSION,
12
+ PropertyType::API_VERSION,
13
+ PropertyType::CUSTOM_PROPERTIES,
14
+ PropertyType::FEATURE_FLAGS,
15
+ PropertyType::REMOTE_VARIABLES
16
+ ].freeze
17
+
18
+ def initialize(sdk_settings, device_properties, flag_repository, custom_property_repository)
19
+ @sdk_settings = sdk_settings
20
+ @device_properties = device_properties
21
+ @flag_repository = flag_repository
22
+ @custom_property_repository = custom_property_repository
23
+ @buid = nil
24
+ end
25
+
26
+ def value
27
+ properties = @device_properties.all_properties
28
+ values = []
29
+ BUID::BUID_GENERATORS.each do |pt, _|
30
+ values << properties[pt.name] if properties.include?(pt.name)
31
+ end
32
+
33
+ values << serialize_feature_flags
34
+ values << serialize_custom_properties
35
+
36
+ hash = Digest::MD5.hexdigest(values.join('|'))
37
+
38
+ @buid = hash.upcase
39
+ end
40
+
41
+ def query_string_parts
42
+ generators = BUID::BUID_GENERATORS.map {|pt, _| pt.name}
43
+
44
+ {
45
+ PropertyType::BUID.name => value,
46
+ PropertyType::BUID_GENERATORS_LIST.name => generators.join(','),
47
+ PropertyType::FEATURE_FLAGS.name => serialize_feature_flags,
48
+ PropertyType::REMOTE_VARIABLES.name => '[]',
49
+ PropertyType::CUSTOM_PROPERTIES.name => serialize_custom_properties,
50
+ }
51
+ end
52
+
53
+ def serialize_feature_flags
54
+ flags = []
55
+ @flag_repository.all_flags.each do |f|
56
+ flags << {
57
+ name: f.name,
58
+ defaultValue: f.default_value,
59
+ options: f.options
60
+ }
61
+ end
62
+ JSON.dump(flags)
63
+ end
64
+
65
+ def serialize_custom_properties
66
+ properties = []
67
+ @custom_property_repository.all_custom_properties.each do |p|
68
+ properties << {
69
+ name: p.name,
70
+ type: p.type.type,
71
+ externalType: p.type.external_type
72
+ }
73
+ end
74
+ JSON.dump(properties)
75
+ end
76
+
77
+ def to_s
78
+ @buid
79
+ end
80
+ end
81
+ end
82
+ end