diff --git a/.circleci/config.yml b/.circleci/config.yml index 1b21baf..3419d0a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,5 @@ version: 2.1 + workflows: version: 2 ruby-exclaim: @@ -8,18 +9,19 @@ workflows: jobs: build: docker: - - image: salsify/ruby_ci:2.7.2 + - image: $SALSIFY_ECR_REPO/ruby_ci:3.3.5 + aws_auth: + aws_access_key_id: $ECR_AWS_ACCESS_KEY_ID + aws_secret_access_key: $ECR_AWS_SECRET_ACCESS_KEY environment: - RACK_ENV: "test" - RAILS_ENV: "test" CIRCLE_TEST_REPORTS: "test-results" working_directory: ~/ruby-exclaim steps: - checkout - restore_cache: keys: - - v1-gems-ruby-2.7.2-{{ checksum "ruby-exclaim.gemspec" }}-{{ checksum "Gemfile" }} - - v1-gems-ruby-2.7.2- + - v1-gems-ruby-3.3.5-{{ checksum "ruby-exclaim.gemspec" }}-{{ checksum "Gemfile" }} + - v1-gems-ruby-3.3.5- - run: name: Install Gems command: | @@ -28,7 +30,7 @@ jobs: bundle clean fi - save_cache: - key: v1-gems-ruby-2.7.2-{{ checksum "ruby-exclaim.gemspec" }}-{{ checksum "Gemfile" }} + key: v1-gems-ruby-3.3.5-{{ checksum "ruby-exclaim.gemspec" }}-{{ checksum "Gemfile" }} paths: - "vendor/bundle" - "gemfiles/vendor/bundle" diff --git a/CHANGELOG.md b/CHANGELOG.md index 470a9fc..4c4a602 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## Unreleased +## 0.1.1 - 2024-11-18 +### Fixed +- Fix various issues related to path segments that appear to be numbers. + ## 0.1.0 - 2021-05-06 ### Added - Ability to disable all HTML escaping by setting the `should_escape_html` flag to `false` when instantiating diff --git a/README.md b/README.md index 1706d04..1a858f3 100644 --- a/README.md +++ b/README.md @@ -220,10 +220,8 @@ exclaim_ui.render(env: my_environment) Dot-separated `$bind` paths dig into nested `env` values: `a.b.c` refers to `{ "a" => { "b" => { "c" => "value" } } }` -If a `$bind` path segment is an Integer, -the library will attempt to treat it as an Array index when resolving the value at render time: - -`"my_array.1"` refers to array index 1 in an `env` like `{ "my_array: ["zero", "one", ...] }` +If the field a `$bind` subpath refers is an Array, the next segment is assumed to be an integer. For example, +`"my_array.1"` refers to array index 1, value "zero" in an `env` like `{ "my_array: ["zero", "one", ...] }`. ### Implementing Components and Helpers @@ -800,7 +798,7 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. -To install this gem onto your local machine, run `bundle exec rake install`. +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`. When merged to the default branch, [a GitHub action](.github/workflows/release.yml) will diff --git a/lib/exclaim/bind.rb b/lib/exclaim/bind.rb index 4a407e1..6b243aa 100644 --- a/lib/exclaim/bind.rb +++ b/lib/exclaim/bind.rb @@ -14,15 +14,27 @@ def initialize(path:, json_declaration: nil) def path=(value) @path = value @path_keys = @path.split('.') - @path_keys_for_arrays = @path_keys.map do |string| - Integer(string) - rescue ArgumentError, TypeError - string - end end def evaluate(env) - env.dig(*@path_keys_for_arrays) || env.dig(*@path_keys) + obj = env + + @path_keys.each do |key| + return nil if !obj.is_a?(Hash) && !obj.is_a?(Array) + + if obj.is_a?(Array) + key = begin + Integer(key) + rescue ArgumentError, TypeError + return nil + end + end + + obj = obj[key] + return nil if obj.nil? + end + + obj end end end diff --git a/lib/exclaim/version.rb b/lib/exclaim/version.rb index 67edfe0..e0ad88a 100644 --- a/lib/exclaim/version.rb +++ b/lib/exclaim/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Exclaim - VERSION = '0.1.0' + VERSION = '0.1.1' end diff --git a/spec/rendering/basic_spec.rb b/spec/rendering/basic_spec.rb index f077ebb..0f99e7f 100644 --- a/spec/rendering/basic_spec.rb +++ b/spec/rendering/basic_spec.rb @@ -83,6 +83,20 @@ env = { 'x' => 'five' } expect(exclaim_ui.render(env: env)).to eq('Bound value: five') end + + it "assumes path represents a string key when indexing a hash field" do + bind = Exclaim::Bind.new(path: '1') + parsed_component.config = { 'content' => bind } + + env = { '1' => 5 } + expect(exclaim_ui.render(env: env)).to eq('Bound value: 5') + + bind = Exclaim::Bind.new(path: '1') + parsed_component.config = { 'content' => bind } + + env = { 1 => 5 } + expect(exclaim_ui.render(env: env)).to eq('Bound value: ') + end end context "array index as path" do @@ -93,6 +107,22 @@ env = ['zero', 'one', 'two'] expect(exclaim_ui.render(env: env)).to eq('Bound value: two') end + + it "assumes path represents an integer key when indexing an array field" do + bind = Exclaim::Bind.new(path: 'not_an_integer') + parsed_component.config = { 'content' => bind } + + env = [] + expect(exclaim_ui.render(env: env)).to eq('Bound value: ') + end + + it "evaluates to nil when index is out of bounds" do + bind = Exclaim::Bind.new(path: '0') + parsed_component.config = { 'content' => bind } + + env = [] + expect(exclaim_ui.render(env: env)).to eq('Bound value: ') + end end context "dot-separated bind path" do