Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions features/abbreviations_cn22.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
user:
id: 1
3 changes: 3 additions & 0 deletions features/file_s3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
user:
id: 1
3 changes: 3 additions & 0 deletions features/s3_file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
user:
id: 1
19 changes: 11 additions & 8 deletions lib/toggles/constant_lookup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,38 @@ def initialize(sym)
end
end


# Return a tree walker that translates Module#const_missing(sym) into the next child node
#
# So Features::Cat::BearDog walks as:
# * next_features = Feature.features # root
# * const_missing(:Cat) => next_features = next_features['cat']
# * const_missing(:BearDog) => next_features['bear_dog']
# * const_missing(:CN22) => next_features['c_n_22']
#
# Defined at Toggles.features_dir + "/cat/bear_dog.yaml"
#
# @raise [Error] if constant cannot be resolved
def self.from(features, path)
Class.new {
class << self
attr_accessor :features
attr_accessor :path
attr_accessor :features, :path

def const_missing(sym)
subtree_or_feature = features.fetch(
# translate class name into path part i.e :BearDog #=> 'bear_dog'
sym.to_s.gsub(/([a-z])([A-Z])/) { |s| s.chars.join('_') }.downcase.to_sym,
)
# translate class name into path part i.e :BearDog #=> 'bear_dog'
key = sym.to_s
key.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
key.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
key.downcase!
Comment on lines +29 to +32
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still seeing that we're having some issues with translation of potential keys, but let me know if you don't see it as an issue right now, or something we'll fix later.

[2] pry(main)> def tr(str)
[2] pry(main)*   str.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
[2] pry(main)*   str.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
[2] pry(main)*   str.downcase!
[2] pry(main)*   return str
[2] pry(main)* end
=> :tr
[3] pry(main)>
[4] pry(main)> tr("CN22")
=> "cn22"
[5] pry(main)> tr("Allow2DayAir")
=> "allow2_day_air"
[6] pry(main)> tr("Allow2ndDaySomething")
=> "allow2nd_day_something"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this a transitionary release and there is a workaround for it, I'm inclined to improve it within reason and then move on to a major release that removes support for module-based access entirely.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, works for me


subtree_or_feature = features.fetch(key.to_sym)

if subtree_or_feature.is_a?(Hash)
Feature::ConstantLookup.from(subtree_or_feature, path + [sym])
else
subtree_or_feature
end
rescue KeyError
raise Error.new(path + [sym])
raise Error, path + [sym]
end
end
}.tap do |resolver|
Expand Down
2 changes: 1 addition & 1 deletion lib/toggles/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Toggles
VERSION = '0.3.0'
VERSION = '0.3.2'
end
34 changes: 30 additions & 4 deletions spec/toggles/feature/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,35 @@
let(:user) { double(id: 1, logged_in?: true) }
let(:widget) { double(id: 2) }

subject { Feature::MultipleSubjects.new(user: user, widget: widget) }
context 'multiple subjects' do
subject { Feature::MultipleSubjects.new(user: user, widget: widget) }

its(:enabled?) { is_expected.to eq true }
its(:subjects) { is_expected.to eq user: user, widget: widget }
its("permissions.subjects") { is_expected.to eq [:user, :widget] }
its(:enabled?) do is_expected.to eq true end
its(:subjects) do is_expected.to eq user: user, widget: widget end
its('permissions.subjects') { is_expected.to eq %i[user widget] }
end

context 'abbreviation with numbers' do
subject { Feature::AbbreviationsCN22.new(user: user) }

its(:enabled?) do is_expected.to eq true end
its(:subjects) do is_expected.to eq user: user end
its('permissions.subjects') { is_expected.to eq [:user] }
end

context 'irregular capitalization' do
subject { Feature::S3File.new(user: user) }

its(:enabled?) do is_expected.to eq true end
its(:subjects) do is_expected.to eq user: user end
its('permissions.subjects') { is_expected.to eq [:user] }
end

context 'irregular capitalization' do
subject { Feature::FileS3.new(user: user) }

its(:enabled?) do is_expected.to eq true end
its(:subjects) do is_expected.to eq user: user end
its('permissions.subjects') { is_expected.to eq [:user] }
end
end