pidgin 0.0.0.dev → 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8e52b8266905c58fb05e7ced0c266a2c22ad262
4
- data.tar.gz: 67881201fb2c036d03aa84f9b62b74bf4aef84fa
3
+ metadata.gz: 320f277f2080469c666e5eb6e63b16dc91acfef0
4
+ data.tar.gz: 2598a9b84457ccff4855b848f880fbfc288681ee
5
5
  SHA512:
6
- metadata.gz: 9dab4ce7d34dd769184c8cdacfe13c2e4c3defc9bddb26abf4ffa24476152706920128df13b7b07a1c1bb379fb5b692e8f4b8e706f57298e212363430f548d79
7
- data.tar.gz: a4a0068b49ae2170862e9a5af5bee056f8af19aa843b7f559cfd28ac69a207575522dbf2a2ce8640f736229e557135ef0dce6b53d7f973dee6f6b0f1a350b5a4
6
+ metadata.gz: 5ef34d7d512730de03039b5a6eda4d8ba324a4a26dc8233450a055421f7d5bf3da3b6260765fe785d7a660e873cb957a11640b246aa5c31782bec8f1a7dedc58
7
+ data.tar.gz: 26f74dcff76c6d96ac4c096b8b575a78014067608260bbc21bb999bc82903e03cad5e5361f0a8201d143cbb5ff03626ef82ed454271579afd316623326584697
@@ -0,0 +1,8 @@
1
+ # Operating system garbage
2
+ .DS_Store
3
+
4
+ # Sublime Text 2/3
5
+ *.sublime-workspace
6
+
7
+ # Gem stuffs
8
+ *.gem
@@ -0,0 +1,57 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pidgin (0.0.0.dev)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ aruba (0.8.0)
10
+ childprocess (~> 0.5.6)
11
+ contracts (~> 0.9)
12
+ cucumber (>= 1.3.19)
13
+ rspec-expectations (>= 2.99)
14
+ builder (3.2.2)
15
+ childprocess (0.5.6)
16
+ ffi (~> 1.0, >= 1.0.11)
17
+ contracts (0.10)
18
+ cucumber (2.0.1)
19
+ builder (>= 2.1.2)
20
+ cucumber-core (~> 1.2.0)
21
+ diff-lcs (>= 1.1.3)
22
+ gherkin (~> 2.12)
23
+ multi_json (>= 1.7.5, < 2.0)
24
+ multi_test (>= 0.1.2)
25
+ cucumber-core (1.2.0)
26
+ gherkin (~> 2.12.0)
27
+ diff-lcs (1.2.5)
28
+ ffi (1.9.10)
29
+ gherkin (2.12.2)
30
+ multi_json (~> 1.3)
31
+ multi_json (1.11.2)
32
+ multi_test (0.1.2)
33
+ rspec (3.3.0)
34
+ rspec-core (~> 3.3.0)
35
+ rspec-expectations (~> 3.3.0)
36
+ rspec-mocks (~> 3.3.0)
37
+ rspec-core (3.3.1)
38
+ rspec-support (~> 3.3.0)
39
+ rspec-expectations (3.3.0)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.3.0)
42
+ rspec-mocks (3.3.1)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.3.0)
45
+ rspec-support (3.3.0)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ aruba
52
+ cucumber
53
+ pidgin!
54
+ rspec
55
+
56
+ BUNDLED WITH
57
+ 1.10.5
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'ostruct'
3
+
4
+ require 'pidgin/version'
5
+
6
+ require 'pidgin/domain_specific_language'
7
+ require 'pidgin/object'
8
+ require 'pidgin/property'
@@ -0,0 +1,59 @@
1
+ module Pidgin
2
+ module DomainSpecificLanguage
3
+ class Evaluator
4
+ def initialize(dsl)
5
+ @dsl = dsl
6
+ @objects = {}
7
+ end
8
+
9
+ def method_missing(name, *args, &block)
10
+ objects = @dsl.class_variable_get(:@@objects)
11
+ collections = @dsl.class_variable_get(:@@collections)
12
+ if collections.any? { |collection| collection.object.name == name }
13
+ collection = (collections.select { |collection| collection.object.name == name }).first
14
+ object = collection.object
15
+ object_inst = Kernel.const_get("#{object.type}::DSL").eval(args.first, &block)
16
+ @objects[collection.name] ||= []
17
+ @objects[collection.name] << object_inst
18
+ elsif (objects.any? { |object| object.name == name })
19
+ object = (objects.select { |object| object.name == name }).first
20
+ object_inst = Kernel.const_get("#{object.type}::DSL").eval(args.first, &block)
21
+ raise "Tried to redefine `#{object.name}'!" if @objects.include? object.name
22
+ @objects[object.name] = object_inst
23
+ else
24
+ super
25
+ end
26
+ end
27
+ end
28
+
29
+ module ClassMethods
30
+ def object(name, type)
31
+ dsl = Kernel.const_get(self.name)
32
+ object = OpenStruct.new({:name => name, :type => type})
33
+ dsl.class_variable_get(:@@objects) << object
34
+ object
35
+ end
36
+
37
+ def collection(name, type, opts={})
38
+ plural = opts[:plural] || "#{name}s"
39
+ dsl = Kernel.const_get(self.name)
40
+ collection = OpenStruct.new({:name => plural, :object => OpenStruct.new({:name => name, :type => type})})
41
+ dsl.class_variable_get(:@@collections) << collection
42
+ collection
43
+ end
44
+
45
+ def eval(code)
46
+ dsl = Kernel.const_get(self.name)
47
+ evaluator = Evaluator.new(dsl)
48
+ evaluator.instance_eval(code)
49
+ evaluator.instance_variable_get(:@objects).freeze
50
+ end
51
+ end
52
+
53
+ def self.included(klass)
54
+ klass.class_variable_set(:@@objects, [])
55
+ klass.class_variable_set(:@@collections, [])
56
+ klass.extend(ClassMethods)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,157 @@
1
+ module Pidgin
2
+ module Object
3
+ module DomainSpecificLanguage
4
+ module ClassMethods
5
+ def eval(inlined_props={}, &block)
6
+ inlined_props ||= {}
7
+ object_klass = Kernel.const_get(self.name.split('::')[0..-2].join('::'))
8
+ puts "Pidgin::Object::DomainSpecificLanguage.eval for #{object_klass}"
9
+
10
+ # Handle inlined properties, adjusting |inlined_props| as we go along.
11
+ instances_of_props = {}
12
+ allowable_inlined_props = object_klass.class_variable_get(:@@properties)
13
+ .select { |prop| prop.inline? }
14
+ allowable_inlined_props.each do |allowable_inlined_prop|
15
+ instances_of_prop = inlined_props.select { |name, _| name == allowable_inlined_prop.name }
16
+ specified_at_least_once = instances_of_prop.length > 0
17
+ specified_more_than_once = instances_of_prop.length > 1
18
+ if specified_more_than_once
19
+ # Freak out, because there's no 'good' way to handle the same inlined
20
+ # propeter being specified twice. Note however, that this shouldn't
21
+ # occur, at least if |inlined_props| is a hash.
22
+ raise ArgumentError.new("The inlined property `#{allowable_inlined_prop.name}' was specified more than once?!")
23
+ elsif specified_at_least_once
24
+ instance_of_prop = instances_of_prop.first
25
+ instances_of_sub_props = {}
26
+ # TODO(mtwilliams): Refactor out the commonality between these.
27
+ allowable_inlined_prop.sub_properties.each do |allowable_sub_prop|
28
+ instances_of_sub_prop = inlined_props.select { |name, _| name == allowable_sub_prop.name }
29
+ specified_at_least_once = instances_of_sub_prop.length > 0
30
+ specified_more_than_once = instances_of_sub_prop.length > 1
31
+ if specified_more_than_once
32
+ # Similar deal.
33
+ raise ArgumentError.new("The inlined sub-property `#{allowable_sub_prop.name}' was specified more than once?!")
34
+ elsif specified_at_least_once
35
+ instance_of_sub_prop = instances_of_sub_prop.first
36
+ sub_prop = allowable_sub_prop.type.new(instance_of_sub_prop[1])
37
+ instances_of_sub_props.merge! Hash[allowable_sub_prop.name, sub_prop]
38
+ end
39
+ inlined_props.reject! { |name, _| name == allowable_sub_prop.name }
40
+ end
41
+ # TODO(mtwilliams): Refactor?
42
+ case allowable_inlined_prop.type.name.to_sym
43
+ when :nil
44
+ # TODO(mtwilliams): Freak out, proper.
45
+ raise "..."
46
+ when :TrueClass
47
+ instances_of_props = instances_of_props.merge! Hash[allowable_inlined_prop.name, !!instance_of_prop[1]]
48
+ when :FalseClass
49
+ instances_of_props = instances_of_props.merge! Hash[allowable_inlined_prop.name, !!!instance_of_prop[1]]
50
+ else
51
+ prop = allowable_inlined_prop.type.new(instance_of_prop[1], instances_of_sub_props)
52
+ instances_of_props = instances_of_props.merge! Hash[allowable_inlined_prop.name, prop]
53
+ end
54
+ inlined_props.reject! { |name, _| name == allowable_inlined_prop.name }
55
+ end
56
+ end
57
+
58
+ # If any arguments remain, then the user has done something wrong.
59
+ raise ArgumentError.new("Unknown properties were supplied inline.") unless inlined_props.empty?
60
+
61
+ # Use the builder pattern to create an instance of the object, however
62
+ # proxy all of the DSL user's calls so they don't stomp on internals.
63
+ object_builder = ((Class.new do
64
+ def initialize(klass, properties)
65
+ @klass = klass
66
+ @properties = properties
67
+ @sub_objects = {}
68
+ end
69
+
70
+ def build
71
+ object_inst = @klass.new
72
+ @sub_objects.each { |name, sub_object_inst| object_inst.instance_variable_set("@#{name}".to_sym, sub_object_inst) }
73
+ @properties.each { |name, property| object_inst.instance_variable_set("@#{name}".to_sym, property) }
74
+ object_inst.freeze
75
+ end
76
+ end).new(object_klass, instances_of_props))
77
+
78
+ (Class.new do
79
+ def initialize(klass, builder)
80
+ @klass = klass
81
+ @builder = builder
82
+ end
83
+
84
+ def method_missing(name, *args, &block)
85
+ objects = @klass.class_variable_get(:@@objects)
86
+ collections = @klass.class_variable_get(:@@collections)
87
+ properties = @klass.class_variable_get(:@@properties)
88
+ if objects.any? { |object| object.name == name }
89
+ object = (objects.select { |object| object.name == name }).first
90
+ object_inst = Kernel.const_get("#{object.type}::DSL").eval(args.first, &block)
91
+ raise "Tried to redefine `#{object.name}'!" if @builder.instance_variable_get(:@sub_objects).include? object.name
92
+ @builder.instance_variable_get(:@sub_objects)[object.name] = object_inst
93
+ object_inst
94
+ elsif collections.any? { |collection| collection.object.name == name }
95
+ collection = (collections.select { |collection| collection.object.name == name }).first
96
+ object = collection.object
97
+ object_inst = Kernel.const_get("#{object.type}::DSL").eval(args.first, &block)
98
+ @builder.instance_variable_get(:@sub_objects)[collection.name] ||= []
99
+ @builder.instance_variable_get(:@sub_objects)[collection.name] << object_inst
100
+ object_inst
101
+ elsif properties.any? { |property| property.name == name }
102
+ property = (properties.select{ |prop| prop.name == name }).first
103
+ raise ArgumentError.new("Excepted sub-properties as a second argument!") if (args.length > 1) && !(args[1].is_a? Hash)
104
+ property_inst = property.type.new(args[0], args[1])
105
+ @builder.instance_variable_get(:@properties).merge!({property.name => property_inst})
106
+ property_inst
107
+ else
108
+ super
109
+ end
110
+ end
111
+ end).new(object_klass, object_builder).instance_eval(&block)
112
+
113
+ object = object_builder.build
114
+ return object
115
+ end
116
+ end
117
+
118
+ def self.included(klass)
119
+ klass.extend(ClassMethods)
120
+ end
121
+ end
122
+
123
+ module ClassMethods
124
+ def object(name, type)
125
+ object_klass = Kernel.const_get(self.name)
126
+ object = OpenStruct.new({:name => name, :type => type})
127
+ object_klass.class_variable_get(:@@objects) << object
128
+ object
129
+ end
130
+
131
+ def collection(name, type, opts={})
132
+ plural = opts[:plural] || "#{name}s"
133
+ object_klass = Kernel.const_get(self.name)
134
+ collection = OpenStruct.new({:name => plural, :object => OpenStruct.new({:name => name, :type => type})})
135
+ object_klass.class_variable_get(:@@collections) << collection
136
+ collection
137
+ end
138
+
139
+ def property(name, type, opts={})
140
+ object_klass = Kernel.const_get(self.name)
141
+ property = Property.new(name, type, opts)
142
+ object_klass.class_variable_get(:@@properties) << property
143
+ property
144
+ end
145
+ end
146
+
147
+ def self.included(klass)
148
+ klass.class_variable_set(:@@objects, [])
149
+ klass.class_variable_set(:@@collections, [])
150
+ klass.class_variable_set(:@@properties, [])
151
+ klass.extend(ClassMethods)
152
+ klass.const_set(:DSL, Class.new do
153
+ include Pidgin::Object::DomainSpecificLanguage
154
+ end)
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,18 @@
1
+ module Pidgin
2
+ class Property
3
+ def initialize(name, type, opts={})
4
+ @name = name
5
+ @type = type
6
+ @inline = opts[:inline] || false
7
+ @sub_properties = []
8
+ (opts[:allow] || {}).each do |sub_prop_name, sub_prop_type|
9
+ @sub_properties << Property.new(sub_prop_name, sub_prop_type)
10
+ end
11
+ end
12
+
13
+ def name; @name; end
14
+ def type; @type; end
15
+ def inline?; @inline; end
16
+ def sub_properties; @sub_properties; end
17
+ end
18
+ end
@@ -1,6 +1,6 @@
1
1
  module Pidgin
