Commit 19298cf

mo <mo.khan@gmail.com>
2018-12-24 19:33:46
build simple attribute type
1 parent 672d539
bin/cibuild
@@ -7,7 +7,7 @@ set -e
 
 cd "$(dirname "$0")/.."
 
-echo [$(date "+%H:%M:%S")] "==> Started at…"
+echo ["$(date "+%H:%M:%S")"] "==> Started at…"
 
 # GC customizations
 export RUBY_GC_MALLOC_LIMIT=79000000
@@ -19,3 +19,4 @@ export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
 ruby -v
 gem install bundler --no-ri --no-rdoc --conservative
 bin/test
+bin/lint
lib/scim/kit/v2/attribute_type.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      # Represents a scim Attribute type
+      class AttributeType
+        attr_reader :name, :type
+
+        def initialize(name:, type: :string, overrides: {})
+          @name = name
+          @type = type
+          @overrides = defaults.merge(overrides)
+          ensure_valid!(@overrides)
+        end
+
+        def to_h
+          @overrides
+        end
+
+        private
+
+        def ensure_valid!(overrides)
+          valid_mutability!(overrides[:mutability])
+          valid_returned!(overrides[:returned])
+          valid_uniqueness!(overrides[:uniqueness])
+        end
+
+        def valid_mutability!(mutability)
+          raise ArgumentError, :mutability unless Mutability.valid?(mutability)
+        end
+
+        def valid_returned!(returned)
+          raise ArgumentError, :returned unless Returned.valid?(returned)
+        end
+
+        def valid_uniqueness!(uniqueness)
+          raise ArgumentError, :uniqueness unless Uniqueness.valid?(uniqueness)
+        end
+
+        def defaults
+          {
+            name: name, type: type.to_s, description: '',
+            multiValued: false, required: false, caseExact: false,
+            mutability: Mutability::READ_WRITE,
+            returned: Returned::DEFAULT,
+            uniqueness: Uniqueness::NONE
+          }
+        end
+      end
+    end
+  end
+end
lib/scim/kit/v2/mutability.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      # Represents the valid Mutability values
+      class Mutability
+        READ_ONLY = 'readOnly'
+        READ_WRITE = 'readWrite'
+        IMMUTABLE = 'immutable'
+        WRITE_ONLY = 'writeOnly'
+        VALID = {
+          read_only: 'readOnly',
+          read_write: 'readWrite',
+          immutable: 'immutable',
+          write_only: 'writeOnly'
+        }.freeze
+
+        def self.valid?(value)
+          VALID.key?(value.to_sym) || VALID.value?(value)
+        end
+      end
+    end
+  end
+end
lib/scim/kit/v2/resource.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      # Represents a ResourceType Schema
+      # https://tools.ietf.org/html/rfc7643#section-6
+      class Resource
+        attr_accessor :id
+        attr_accessor :name
+        attr_accessor :description
+        attr_accessor :endpoint
+        attr_accessor :schema
+        attr_reader :location
+
+        def initialize(location:)
+          @location = location
+        end
+
+        def to_json
+          JSON.generate(to_h)
+        end
+
+        def to_h
+          {
+            meta: meta,
+            schemas: [Schema::RESOURCE_TYPE],
+            id: id,
+            name: name,
+            description: description,
+            endpoint: endpoint,
+            schema: schema,
+            schemaExtensions: []
+          }
+        end
+
+        private
+
+        def meta
+          {
+            resourceType: 'ResourceType',
+            location: location
+          }
+        end
+      end
+    end
+  end
+end
lib/scim/kit/v2/returned.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      # Represents the valid Returned values
+      class Returned
+        ALWAYS = 'always'
+        NEVER = 'never'
+        DEFAULT = 'default'
+        REQUEST = 'request'
+        VALID = {
+          always: 'always',
+          never: 'never',
+          default: 'default',
+          request: 'request'
+        }.freeze
+
+        def self.valid?(value)
+          VALID[value.to_sym]
+        end
+      end
+    end
+  end
+end
lib/scim/kit/v2/schema.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      module Schema
+        ERROR = 'urn:ietf:params:scim:api:messages:2.0:Error'
+        GROUP = 'urn:ietf:params:scim:schemas:core:2.0:Group'
+        RESOURCE_TYPE = 'urn:ietf:params:scim:schemas:core:2.0:ResourceType'
+        USER = 'urn:ietf:params:scim:schemas:core:2.0:User'
+      end
+    end
+  end
+end
lib/scim/kit/v2/uniqueness.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    module V2
+      # Represents the valid Uniqueness values
+      class Uniqueness
+        NONE = 'none'
+        SERVER = 'server'
+        GLOBAL = 'global'
+        VALID = {
+          none: 'none',
+          server: 'server',
+          global: 'global'
+        }.freeze
+
+        def self.valid?(value)
+          VALID[value.to_sym]
+        end
+      end
+    end
+  end
+end
lib/scim/kit/resource.rb
@@ -1,36 +0,0 @@
-module Scim
-  module Kit
-    class Resource
-      attr_accessor :id
-      attr_accessor :name
-      attr_accessor :description
-      attr_accessor :endpoint
-      attr_accessor :schema
-      attr_reader :location
-
-      def initialize(location:)
-        @location = location
-      end
-
-      def to_json
-        JSON.generate(to_h)
-      end
-
-      def to_h
-        {
-          meta: {
-            resourceType: 'ResourceType',
-            location: location,
-          },
-          schemas: [Schema::RESOURCE_TYPE],
-          id: id,
-          name: name,
-          description: description,
-          endpoint: endpoint,
-          schema: schema,
-          schemaExtensions: [],
-        }
-      end
-    end
-  end
-end
lib/scim/kit/schema.rb
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-module Scim
-  module Kit
-    module Schema
-      ERROR = 'urn:ietf:params:scim:api:messages:2.0:Error'
-      GROUP = 'urn:ietf:params:scim:schemas:core:2.0:Group'
-      RESOURCE_TYPE = 'urn:ietf:params:scim:schemas:core:2.0:ResourceType'
-      USER = 'urn:ietf:params:scim:schemas:core:2.0:User'
-    end
-  end
-end
lib/scim/kit.rb
@@ -1,12 +1,15 @@
 # frozen_string_literal: true
 
 require 'scim/kit/version'
