circuits 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OWQ4ZDliNDEyMjk5YzVjMzIzOGI3NTNkOWU4MDY2NDNiNjAwMzM2Ng==
5
+ data.tar.gz: !binary |-
6
+ MDM1ZDQ4NmEwNThhMzU4MzU5Yzc4OTU3NDI3MGY1NDRhOTk2NDQ2Nw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTQzZjJiMDhjYzI2NzliYWI0NjQyYWRlYjA2ZjRhYWNiYTJiNDNmNTVjMTY3
10
+ ZmQ4OGZjODg0ZmNlMDRiZDM1NzU3N2Q4MzIzMmJmNjQ0MTM2NjdkNzNiODg3
11
+ NDE3YjU0YjBhZWM1MjQyMjc3MmI0OTE4NjYyZjdmNjhhODlmOGU=
12
+ data.tar.gz: !binary |-
13
+ MmJjZjlkYmExZGM3YmQzYTEzNzkzN2NjMGMwYWZjMzhkNTZhZGU1Y2ZiNjU5
14
+ ZTMyMjMyYjExMTRjYjk3MmVkMjAyMWQwZTM4ODAyMjcxOTM5NTRhZTVmMTk3
15
+ ZWJkYjU5NDdjNmUxM2VlNTdlNWI5NTZiZjc1YzYxYzgzODIzNDU=
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.7
4
+ deploy:
5
+ provider: rubygems
6
+ api_key:
7
+ secure: K2gXdUNvY+lydX07VBbBf+pHab9tqkKjE7/4LL+sq0AJOLl+WSpu7Y1gyPUNNlVNlI8zdD10o0aSAiL30knk9Gff5XLycWZtK7U3oLf0npO0JLas6CeWrs7kVcOkMZkRxTabgDdKUsq37Jj3ROXXY8Y3404Ne9IjUstJl0AS0AQkcIYjThrXGUFfJY5QRx8iPIuDejoVLSgIADgw2tLcmZNwvDy/BucpNg3/HlZbFvZeFIkzqcknY1hmFEKJq55s3Y/Gbr0InAkLxfbRwK6cVBQxaxEV271+o54bj59UAIOiry5Zvxzeb/5r8r37c6eOJx5Yr5dNUy0Nn4fPloseWaKkvAQQEgA15JdYQRvMPJa67i9IaHcOB01+gfFK1gOymGHf+WYCrgRNf5S67MtozIeM42GRwg2z0sTszcSC8YIMs0dDSCqj53aMgGApJH4mguk7dDAB0kpdQHet/B6EvvjA9DDky5qc59WmJSJFGi0JwBWWi+Z3YhCutPa9vLlpGDDyb/j46ZMbhn2KsDwd6hWUusqTxu/HjO9bELCmsPvg9IOEFQ/eCiE834UerOYDWwf7JLelDOFwpQ2qpssmQjSI288gzMM66OWsi2xOaaReZZJyJ40zgOdekvFSR9fzrwStQMdDg3qbdxQZ5q+LWEprjPBev9kdkihNCE9DV9I=
8
+ gem: circuits
9
+ on:
10
+ tags: true
11
+ repo: meringu/circuits
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in circuits.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Henry Muru Paenga
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ [![Build Status](https://travis-ci.org/meringu/circuits.svg?branch=master)](https://travis-ci.org/meringu/circuits)
2
+ [![Coverage Status](https://coveralls.io/repos/meringu/circuits/badge.svg?branch=master&service=github)](https://coveralls.io/github/meringu/circuits?branch=master)
3
+ [![Code Climate](https://codeclimate.com/github/meringu/circuits/badges/gpa.svg)](https://codeclimate.com/github/meringu/circuits)
4
+
5
+ # Circuits
6
+
7
+ Express logical circuits in code!
8
+
9
+ ## How it works
10
+
11
+ You define components in terms of other component's inputs and outputs. Every
12
+ "tick" the components compute their next outputs. In between each "tick" the
13
+ "tock" will update the outputs before the next tick
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'circuits'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install circuits
30
+
31
+ ## Usage
32
+
33
+ ### Using a component
34
+
35
+ ```ruby
36
+ and_gate = Circuits::Component::And.new
37
+ # Set the inputs
38
+ and_gate.inputs[0].set true
39
+ and_gate.inputs[1].set false
40
+ # Update the AND gate
41
+ and_gate.tick # compute the next output from the inputs
42
+ and_gate.tock # apply to the output after all components have "ticked"
43
+ # Get the output
44
+ and_gate.outputs[0].get # false
45
+ ```
46
+
47
+ ### Linking components
48
+
49
+ ```ruby
50
+ and_gate = Circuits::Component::And.new
51
+ not_gate = Circuits::Component::And.new(inputs: [and_gate.outputs[0])
52
+ ```
53
+
54
+ ## Contributing
55
+
56
+ 1. Fork it ( https://github.com/meringu/circuits/fork )
57
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
58
+ 3. Make your changes
59
+ 4. Run the tests (`bundle exec rake`)
60
+ 5. Bump the version ( http://semver.org/ )
61
+ 6. Push to the branch (`git push origin my-new-feature`)
62
+ 7. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/circuits.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'circuits/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'circuits'
8
+ spec.version = Circuits::VERSION
9
+ spec.authors = ['Henry Muru Paenga']
10
+ spec.email = ['meringu@gmail.com']
11
+ spec.summary = 'Express logical circuits in code'
12
+ spec.homepage = 'https://github.com/meringu/circuits'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.7'
21
+ spec.add_development_dependency 'coveralls'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.3'
24
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical AND Operator
6
+ class And
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(inputs.map(&:get).inject(:&))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical NAND Operator
6
+ class Nand
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(!inputs.map(&:get).inject(:&))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical NOR Operator
6
+ class Nor
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(!inputs.map(&:get).inject(:|))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical NOT Operator
6
+ class Not
7
+ include Component
8
+
9
+ def input_count
10
+ 1
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(!inputs[0].get)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical OR Operator
6
+ class Or
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(inputs.map(&:get).inject(:|))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # SR NOR Latch
6
+ class SrNor
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 2
15
+ end
16
+
17
+ def tick
18
+ 2.times.each do
19
+ sub_components.each(&:tick)
20
+ sub_components.each(&:tock)
21
+ end
22
+ outputs[0].set nor_1.outputs[0].get
23
+ outputs[1].set nor_2.outputs[0].get
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :nor_1, :nor_2, :sub_components
29
+
30
+ def setup
31
+ @nor_1 = Nor.new(inputs: [inputs[0]])
32
+ @nor_2 = Nor.new(inputs: [inputs[1]])
33
+ @sub_components = [@nor_1, @nor_2]
34
+ nor_1.inputs << nor_2.outputs[0]
35
+ nor_2.inputs << nor_1.outputs[0]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical XNOR Operator
6
+ class Xnor
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(inputs[0].get == inputs[1].get)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'circuits/component'
2
+
3
+ module Circuits
4
+ module Component
5
+ # Logical XOR Operator
6
+ class Xor
7
+ include Component
8
+
9
+ def input_count
10
+ 2
11
+ end
12
+
13
+ def output_count
14
+ 1
15
+ end
16
+
17
+ def tick
18
+ outputs[0].set(inputs[0].get != inputs[1].get)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ require 'circuits/terminal/input'
2
+ require 'circuits/terminal/output'
3
+
4
+ module Circuits
5
+ # A component has a set of inputs an outputs. Every `tick` a componnent
6
+ # computes its outputs, but the componnent will wait for the `tock` before the
7
+ # componnent updates its own outputs
8
+ module Component
9
+ def initialize(opts = {})
10
+ @inputs = opts[:inputs] ||
11
+ input_count.times.collect { Circuits::Terminal::Input.new }
12
+ @outputs = output_count.times.collect { Circuits::Terminal::Output.new }
13
+ setup
14
+ end
15
+
16
+ attr_reader :inputs, :outputs
17
+
18
+ def input_count
19
+ fail NotImplementedError
20
+ end
21
+
22
+ def output_count
23
+ fail NotImplementedError
24
+ end
25
+
26
+ def setup
27
+ end
28
+
29
+ def tick
30
+ fail NotImplementedError
31
+ end
32
+
33
+ def tock
34
+ outputs.each(&:tock)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ module Circuits
2
+ module Terminal
3
+ # Reads from a single output, only assigned to one component
4
+ class Input
5
+ def initialize(opts = {})
6
+ @output = opts[:output] || Circuits::Terminal::Output.new
7
+ end
8
+
9
+ attr_accessor :output
10
+
11
+ def get
12
+ output.get
13
+ end
14
+
15
+ def set(s)
16
+ @output = Circuits::Terminal::Output.new(state: s)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Circuits
2
+ module Terminal
3
+ # Owned by a single component, gets set for reading by inputs
4
+ class Output
5
+ def initialize(opts = {})
6
+ @next_state = opts[:state] || false
7
+ @state = opts[:state] || false
8
+ end
9
+
10
+ def get
11
+ state
12
+ end
13
+
14
+ def set(s)
15
+ @next_state = s
16
+ end
17
+
18
+ def tock
19
+ @state = next_state
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :state, :next_state
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ # Circuits allows you to express logical circuits in code
2
+ module Circuits
3
+ VERSION = '0.2.2'
4
+ end
data/lib/circuits.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'circuits/component/and'
2
+ require 'circuits/component/nand'
3
+ require 'circuits/component/nor'
4
+ require 'circuits/component/not'
5
+ require 'circuits/component/or'
6
+ require 'circuits/component/sr_nor'
7
+ require 'circuits/component/xnor'
8
+ require 'circuits/component/xor'
9
+
10
+ require 'circuits/version'
@@ -0,0 +1,2 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/and'
3
+
4
+ describe Circuits::Component::And do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::And.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= false' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(false)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= false' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(false)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= false' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(false)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= true' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(true)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/nand'
3
+
4
+ describe Circuits::Component::Nand do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::Nand.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= true' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(true)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= true' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(true)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= true' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(true)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= false' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(false)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/nor'
3
+
4
+ describe Circuits::Component::Nor do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::Nor.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= true' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(true)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= false' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(false)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= false' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(false)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= false' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(false)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/not'
3
+
4
+ describe Circuits::Component::Not do
5
+ describe '#tick' do
6
+ subject { Circuits::Component::Not.new }
7
+
8
+ before { subject.inputs[0].set input }
9
+
10
+ context '!false' do
11
+ let(:input) { false }
12
+
13
+ it '= true' do
14
+ subject.tick
15
+ subject.tock
16
+ expect(subject.outputs[0].get).to eq(true)
17
+ end
18
+ end
19
+
20
+ context '!true' do
21
+ let(:input) { true }
22
+
23
+ it '= false' do
24
+ subject.tick
25
+ subject.tock
26
+ expect(subject.outputs[0].get).to eq(false)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/or'
3
+
4
+ describe Circuits::Component::Or do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::Or.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= false' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(false)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= true' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(true)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= true' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(true)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= true' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(true)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/sr_nor'
3
+
4
+ describe Circuits::Component::SrNor do
5
+ describe '#tick' do
6
+ subject { Circuits::Component::SrNor.new }
7
+
8
+ context 'is set' do
9
+ before do
10
+ subject.inputs[0].set false
11
+ subject.inputs[1].set true
12
+ subject.tick
13
+ subject.tock
14
+ subject.inputs[1].set false
15
+ end
16
+
17
+ it 'is set' do
18
+ expect(subject.outputs[0].get).to eq(true)
19
+ expect(subject.outputs[1].get).to eq(false)
20
+ end
21
+
22
+ it 'is stable' do
23
+ subject.tick
24
+ subject.tock
25
+ expect(subject.outputs[0].get).to eq(true)
26
+ expect(subject.outputs[1].get).to eq(false)
27
+ end
28
+
29
+ it 'can be reset' do
30
+ subject.inputs[0].set true
31
+ subject.tick
32
+ subject.tock
33
+ expect(subject.outputs[0].get).to eq(false)
34
+ expect(subject.outputs[1].get).to eq(true)
35
+ end
36
+ end
37
+
38
+ context 'is reset' do
39
+ before do
40
+ subject.inputs[0].set true
41
+ subject.inputs[1].set false
42
+ subject.tick
43
+ subject.tock
44
+ subject.inputs[0].set false
45
+ end
46
+
47
+ it 'is reset' do
48
+ expect(subject.outputs[0].get).to eq(false)
49
+ expect(subject.outputs[1].get).to eq(true)
50
+ end
51
+
52
+ it 'is stable' do
53
+ subject.tick
54
+ subject.tock
55
+ expect(subject.outputs[0].get).to eq(false)
56
+ expect(subject.outputs[1].get).to eq(true)
57
+ end
58
+
59
+ it 'can be set' do
60
+ subject.inputs[1].set true
61
+ subject.tick
62
+ subject.tock
63
+ expect(subject.outputs[0].get).to eq(true)
64
+ expect(subject.outputs[1].get).to eq(false)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/xnor'
3
+
4
+ describe Circuits::Component::Xnor do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::Xnor.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= true' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(true)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= false' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(false)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= false' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(false)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= true' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(true)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component/xor'
3
+
4
+ describe Circuits::Component::Xor do
5
+ describe '#tick' do
6
+ context 'default input count' do
7
+ subject { Circuits::Component::Xor.new }
8
+
9
+ before do
10
+ subject.inputs[0].set input_1
11
+ subject.inputs[1].set input_2
12
+ end
13
+
14
+ context 'false + false' do
15
+ let(:input_1) { false }
16
+ let(:input_2) { false }
17
+
18
+ it '= false' do
19
+ subject.tick
20
+ subject.tock
21
+ expect(subject.outputs[0].get).to eq(false)
22
+ end
23
+ end
24
+
25
+ context 'true + false' do
26
+ let(:input_1) { true }
27
+ let(:input_2) { false }
28
+
29
+ it '= true' do
30
+ subject.tick
31
+ subject.tock
32
+ expect(subject.outputs[0].get).to eq(true)
33
+ end
34
+ end
35
+
36
+ context 'false + true' do
37
+ let(:input_1) { false }
38
+ let(:input_2) { true }
39
+
40
+ it '= true' do
41
+ subject.tick
42
+ subject.tock
43
+ expect(subject.outputs[0].get).to eq(true)
44
+ end
45
+ end
46
+
47
+ context 'true + true' do
48
+ let(:input_1) { true }
49
+ let(:input_2) { true }
50
+
51
+ it '= false' do
52
+ subject.tick
53
+ subject.tock
54
+ expect(subject.outputs[0].get).to eq(false)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'circuits/component'
3
+
4
+ # Mock component to include Circuits::Component for function accessability
5
+ class MockComponent
6
+ include Circuits::Component
7
+
8
+ def initialize(opts = {})
9
+ @outputs = opts[:outputs]
10
+ end
11
+ end
12
+
13
+ describe Circuits::Component do
14
+ subject { MockComponent.new }
15
+
16
+ describe '#input_count' do
17
+ it 'is not implemented' do
18
+ expect { subject.input_count }.to raise_error(NotImplementedError)
19
+ end
20
+ end
21
+
22
+ describe '#output_count' do
23
+ it 'is not implemented' do
24
+ expect { subject.output_count }.to raise_error(NotImplementedError)
25
+ end
26
+ end
27
+
28
+ describe '#tick' do
29
+ it 'is not implemented' do
30
+ expect { subject.tick }.to raise_error(NotImplementedError)
31
+ end
32
+ end
33
+
34
+ describe '#tock' do
35
+ let(:outputs) { [double('output')] }
36
+
37
+ subject { MockComponent.new(outputs: outputs) }
38
+
39
+ it 'tocks the outputs' do
40
+ expect(outputs[0]).to receive(:tock)
41
+ subject.tock
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'circuits/terminal/input'
3
+
4
+ module Circuits
5
+ module Terminal
6
+ class Output
7
+ end
8
+ end
9
+ end
10
+
11
+ describe Circuits::Terminal::Input do
12
+ let(:output) { double('output') }
13
+
14
+ describe '#output' do
15
+ context 'when given an output' do
16
+ subject { Circuits::Terminal::Input.new(output: output) }
17
+
18
+ it 'sets the output' do
19
+ expect(subject.output).to eq(output)
20
+ end
21
+ end
22
+
23
+ context 'when not given an output' do
24
+ subject { Circuits::Terminal::Input.new }
25
+
26
+ before do
27
+ expect(Circuits::Terminal::Output).to receive(:new).and_return(output)
28
+ end
29
+
30
+ it 'sets the output' do
31
+ expect(subject.output).to eq(output)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#get' do
37
+ let(:res) { double('res') }
38
+
39
+ subject { Circuits::Terminal::Input.new(output: output) }
40
+
41
+ it 'forwards the request to output' do
42
+ expect(output).to receive(:get).and_return(res)
43
+ expect(subject.get).to eq(res)
44
+ end
45
+ end
46
+
47
+ describe '#set' do
48
+ let(:state) { double('state') }
49
+ let(:new_output) { double('new_output', get: state) }
50
+
51
+ subject { Circuits::Terminal::Input.new(output: output) }
52
+
53
+ it 'sets the output to the passed output' do
54
+ expect(Circuits::Terminal::Output).to receive(:new)
55
+ .with(state: state).and_return(new_output)
56
+ subject.set state
57
+ expect(subject.get).to eq(state)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'circuits/terminal/output'
3
+
4
+ describe Circuits::Terminal::Output do
5
+ describe '#get' do
6
+ context 'when given no state' do
7
+ subject { Circuits::Terminal::Output.new }
8
+
9
+ it 'is false' do
10
+ expect(subject.get).to eq(false)
11
+ end
12
+ end
13
+
14
+ context 'when given false state' do
15
+ subject { Circuits::Terminal::Output.new(state: false) }
16
+
17
+ it 'is false' do
18
+ expect(subject.get).to eq(false)
19
+ end
20
+ end
21
+
22
+ context 'when given true state' do
23
+ subject { Circuits::Terminal::Output.new(state: true) }
24
+
25
+ it 'is true' do
26
+ expect(subject.get).to eq(true)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#set' do
32
+ let(:state_1) { double('state_1') }
33
+ let(:state_2) { double('state_2') }
34
+
35
+ subject { Circuits::Terminal::Output.new(state: state_1) }
36
+
37
+ it 'does not set get immediately' do
38
+ subject.set state_2
39
+ expect(subject.get).to eq(state_1)
40
+ end
41
+ end
42
+
43
+ describe '#tock' do
44
+ let(:state) { double('state') }
45
+
46
+ subject { Circuits::Terminal::Output.new }
47
+
48
+ it 'moves next set to get' do
49
+ subject.set state
50
+ subject.tock
51
+ expect(subject.get).to eq(state)
52
+ end
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: circuits
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Henry Muru Paenga
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coveralls
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ description:
70
+ email:
71
+ - meringu@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - .travis.yml
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - circuits.gemspec
84
+ - lib/circuits.rb
85
+ - lib/circuits/component.rb
86
+ - lib/circuits/component/and.rb
87
+ - lib/circuits/component/nand.rb
88
+ - lib/circuits/component/nor.rb
89
+ - lib/circuits/component/not.rb
90
+ - lib/circuits/component/or.rb
91
+ - lib/circuits/component/sr_nor.rb
92
+ - lib/circuits/component/xnor.rb
93
+ - lib/circuits/component/xor.rb
94
+ - lib/circuits/terminal/input.rb
95
+ - lib/circuits/terminal/output.rb
96
+ - lib/circuits/version.rb
97
+ - spec/spec_helper.rb
98
+ - spec/unit/circuits/component/and_spec.rb
99
+ - spec/unit/circuits/component/nand_spec.rb
100
+ - spec/unit/circuits/component/nor_spec.rb
101
+ - spec/unit/circuits/component/not_spec.rb
102
+ - spec/unit/circuits/component/or_spec.rb
103
+ - spec/unit/circuits/component/sr_nor_spec.rb
104
+ - spec/unit/circuits/component/xnor_spec.rb
105
+ - spec/unit/circuits/component/xor_spec.rb
106
+ - spec/unit/circuits/component_spec.rb
107
+ - spec/unit/circuits/terminal/input_spec.rb
108
+ - spec/unit/circuits/terminal/output_spec.rb
109
+ homepage: https://github.com/meringu/circuits
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.5
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Express logical circuits in code
133
+ test_files:
134
+ - spec/spec_helper.rb
135
+ - spec/unit/circuits/component/and_spec.rb
136
+ - spec/unit/circuits/component/nand_spec.rb
137
+ - spec/unit/circuits/component/nor_spec.rb
138
+ - spec/unit/circuits/component/not_spec.rb
139
+ - spec/unit/circuits/component/or_spec.rb
140
+ - spec/unit/circuits/component/sr_nor_spec.rb
141
+ - spec/unit/circuits/component/xnor_spec.rb
142
+ - spec/unit/circuits/component/xor_spec.rb
143
+ - spec/unit/circuits/component_spec.rb
144
+ - spec/unit/circuits/terminal/input_spec.rb
145
+ - spec/unit/circuits/terminal/output_spec.rb