2
2
  module VERSION #:nodoc:
3
- MAJOR, MINOR, PATCH, PRE = [0, 0, 0, 'dev']
3
+ MAJOR, MINOR, PATCH, PRE = [0, 0, 1, 'pre']
4
4
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
5
5
  end
6
6
 
@@ -16,11 +16,8 @@ Gem::Specification.new do |s|
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- # TODO(mtwilliams): Handle this gracefuly in `bin/pidgin'.
20
19
  s.require_paths = %w(lib)
21
20
 
22
- s.add_dependency 'docile'
23
-
24
21
  s.add_development_dependency 'rspec'
25
22
  s.add_development_dependency 'cucumber'
26
23
  s.add_development_dependency 'aruba'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pidgin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0.dev
4
+ version: 0.0.1.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: docile
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rspec
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -72,11 +58,14 @@ executables: []
72
58
  extensions: []
73
59
  extra_rdoc_files: []
74
60
  files:
75
- - ".DS_Store"
61
+ - ".gitignore"
76
62
  - Gemfile
63
+ - Gemfile.lock
77
64
  - README.md
78
- - lib/.DS_Store
79
- - lib/pidgin/.DS_Store
65
+ - lib/pidgin.rb
66
+ - lib/pidgin/domain_specific_language.rb
67
+ - lib/pidgin/object.rb
68
+ - lib/pidgin/property.rb
80
69
  - lib/pidgin/version.rb
81
70
  - pidgin.gemspec
82
71
  - pidgin.sublime-project
data/.DS_Store DELETED
Binary file
Binary file
Binary file