-require 'scim/kit/schema'
-require 'scim/kit/resource'
+require 'scim/kit/v2/attribute_type'
+require 'scim/kit/v2/returned'
+require 'scim/kit/v2/uniqueness'
+require 'scim/kit/v2/mutability'
+require 'scim/kit/v2/schema'
+require 'scim/kit/v2/resource'
 
 module Scim
   module Kit
     class Error < StandardError; end
-    # Your code goes here...
   end
 end
spec/scim/kit/v2/attribute_type_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+RSpec.describe Scim::Kit::V2::AttributeType do
+  describe 'String Attribute' do
+    describe 'defaults' do
+      subject { described_class.new(name: 'displayName') }
+
+      specify { expect(subject.name).to eql('displayName') }
+      specify { expect(subject.type).to be(:string) }
+      specify { expect(subject.to_h[:name]).to eql('displayName') }
+      specify { expect(subject.to_h[:type]).to eql('string') }
+      specify { expect(subject.to_h[:multiValued]).to be(false) }
+      specify { expect(subject.to_h[:description]).to eql('') }
+      specify { expect(subject.to_h[:required]).to be(false) }
+      specify { expect(subject.to_h[:caseExact]).to be(false) }
+      specify { expect(subject.to_h[:mutability]).to eql('readWrite') }
+      specify { expect(subject.to_h[:returned]).to eql('default') }
+      specify { expect(subject.to_h[:uniqueness]).to eql('none') }
+    end
+
+    describe 'overrides' do
+      def build(overrides)
+        described_class.new(name: 'displayName', overrides: overrides)
+      end
+
+      specify { expect(build(multiValued: true).to_h[:multiValued]).to be(true) }
+      specify { expect(build(description: 'hello').to_h[:description]).to eq('hello') }
+      specify { expect(build(required: true).to_h[:required]).to be(true) }
+      specify { expect(build(caseExact: true).to_h[:caseExact]).to be(true) }
+
+      specify { expect(build(mutability: 'readOnly').to_h[:mutability]).to eql('readOnly') }
+      specify { expect(build(mutability: 'readWrite').to_h[:mutability]).to eql('readWrite') }
+      specify { expect(build(mutability: 'immutable').to_h[:mutability]).to eql('immutable') }
+      specify { expect(build(mutability: 'writeOnly').to_h[:mutability]).to eql('writeOnly') }
+      specify { expect { build(mutability: 'invalid') }.to raise_error(ArgumentError) }
+
+      specify { expect(build(returned: 'always').to_h[:returned]).to eql('always') }
+      specify { expect(build(returned: 'never').to_h[:returned]).to eql('never') }
+      specify { expect(build(returned: 'default').to_h[:returned]).to eql('default') }
+      specify { expect(build(returned: 'request').to_h[:returned]).to eql('request') }
+      specify { expect { build(returned: 'invalid') }.to raise_error(ArgumentError) }
+
+      specify { expect(build(uniqueness: 'none').to_h[:uniqueness]).to eql('none') }
+      specify { expect(build(uniqueness: 'server').to_h[:uniqueness]).to eql('server') }
+      specify { expect(build(uniqueness: 'global').to_h[:uniqueness]).to eql('global') }
+      specify { expect { build(uniqueness: 'invalid') }.to raise_error(ArgumentError) }
+    end
+  end
+end
spec/scim/kit/resource_spec.rb → spec/scim/kit/v2/resource_spec.rb
@@ -1,20 +1,22 @@
-RSpec.describe Scim::Kit::Resource do
+# frozen_string_literal: true
+
+RSpec.describe Scim::Kit::V2::Resource do
   subject { described_class.new(location: location) }
