RSpec – Filtering ”; Previous Next You may want to read the section on RSpec Metadata before reading this section because, as it turns out, RSpec filtering is based on RSpec Metadata. Imagine that you have a spec file and it contains two types of tests (Examples): positive functional tests and negative (error) tests. Let’s define them like this − RSpec.describe “An Example Group with positive and negative Examples” do context ”when testing Ruby”s build-in math library” do it ”can do normal numeric operations” do expect(1 + 1).to eq(2) end it ”generates an error when expected” do expect{1/0}.to raise_error(ZeroDivisionError) end end end Now, save the above text as a file called ‘filter_spec.rb’ and then run it with this command − rspec filter_spec.rb You will see output that looks something like this − .. Finished in 0.003 seconds (files took 0.11201 seconds to load) 2 examples, 0 failures Now what if, we wanted to re-run only the positive tests in this file? Or only the negative tests? We can easily do that with RSpec Filters. Change the above code to this − RSpec.describe “An Example Group with positive and negative Examples” do context ”when testing Ruby”s build-in math library” do it ”can do normal numeric operations”, positive: true do expect(1 + 1).to eq(2) end it ”generates an error when expected”, negative: true do expect{1/0}.to raise_error(ZeroDivisionError) end end end Save your changes to filter_spec.rb and run this slightly different command − rspec –tag positive filter_spec.rb Now, you will see output that looks like this − Run options: include {:positive=>true} . Finished in 0.001 seconds (files took 0.11401 seconds to load) 1 example, 0 failures By specifying –tag positive, we’re telling RSpec to only run Examples with the: positive metadata variable defined. We could do the same thing with negative tests by running the command like this − rspec –tag negative filter_spec.rb Keep in mind that these are just examples, you can specify a filter with any name that you want. RSpec Formatters Formatters allow RSpec to display the output from tests in different ways. Let’s create a new RSpec file containing this code − RSpec.describe “A spec file to demonstrate how RSpec Formatters work” do context ”when running some tests” do it ”the test usually calls the expect() method at least once” do expect(1 + 1).to eq(2) end end end Now, save this to a file called formatter_spec.rb and run this RSpec command − rspec formatter_spec.rb You should see output that looks like this − . Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures Now run the same command but this time specify a formatter, like this − rspec –format progress formatter_spec.rb You should see the same output this time − . Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures The reason is that the “progress” formatter is the default formatter. Let’s try a different formatter next, try running this command − rspec –format doc formatter_spec.rb Now you should see this output − A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Finished in 0.002 seconds (files took 0.11401 seconds to load) 1 example, 0 failures As you can see, the output is quite different with the “doc” formatter. This formatter presents the output in a documentation-like style. You might be wondering what these options look like when you have a failure in a test (Example). Let’s change the code in formatter_spec.rb to look like this − RSpec.describe “A spec file to demonstrate how RSpec Formatters work” do context ”when running some tests” do it ”the test usually calls the expect() method at least once” do expect(1 + 1).to eq(1) end end end The expectation expect(1 + 1).to eq(1) should fail. Save your changes and re-run the above commands − rspec –format progress formatter_spec.rb and remember, since the “progress” formatter is the default, you could just run: rspec formatter_spec.rb. You should see this output − F Failures: 1) A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Failure/Error: expect(1 + 1).to eq(1) expected: 1 got: 2 (compared using ==) # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>” Finished in 0.016 seconds (files took 0.11201 seconds to load) 1 example, 1 failure Failed examples: rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Now, let’s try the doc formatter, run this command − rspec –format doc formatter_spec.rb Now, with the failed test, you should see this output − A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once (FAILED – 1) Failures: 1) A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once Failure/Error: expect(1 + 1).to eq(1) expected: 1 got: 2 (compared using ==) # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>” Finished in 0.015 seconds (files took 0.11401 seconds to load) 1 example, 1 failure Failed Examples rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec Formatters work when running some tests the test usually calls the expect() method at least once. RSpec Formatters offer the ability to change the way test results display, it is even possible to create your own custom Formatter, but that is a more advanced topic. Print Page Previous Next Advertisements ”;
Category: Computer Programming
RSpec – Quick Guide
RSpec – Quick Guide ”; Previous Next RSpec – Introduction RSpec is a unit test framework for the Ruby programming language. RSpec is different than traditional xUnit frameworks like JUnit because RSpec is a Behavior driven development tool. What this means is that, tests written in RSpec focus on the “behavior” of an application being tested. RSpec does not put emphasis on, how the application works but instead on how it behaves, in other words, what the application actually does. RSpec Environment First of all, you will need to install Ruby on your computer. However, if you haven’t already done earlier, then you can download and install Ruby from the main Ruby website − Ruby. If you are installing Ruby on Windows, you should have the Ruby installer for Windows here at − http://www.rubyinstaller.org For this tutorial, you will only need text editor, such as Notepad and a command line console. The examples here will use cmd.exe on Windows. To run cmd.exe, simply click on the Start menu and type “cmd.exe”, then hit the Return key. At the command prompt in your cmd.exe window, type the following command to see what version of Ruby you are using − ruby -v You should see the below output that looks similar to this − ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32] The examples in this tutorial will use Ruby 2.2.3 but any version of Ruby higher than 2.0.0 will suffice. Next, we need to install the RSpec gem for your Ruby installation. A gem is a Ruby library which you can use in your own code. In order to install a gem, you need to use the gem command. Let’s install the Rspec gem now. Go back to your cmd.exe Window and type the following − gem install rspec You should have a list of dependent gems that were installed, these are gems that the rspec gem needs to function correctly. At the end of the output, you should see something that looks like this − Done installing documentation for diff-lcs, rspec-support, rspec-mocks, rspec-expectations, rspec-core, rspec after 22 seconds 6 gems installed Do not worry, if your output does not look exactly the same. Also, if you are using a Mac or Linux computer, you may need to either run gem install rspec command using sudo or use a tool like HomeBrew or RVM to install the rspec gem. Hello World To get started, let’s create a directory (folder) to store our RSpec files. In your cmd.exe window, type the following − cd Then type − mkdir rspec_tutorial And finally, type − cd rspec_tutorial From here, we’re going to create another directory named spec, do that by typing − mkdir spec We are going to store our RSpec files in this folder. RSpec files are known as “specs”. If this seems confusing to you, you can think of a spec file as a test file. RSpec uses the term “spec” which is a short form for “specification”. Since, RSpec is a BDD test tool, the goal is to focus on what the application does and whether or not it follows a specification. In behavior driven development, the specification is often described in terms of a “User Story”. RSpec is designed to make it clear whether the target code is behaving correctly, in other words following the specification. Let’s return to our Hello World code. Open a text editor and add the following code − class HelloWorld def say_hello “Hello World!” end end describe HelloWorld do context “When testing the HelloWorld class” do it “should say ”Hello World” when we call the say_hello method” do hw = HelloWorld.new message = hw.say_hello expect(message).to eq “Hello World!” end end end Next, save this to a file named hello_world_spec.rb in the spec folder that you created above. Now back in your cmd.exe window, run this command − rspec spec spechello_world_spec.rb When the command completes, you should see output that looks like this − Finished in 0.002 seconds (files took 0.11101 seconds to load) 1 example, 0 failures Congratulations, you just created and ran your first RSpec unit test! In the next section, we will continue to discuss the syntax of RSpec files. RSpec – Basic Syntax Let’s take a closer look at the code of our HelloWorld example. First of all, in case it isn’t clear, we are testing the functionality of the HelloWorld class. This of course, is a very simple class that contains only one method say_hello(). Here is the RSpec code again − describe HelloWorld do context “When testing the HelloWorld class” do it “The say_hello method should return ”Hello World”” do hw = HelloWorld.new message = hw.say_hello expect(message).to eq “Hello World!” end end end The describe Keyword The word describe is an RSpec keyword. It is used to define an “Example Group”. You can think of an “Example Group” as a collection of tests. The describe keyword can take a class name and/or string argument. You also need to pass a block argument to describe, this will contain the individual tests, or as they are known in RSpec, the “Examples”. The block is just a Ruby block designated by the Ruby do/end keywords. The context Keyword The context keyword is similar to describe. It too can accept a class name and/or string argument. You should use a block with context as well. The idea of context is that it encloses tests of a certain type. For example, you can specify groups of Examples with different contexts like this − context “When passing bad parameters to the foobar() method” context “When passing valid parameters to the foobar() method” context “When testing corner cases with the foobar() method” The context keyword is not mandatory, but it helps to add more details about the examples that it contains. The it Keyword The word it is another RSpec keyword which is used to define an “Example”. An example is basically a test or a test case. Again, like describe and context, it accepts
Rexx – Environment
Rexx – Environment ”; Previous Next Before you can start working on Rexx, you need to ensure that you have a fully functional version of Rexx running on your system. This chapter will explain the installation of Rexx and its subsequent configuration on a Windows machine to get started with Rexx. Ensure the following System requirements are met before proceeding with the installation. System Requirements Memory 2 GB RAM (recommended) Disk Space No minimum requirement. Preferably to have enough storage to store the programs which will be created using Rexx. Operating System Version Rexx can be installed on Windows, Ubuntu/Debian, Mac OS X. Downloading Rexx To download Rexx, you should use the following URL − https://www.oorexx.org/download.html This page has a variety of downloads for various versions of Rexx as shown in the following screenshot. Click on the ‘ooRexx install files’ in the table with the header of Release 4.2.0. After this, you will be re-directed to the following page. Click on the ooRexx-4.2.0.windows.x86_64.exe to download the 64-bit version of the software. We will discuss regarding the installation of the software in the following chapter. Print Page Previous Next Advertisements ”;
Prolog – Built-In Predicates
Prolog – Built-In Predicates ”; Previous Next In Prolog, we have seen the user defined predicates in most of the cases, but there are some built-in-predicates. There are three types of built-in predicates as given below − Identifying terms Decomposing structures Collecting all solutions So this is the list of some predicates that are falls under the identifying terms group − Predicate Description var(X) succeeds if X is currently an un-instantiated variable. novar(X) succeeds if X is not a variable, or already instantiated atom(X) is true if X currently stands for an atom number(X) is true if X currently stands for a number integer(X) is true if X currently stands for an integer float(X) is true if X currently stands for a real number. atomic(X) is true if X currently stands for a number or an atom. compound(X) is true if X currently stands for a structure. ground(X) succeeds if X does not contain any un-instantiated variables. The var(X) Predicate When X is not initialized, then, it will show true, otherwise false. So let us see an example. Example | ?- var(X). yes | ?- X = 5, var(X). no | ?- var([X]). no | ?- The novar(X) Predicate When X is not initialized, the, it will show false, otherwise true. So let us see an example. Example | ?- nonvar(X). no | ?- X = 5,nonvar(X). X = 5 yes | ?- nonvar([X]). yes | ?- The atom(X) Predicate This will return true, when a non-variable term with 0 argument and a not numeric term is passed as X, otherwise false. Example | ?- atom(paul). yes | ?- X = paul,atom(X). X = paul yes | ?- atom([]). yes | ?- atom([a,b]). no | ?- The number(X) Predicate This will return true, X stands for any number, otherwise false. Example | ?- number(X). no | ?- X=5,number(X). X = 5 yes | ?- number(5.46). yes | ?- The integer(X) Predicate This will return true, when X is a positive or negative integer value, otherwise false. Example | ?- integer(5). yes | ?- integer(5.46). no | ?- The float(X) Predicate This will return true, X is a floating point number, otherwise false. Example | ?- float(5). no | ?- float(5.46). yes | ?- The atomic(X) Predicate We have atom(X), that is too specific, it returns false for numeric data, the atomic(X) is like atom(X) but it accepts number. Example | ?- atom(5). no | ?- atomic(5). yes | ?- The compound(X) Predicate If atomic(X) fails, then the terms are either one non-instantiated variable (that can be tested with var(X)) or a compound term. Compound will be true when we pass some compound structure. Example | ?- compound([]). no | ?- compound([a]). yes | ?- compound(b(a)). yes | ?- The ground(X) Predicate This will return true, if X does not contain any un-instantiated variables. This also checks inside the compound terms, otherwise returns false. Example | ?- ground(X). no | ?- ground(a(b,X)). no | ?- ground(a). yes | ?- ground([a,b,c]). yes | ?- Decomposing Structures Now we will see, another group of built-in predicates, that is Decomposing structures. We have seen the identifying terms before. So when we are using compound structures we cannot use a variable to check or make a functor. It will return error. So functor name cannot be represented by a variable. Error X = tree, Y = X(maple). Syntax error Y=X>(maple) Now, let us see some inbuilt predicates that falls under the Decomposing structures group. The functor(T,F,N) Predicate This returns true if F is the principal functor of T, and N is the arity of F. Note − Arity means the number of attributes. Example | ?- functor(t(f(X),a,T),Func,N). Func = t N = 3 (15 ms) yes | ?- The arg(N,Term,A) Predicate This returns true if A is the Nth argument in Term. Otherwise returns false. Example | ?- arg(1,t(t(X),[]),A). A = t(X) yes | ?- arg(2,t(t(X),[]),A). A = [] yes | ?- Now, let us see another example. In this example, we are checking that the first argument of D will be 12, the second argument will be apr and the third argument will be 2020. Example | ?- functor(D,date,3), arg(1,D,12), arg(2,D,apr), arg(3,D,2020). D = date(12,apr,2020) yes | ?- The ../2 Predicate This is another predicate represented as double dot (..). This takes 2 arguments, so ‘/2’ is written. So Term = .. L, this is true if L is a list that contains the functor of Term, followed by its arguments. Example | ?- f(a,b) =.. L. L = [f,a,b] yes | ?- T =.. [is_blue,sam,today]. T = is_blue(sam,today) yes | ?- By representing the component of a structure as a list, they can be recursively processed without knowing the functor name. Let us see another example − Example | ?- f(2,3)=..[F,N|Y], N1 is N*3, L=..[F,N1|Y]. F = f L = f(6,3) N = 2 N1 = 6 Y = [3] yes | ?- Collecting All Solutions Now let us see the third category called the collecting all solutions, that falls under built-in predicates in Prolog. We have seen that to generate all of the given solutions of a given goal using the semicolon in the prompt. So here is an example of it. Example | ?- member(X, [1,2,3,4]). X = 1 ? ; X = 2 ? ; X = 3 ? ; X = 4 yes Sometimes, we need to generate all of the solutions to some goal within a program in some AI related applications. So there are three built-in predicates that will help us to get the results. These predicates are as follows − findall/3 setoff/3 bagof/3 These three predicates take three arguments, so we have written ‘/3’ after the name of the predicates. These are also known as meta-predicates. These
RSpec – Matchers
RSpec – Matchers ”; Previous Next If you recall our original Hello World example, it contained a line that looked like this − expect(message).to eq “Hello World!” The keyword eql is an RSpec “matcher”. Here, we will introduce the other types of matchers in RSpec. Equality/Identity Matchers Matchers to test for object or value equality. Matcher Description Example eq Passes when actual == expected expect(actual).to eq expected eql Passes when actual.eql?(expected) expect(actual).to eql expected be Passes when actual.equal?(expected) expect(actual).to be expected equal Also passes when actual.equal?(expected) expect(actual).to equal expected Example describe “An example of the equality Matchers” do it “should show how the equality Matchers work” do a = “test string” b = a # The following Expectations will all pass expect(a).to eq “test string” expect(a).to eql “test string” expect(a).to be b expect(a).to equal b end end When the above code is executed, it will produce the following output. The number of seconds may be slightly different on your computer − . Finished in 0.036 seconds (files took 0.11901 seconds to load) 1 example, 0 failures Comparison Matchers Matchers for comparing to values. Matcher Description Example > Passes when actual > expected expect(actual).to be > expected >= Passes when actual >= expected expect(actual).to be >= expected < Passes when actual < expected expect(actual).to be < expected <= Passes when actual <= expected expect(actual).to be <= expected be_between inclusive Passes when actual is <= min and >= max expect(actual).to be_between(min, max).inclusive be_between exclusive Passes when actual is < min and > max expect(actual).to be_between(min, max).exclusive match Passes when actual matches a regular expression expect(actual).to match(/regex/) Example describe “An example of the comparison Matchers” do it “should show how the comparison Matchers work” do a = 1 b = 2 c = 3 d = ”test string” # The following Expectations will all pass expect(b).to be > a expect(a).to be >= a expect(a).to be < b expect(b).to be <= b expect(c).to be_between(1,3).inclusive expect(b).to be_between(1,3).exclusive expect(d).to match /TEST/i end end When the above code is executed, it will produce the following output. The number of seconds may be slightly different on your computer − . Finished in 0.013 seconds (files took 0.11801 seconds to load) 1 example, 0 failures Class/Type Matchers Matchers for testing the type or class of objects. Matcher Description Example be_instance_of Passes when actual is an instance of the expected class. expect(actual).to be_instance_of(Expected) be_kind_of Passes when actual is an instance of the expected class or any of its parent classes. expect(actual).to be_kind_of(Expected) respond_to Passes when actual responds to the specified method. expect(actual).to respond_to(expected) Example describe “An example of the type/class Matchers” do it “should show how the type/class Matchers work” do x = 1 y = 3.14 z = ”test string” # The following Expectations will all pass expect(x).to be_instance_of Fixnum expect(y).to be_kind_of Numeric expect(z).to respond_to(:length) end end When the above code is executed, it will produce the following output. The number of seconds may be slightly different on your computer − . Finished in 0.002 seconds (files took 0.12201 seconds to load) 1 example, 0 failures True/False/Nil Matchers Matchers for testing whether a value is true, false or nil. Matcher Description Example be true Passes when actual == true expect(actual).to be true be false Passes when actual == false expect(actual).to be false be_truthy Passes when actual is not false or nil expect(actual).to be_truthy be_falsey Passes when actual is false or nil expect(actual).to be_falsey be_nil Passes when actual is nil expect(actual).to be_nil Example describe “An example of the true/false/nil Matchers” do it “should show how the true/false/nil Matchers work” do x = true y = false z = nil a = “test string” # The following Expectations will all pass expect(x).to be true expect(y).to be false expect(a).to be_truthy expect(z).to be_falsey expect(z).to be_nil end end When the above code is executed, it will produce the following output. The number of seconds may be slightly different on your computer − . Finished in 0.003 seconds (files took 0.12301 seconds to load) 1 example, 0 failures Error Matchers Matchers for testing, when a block of code raises an error. Matcher Description Example raise_error(ErrorClass) Passes when the block raises an error of type ErrorClass. expect {block}.to raise_error(ErrorClass) raise_error(“error message”) Passes when the block raise an error with the message “error message”. expect {block}.to raise_error(“error message”) raise_error(ErrorClass, “error message”) Passes when the block raises an error of type ErrorClass with the message “error message” expect {block}.to raise_error(ErrorClass,“error message”) Example Save the following code to a file with the name error_matcher_spec.rb and run it with this command − rspec error_matcher_spec.rb. describe “An example of the error Matchers” do it “should show how the error Matchers work” do # The following Expectations will all pass expect { 1/0 }.to raise_error(ZeroDivisionError) expect { 1/0 }.to raise_error(“divided by 0”) expect { 1/0 }.to raise_error(“divided by 0″, ZeroDivisionError) end end When the above code is executed, it will produce the following output. The number of seconds may be slightly different on your computer − . Finished in 0.002 seconds (files took 0.12101 seconds to load) 1 example, 0 failures Print Page Previous Next Advertisements ”;
RSpec – Subjects
RSpec – Subjects ”; Previous Next One of RSpec’s strengths is that it provides many ways to write tests, clean tests. When your tests are short and uncluttered, it becomes easier to focus on the expected behavior and not on the details of how the tests are written. RSpec Subjects are yet another shortcut allowing you to write simple straightforward tests. Consider this code − class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end end describe Person do it ”create a new person with a first and last name” do person = Person.new ”John”, ”Smith” expect(person).to have_attributes(first_name: ”John”) expect(person).to have_attributes(last_name: ”Smith”) end end It’s actually pretty clear as is, but we could use RSpec’s subject feature to reduce the amount of code in the example. We do that by moving the person object instantiation into the describe line. class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end end describe Person.new ”John”, ”Smith” do it { is_expected.to have_attributes(first_name: ”John”) } it { is_expected.to have_attributes(last_name: ”Smith”) } end When you run this code, you will see this output − .. Finished in 0.003 seconds (files took 0.11201 seconds to load) 2 examples, 0 failures Note, how much simpler the second code sample is. We took the one it block in the first example and replaced it with two it blocks which end up requiring less code and are just as clear. Print Page Previous Next Advertisements ”;
RSpec – Hooks
RSpec – Hooks ”; Previous Next When you are writing unit tests, it is often convenient to run setup and teardown code before and after your tests. Setup code is the code that configures or “sets up” conditions for a test. Teardown code does the cleanup, it makes sure that the environment is in a consistent state for subsequent tests. Generally speaking, your tests should be independent of each other. When you run an entire suite of tests and one of them fails, you want to have confidence that it failed because the code that it is testing has a bug, not because the previous test left the environment in an inconsistent state. The most common hooks used in RSpec are before and after hooks. They provide a way to define and run the setup and teardown code we discussed above. Let’s consider this example code − class SimpleClass attr_accessor :message def initialize() puts “nCreating a new instance of the SimpleClass class” @message = ”howdy” end def update_message(new_message) @message = new_message end end describe SimpleClass do before(:each) do @simple_class = SimpleClass.new end it ”should have an initial message” do expect(@simple_class).to_not be_nil @simple_class.message = ”Something else. . .” end it ”should be able to change its message” do @simple_class.update_message(”a new message”) expect(@simple_class.message).to_not be ”howdy” end end When you run this code, you’ll get the following output − Creating a new instance of the SimpleClass class . Creating a new instance of the SimpleClass class . Finished in 0.003 seconds (files took 0.11401 seconds to load) 2 examples, 0 failures Let’s take a closer look at what’s happening. The before(:each) method is where we define the setup code. When you pass the :each argument, you are instructing the before method to run before each example in your Example Group i.e. the two it blocks inside the describe block in the code above. In the line: @simple_class = SimpleClass.new, we are creating a new instance of the SimpleClass class and assigning it to an instance variable of an object. What object you might be wondering? RSpec creates a special class behind the scenes in the scope of the describe block. This allows you to assign values to instance variables of this class, that you can access within the it blocks in your Examples. This also makes it easy to write cleaner code in our tests. If each test (Example) needs an instance of SimpleClass, we can put that code in the before hook and not have to add it to each example. Notice that, the line “Creating a new instance of the SimpleClass class” is written to the console twice, this shows that, before hook was called in each of the it blocks. As we’ve mentioned, RSpec also has an after hook and both the before and after hooks can take: all as an argument. The after hook will run after the specified target. The: all target means that the hook will run before/after all of the Examples. Here is a simple example that illustrates when each hook is called. describe “Before and after hooks” do before(:each) do puts “Runs before each Example” end after(:each) do puts “Runs after each Example” end before(:all) do puts “Runs before all Examples” end after(:all) do puts “Runs after all Examples” end it ”is the first Example in this spec file” do puts ”Running the first Example” end it ”is the second Example in this spec file” do puts ”Running the second Example” end end When you run the above code, you will see this output − Runs before all Examples Runs before each Example Running the first Example Runs after each Example .Runs before each Example Running the second Example Runs after each Example .Runs after all Examples Print Page Previous Next Advertisements ”;
Tree Data Structure (Case Study) ”; Previous Next So far we have seen different concepts of logic programming in Prolog. Now we will see one case study on Prolog. We will see how to implement a tree data structure using Prolog, and we will create our own operators. So let us start the planning. Suppose we have a tree as shown below − We have to implement this tree using prolog. We have some operations as follows − op(500, xfx, ‘is_parent’). op(500, xfx, ‘is_sibling_of’). op(500, xfx, ‘is_at_same_level’). And another predicate namely leaf_node(Node) In these operators, you have seen some parameters as (500, xfx, <operator_name>). The first argument (here 500) is the priority of that operator. The ‘xfx’ indicates that this is a binary operator and the <operator_name> is the name of the operator. These operators can be used to define the tree database. We can use these operators as follows − a is_parent b, or is_parent(a, b). So this indicates that node a is the parent of node b. X is_sibling_of Y or is_sibling_of(X,Y). This indicates that X is the sibling of node Y. So the rule is, if another node Z is parent of X and Z is also the parent of Y and X and Y are different, then X and Y are siblings. leaf_node(Node). A node (Node) is said to be a leaf node when a node has no children. X is_at_same_level Y, or is_at_same_level(X,Y). This will check whether X and Y are at the same level or not. So the condition is when X and Y are same, then it returns true, otherwise W is the parent of X, Z is the parent of Y and W and Z are at the same level. As shown above, other rules are defined in the code. So let us see the program to get better view. Program /* The tree database */ :- op(500,xfx,”is_parent”). a is_parent b. c is_parent g. f is_parent l. j is_parent q. a is_parent c. c is_parent h. f is_parent m. j is_parent r. a is_parent d. c is_parent i. h is_parent n. j is_parent s. b is_parent e. d is_parent j. i is_parent o. m is_parent t. b is_parent f. e is_parent k. i is_parent p. n is_parent u. n is_parent v. /* X and Y are siblings i.e. child from the same parent */ :- op(500,xfx,”is_sibling_of”). X is_sibling_of Y :- Z is_parent X, Z is_parent Y, X == Y. leaf_node(Node) :- + is_parent(Node,Child). % Node grounded /* X and Y are on the same level in the tree. */ :-op(500,xfx,”is_at_same_level”). X is_at_same_level X . X is_at_same_level Y :- W is_parent X, Z is_parent Y, W is_at_same_level Z. Output | ?- [case_tree]. compiling D:/TP Prolog/Sample_Codes/case_tree.pl for byte code… D:/TP Prolog/Sample_Codes/case_tree.pl:20: warning: singleton variables [Child] for leaf_node/1 D:/TP Prolog/Sample_Codes/case_tree.pl compiled, 28 lines read – 3244 bytes written, 7 ms yes | ?- i is_parent p. yes | ?- i is_parent s. no | ?- is_parent(i,p). yes | ?- e is_sibling_of f. true ? yes | ?- is_sibling_of(e,g). no | ?- leaf_node(v). yes | ?- leaf_node(a). no | ?- is_at_same_level(l,s). true ? yes | ?- l is_at_same_level v. no | ?- More on Tree Data Structure Here, we will see some more operations that will be performed on the above given tree data structure. Let us consider the same tree here − We will define other operations − path(Node) locate(Node) As we have created the last database, we will create a new program that will hold these operations, then consult the new file to use these operations on our pre-existing program. So let us see what is the purpose of these operators − path(Node) − This will display the path from the root node to the given node. To solve this, suppose X is parent of Node, then find path(X), then write X. When root node ‘a’ is reached, it will stop. locate(Node) − This will locate a node (Node) from the root of the tree. In this case, we will call the path(Node) and write the Node. Program Let us see the program in execution − path(a). /* Can start at a. */ path(Node) :- Mother is_parent Node, /* Choose parent, */ path(Mother), /* find path and then */ write(Mother), write(” –> ”). /* Locate node by finding a path from root down to the node */ locate(Node) :- path(Node), write(Node), nl. Output | ?- consult(”case_tree_more.pl”). compiling D:/TP Prolog/Sample_Codes/case_tree_more.pl for byte code… D:/TP Prolog/Sample_Codes/case_tree_more.pl compiled, 9 lines read – 866 bytes written, 6 ms yes | ?- path(n). a –> c –> h –> true ? yes | ?- path(s). a –> d –> j –> true ? yes | ?- path(w). no | ?- locate(n). a –> c –> h –> n true ? yes | ?- locate(s). a –> d –> j –> s true ? yes | ?- locate(w). no | ?- Advances in Tree Data Structures Now let us define some advanced operations on the same tree data structure. Here we will see how to find the height of a node, that is, the length of the longest path from that node, using the Prolog built-in predicate setof/3. This predicate takes (Template, Goal, Set). This binds Set to the list of all instances of Template satisfying the goal Goal. We have already defined the tree before, so we will consult the current code to execute these set of operations without redefining the tree database again. We will create some predicates as follows − ht(Node,H). This finds the height. It also checks whether a node is leaf or not, if so, then sets height H as 0, otherwise recursively finds the height of children of Node, and add 1 to them. max([X|R], M,A). This calculates the max element from the list, and a value M. So if M is maximum, then it returns M, otherwise, it returns the maximum element of list that is greater than M. To solve this, if given list is empty, return M as max element, otherwise check whether Head is greater than M or not, if so,
RSpec – Tags
RSpec – Tags ”; Previous Next RSpec Tags provide an easy way to run specific tests in your spec files. By default, RSpec will run all tests in the spec files that it runs, but you might only need to run a subset of them. Let’s say that you have some tests that run very quickly and that you’ve just made a change to your application code and you want to just run the quick tests, this code will demonstrate how to do that with RSpec Tags. describe “How to run specific Examples with Tags” do it ”is a slow test”, :slow = > true do sleep 10 puts ”This test is slow!” end it ”is a fast test”, :fast = > true do puts ”This test is fast!” end end Now, save the above code in a new file called tag_spec.rb. From the command line, run this command: rspec –tag slow tag_spec.rb You will see this output − Run options: include {: slow = >true} This test is slow! . Finished in 10 seconds (files took 0.11601 seconds to load) 1 example, 0 failures Then, run this command: rspec –tag fast tag_spec.rb You will see this output − Run options: include {:fast = >true} This test is fast! . Finished in 0.001 seconds (files took 0.11201 seconds to load) 1 example, 0 failures As you can see, RSpec Tags makes it very easy to a subset of tests! Print Page Previous Next Advertisements ”;
RSpec – Metadata
RSpec – Metadata ”; Previous Next RSpec is a flexible and powerful tool. The Metadata functionality in RSpec is no exception. Metadata generally refers to “data about data”. In RSpec, this means data about your describe, context and it blocks. Let’s take a look at an example − RSpec.describe “An Example Group with a metadata variable”, :foo => 17 do context ”and a context with another variable”, :bar => 12 do it ”can access the metadata variable of the outer Example Group” do |example| expect(example.metadata[:foo]).to eq(17) end it ”can access the metadata variable in the context block” do |example| expect(example.metadata[:bar]).to eq(12) end end end When you run the above code, you will see this output − .. Finished in 0.002 seconds (files took 0.11301 seconds to load) 2 examples, 0 failures Metadata provides a way to assign variables at various scopes within your RSpec files. The example.metadata variable is a Ruby hash which contains other information about your Examples and Example groups. For instance, let’s rewrite the above code to look like this − RSpec.describe “An Example Group with a metadata variable”, :foo => 17 do context ”and a context with another variable”, :bar => 12 do it ”can access the metadata variable in the context block” do |example| expect(example.metadata[:foo]).to eq(17) expect(example.metadata[:bar]).to eq(12) example.metadata.each do |k,v| puts “#{k}: #{v}” end end end When we run this code, we see all of the values in the example.metadata hash − .execution_result: #<RSpec::Core::Example::ExecutionResult:0x00000002befd50> block: #<Proc:0x00000002bf81a8@C:/rspec_tutorial/spec/metadata_spec.rb:7> description_args: [“can access the metadata variable in the context block”] description: can access the metadata variable in the context block full_description: An Example Group with a metadata variable and a context with another variable can access the metadata variable in the context block described_class: file_path: ./metadata_spec.rb line_number: 7 location: ./metadata_spec.rb:7 absolute_file_path: C:/rspec_tutorial/spec/metadata_spec.rb rerun_file_path: ./metadata_spec.rb scoped_id: 1:1:2 foo: 17 bar: 12 example_group: {:execution_result=>#<RSpec::Core::Example::ExecutionResult: 0x00000002bfa0e8>, :block=>#< Proc:0x00000002bfac00@C:/rspec_tutorial/spec/metadata_spec.rb:2>, :description_args=>[“and a context with another variable”], :description=>”and a context with another variable”, :full_description=>”An Example Group with a metadata variable and a context with another variable”, :described_class=>nil, :file_path=>”./metadata_spec.rb”, :line_number=>2, :location=>”./metadata_spec.rb:2″, :absolute_file_path=>”C:/rspec_tutorial/spec/metadata_spec.rb”, :rerun_file_path=>”./metadata_spec.rb”, :scoped_id=>”1:1″, :foo=>17, :parent_example_group=> {:execution_result=>#< RSpec::Core::Example::ExecutionResult:0x00000002c1f690>, :block=>#<Proc:0x00000002baff70@C:/rspec_tutorial/spec/metadata_spec.rb:1> , :description_args=>[“An Example Group with a metadata variable”], :description=>”An Example Group with a metadata variable”, :full_description=>”An Example Group with a metadata variable”, :described_class=>nil, :file_path=>”./metadata_spec.rb”, :line_number=>1, :location=>”./metadata_spec.rb:1″, :absolute_file_path=> “C:/rspec_tutorial/spec/metadata_spec.rb”, :rerun_file_path=>”./metadata_spec.rb”, :scoped_id=>”1″, :foo=>17}, :bar=>12}shared_group_inclusion_backtrace: [] last_run_status: unknown . . Finished in 0.004 seconds (files took 0.11101 seconds to load) 2 examples, 0 failures Most likely, you will not need to use all of this metadata, but look at the full description value − An Example Group with a metadata variable and a context with another variable can access the metadata variable in the context block. This is a sentence created from the describe block description + its contained context block description + the description for the it block. What is interesting to note here is that, these three strings together read like a normal English sentence. . . which is one of the ideas behind RSpec, having tests that sound like English descriptions of behavior. Print Page Previous Next Advertisements ”;