+
   let(:location) { FFaker::Internet.uri('https') }
+  let(:hash) { JSON.parse(subject.to_json, symbolize_names: true) }
 
   before do
-    subject.id = "Group"
-    subject.description = "Group"
-    subject.endpoint = "https://www.example.org/scim/v2/groups"
-    subject.name = "Group"
-    subject.schema = Scim::Kit::Schema::GROUP
+    subject.id = 'Group'
+    subject.description = 'Group'
+    subject.endpoint = 'https://www.example.org/scim/v2/groups'
+    subject.name = 'Group'
+    subject.schema = Scim::Kit::V2::Schema::GROUP
   end
 
-  let(:hash) { JSON.parse(subject.to_json, symbolize_names: true) }
-
   specify { expect(hash[:meta][:location]).to eql(location) }
   specify { expect(hash[:meta][:resourceType]).to eql('ResourceType') }
-  specify { expect(hash[:schemas]).to match_array([Scim::Kit::Schema::RESOURCE_TYPE]) }
+  specify { expect(hash[:schemas]).to match_array([Scim::Kit::V2::Schema::RESOURCE_TYPE]) }
   specify { expect(hash[:id]).to eql('Group') }
   specify { expect(hash[:description]).to eql(subject.description) }
   specify { expect(hash[:endpoint]).to eql(subject.endpoint) }
.rubocop.yml
@@ -9,6 +9,17 @@ AllCops:
     - 'vendor/**/*'
   TargetRubyVersion: 2.5
 
+Metrics/BlockLength:
+  Exclude:
+    - 'spec/**/*.rb'
+
+Metrics/LineLength:
+  Exclude:
+    - 'spec/**/*.rb'
+
 Naming/FileName:
   Exclude:
     - 'lib/scim-kit.rb'
+
+RSpec/NamedSubject:
+  Enabled: false